Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/font/GraphicComponent.java
41154 views
1
/*
2
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* (C) Copyright IBM Corp. 1998-2003, All Rights Reserved
28
*
29
*/
30
31
package sun.font;
32
33
import java.awt.Font;
34
import java.awt.Graphics2D;
35
import java.awt.Rectangle;
36
import java.awt.Shape;
37
import java.awt.font.FontRenderContext;
38
import java.awt.font.LineMetrics;
39
import java.awt.font.GraphicAttribute;
40
import java.awt.font.GlyphJustificationInfo;
41
import java.awt.geom.AffineTransform;
42
import java.awt.geom.GeneralPath;
43
import java.awt.geom.Rectangle2D;
44
import java.text.Bidi;
45
import java.util.Map;
46
47
public final class GraphicComponent implements TextLineComponent,
48
Decoration.Label {
49
50
public static final float GRAPHIC_LEADING = 2;
51
52
private GraphicAttribute graphic;
53
private int graphicCount;
54
private int[] charsLtoV; // possibly null
55
private byte[] levels; // possibly null
56
57
// evaluated in computeVisualBounds
58
private Rectangle2D visualBounds = null;
59
60
// used everywhere so we'll cache it
61
private float graphicAdvance;
62
63
private AffineTransform baseTx;
64
65
private CoreMetrics cm;
66
private Decoration decorator;
67
68
69
/**
70
* Create a new GraphicComponent. start and limit are indices
71
* into charLtoV and levels. charsLtoV and levels may be adopted.
72
*/
73
public GraphicComponent(GraphicAttribute graphic,
74
Decoration decorator,
75
int[] charsLtoV,
76
byte[] levels,
77
int start,
78
int limit,
79
AffineTransform baseTx) {
80
81
if (limit <= start) {
82
throw new IllegalArgumentException("0 or negative length in GraphicComponent");
83
}
84
this.graphic = graphic;
85
this.graphicAdvance = graphic.getAdvance();
86
this.decorator = decorator;
87
this.cm = createCoreMetrics(graphic);
88
this.baseTx = baseTx;
89
90
initLocalOrdering(charsLtoV, levels, start, limit);
91
}
92
93
private GraphicComponent(GraphicComponent parent, int start, int limit, int dir) {
94
95
this.graphic = parent.graphic;
96
this.graphicAdvance = parent.graphicAdvance;
97
this.decorator = parent.decorator;
98
this.cm = parent.cm;
99
this.baseTx = parent.baseTx;
100
101
int[] charsLtoV = null;
102
byte[] levels = null;
103
104
if (dir == UNCHANGED) {
105
charsLtoV = parent.charsLtoV;
106
levels = parent.levels;
107
}
108
else if (dir == LEFT_TO_RIGHT || dir == RIGHT_TO_LEFT) {
109
limit -= start;
110
start = 0;
111
if (dir == RIGHT_TO_LEFT) {
112
charsLtoV = new int[limit];
113
levels = new byte[limit];
114
for (int i=0; i < limit; i++) {
115
charsLtoV[i] = limit-i-1;
116
levels[i] = (byte) 1;
117
}
118
}
119
}
120
else {
121
throw new IllegalArgumentException("Invalid direction flag");
122
}
123
124
initLocalOrdering(charsLtoV, levels, start, limit);
125
}
126
127
/**
128
* Initialize graphicCount, also charsLtoV and levels arrays.
129
*/
130
private void initLocalOrdering(int[] charsLtoV,
131
byte[] levels,
132
int start,
133
int limit) {
134
135
this.graphicCount = limit - start; // todo: should be codepoints?
136
137
if (charsLtoV == null || charsLtoV.length == graphicCount) {
138
this.charsLtoV = charsLtoV;
139
}
140
else {
141
this.charsLtoV = BidiUtils.createNormalizedMap(charsLtoV, levels, start, limit);
142
}
143
144
if (levels == null || levels.length == graphicCount) {
145
this.levels = levels;
146
}
147
else {
148
this.levels = new byte[graphicCount];
149
System.arraycopy(levels, start, this.levels, 0, graphicCount);
150
}
151
}
152
153
public boolean isSimple() {
154
return false;
155
}
156
157
public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
158
throw new InternalError("do not call if isSimple returns false");
159
}
160
161
public Rectangle2D handleGetVisualBounds() {
162
163
Rectangle2D bounds = graphic.getBounds();
164
165
float width = (float) bounds.getWidth() +
166
graphicAdvance * (graphicCount-1);
167
168
return new Rectangle2D.Float((float) bounds.getX(),
169
(float) bounds.getY(),
170
width,
171
(float) bounds.getHeight());
172
}
173
174
public CoreMetrics getCoreMetrics() {
175
return cm;
176
}
177
178
public static CoreMetrics createCoreMetrics(GraphicAttribute graphic) {
179
return new CoreMetrics(graphic.getAscent(),
180
graphic.getDescent(),
181
GRAPHIC_LEADING,
182
graphic.getAscent() + graphic.getDescent() + GRAPHIC_LEADING,
183
graphic.getAlignment(),
184
new float[] { 0, -graphic.getAscent() / 2, -graphic.getAscent() },
185
-graphic.getAscent() / 2,
186
graphic.getAscent() / 12,
187
graphic.getDescent() / 3,
188
graphic.getAscent() / 12,
189
0, // ss offset
190
0); // italic angle -- need api for this
191
}
192
193
public float getItalicAngle() {
194
195
return 0;
196
}
197
198
public Rectangle2D getVisualBounds() {
199
200
if (visualBounds == null) {
201
visualBounds = decorator.getVisualBounds(this);
202
}
203
Rectangle2D.Float bounds = new Rectangle2D.Float();
204
bounds.setRect(visualBounds);
205
return bounds;
206
}
207
208
public Shape handleGetOutline(float x, float y) {
209
double[] matrix = { 1, 0, 0, 1, x, y };
210
211
if (graphicCount == 1) {
212
AffineTransform tx = new AffineTransform(matrix);
213
return graphic.getOutline(tx);
214
}
215
216
GeneralPath gp = new GeneralPath();
217
for (int i = 0; i < graphicCount; ++i) {
218
AffineTransform tx = new AffineTransform(matrix);
219
gp.append(graphic.getOutline(tx), false);
220
matrix[4] += graphicAdvance;
221
}
222
223
return gp;
224
}
225
226
public AffineTransform getBaselineTransform() {
227
return baseTx;
228
}
229
230
public Shape getOutline(float x, float y) {
231
232
return decorator.getOutline(this, x, y);
233
}
234
235
public void handleDraw(Graphics2D g2d, float x, float y) {
236
237
for (int i=0; i < graphicCount; i++) {
238
239
graphic.draw(g2d, x, y);
240
x += graphicAdvance;
241
}
242
}
243
244
public void draw(Graphics2D g2d, float x, float y) {
245
246
decorator.drawTextAndDecorations(this, g2d, x, y);
247
}
248
249
public Rectangle2D getCharVisualBounds(int index) {
250
251
return decorator.getCharVisualBounds(this, index);
252
}
253
254
public int getNumCharacters() {
255
256
return graphicCount;
257
}
258
259
public float getCharX(int index) {
260
261
int visIndex = charsLtoV==null? index : charsLtoV[index];
262
return graphicAdvance * visIndex;
263
}
264
265
public float getCharY(int index) {
266
267
return 0;
268
}
269
270
public float getCharAdvance(int index) {
271
272
return graphicAdvance;
273
}
274
275
public boolean caretAtOffsetIsValid(int index) {
276
277
return true;
278
}
279
280
public Rectangle2D handleGetCharVisualBounds(int index) {
281
282
Rectangle2D bounds = graphic.getBounds();
283
// don't modify their rectangle, just in case they don't copy
284
285
Rectangle2D.Float charBounds = new Rectangle2D.Float();
286
charBounds.setRect(bounds);
287
charBounds.x += graphicAdvance * index;
288
289
return charBounds;
290
}
291
292
// measures characters in context, in logical order
293
public int getLineBreakIndex(int start, float width) {
294
295
int index = (int) (width / graphicAdvance);
296
if (index > graphicCount - start) {
297
index = graphicCount - start;
298
}
299
return index;
300
}
301
302
// measures characters in context, in logical order
303
public float getAdvanceBetween(int start, int limit) {
304
305
return graphicAdvance * (limit - start);
306
}
307
308
public Rectangle2D getLogicalBounds() {
309
310
float left = 0;
311
float top = -cm.ascent;
312
float width = graphicAdvance * graphicCount;
313
float height = cm.descent - top;
314
315
return new Rectangle2D.Float(left, top, width, height);
316
}
317
318
public float getAdvance() {
319
return graphicAdvance * graphicCount;
320
}
321
322
public Rectangle2D getItalicBounds() {
323
return getLogicalBounds();
324
}
325
326
public TextLineComponent getSubset(int start, int limit, int dir) {
327
328
if (start < 0 || limit > graphicCount || start >= limit) {
329
throw new IllegalArgumentException("Invalid range. start="
330
+start+"; limit="+limit);
331
}
332
333
if (start == 0 && limit == graphicCount && dir == UNCHANGED) {
334
return this;
335
}
336
337
return new GraphicComponent(this, start, limit, dir);
338
}
339
340
public String toString() {
341
342
return "[graphic=" + graphic + ":count=" + getNumCharacters() + "]";
343
}
344
345
/**
346
* Return the number of justification records this uses.
347
*/
348
public int getNumJustificationInfos() {
349
return 0;
350
}
351
352
/**
353
* Return GlyphJustificationInfo objects for the characters between
354
* charStart and charLimit, starting at offset infoStart. Infos
355
* will be in visual order. All positions between infoStart and
356
* getNumJustificationInfos will be set. If a position corresponds
357
* to a character outside the provided range, it is set to null.
358
*/
359
public void getJustificationInfos(GlyphJustificationInfo[] infos, int infoStart, int charStart, int charLimit) {
360
}
361
362
/**
363
* Apply deltas to the data in this component, starting at offset
364
* deltaStart, and return the new component. There are two floats
365
* for each justification info, for a total of 2 * getNumJustificationInfos.
366
* The first delta is the left adjustment, the second is the right
367
* adjustment.
368
* <p>
369
* If flags[0] is true on entry, rejustification is allowed. If
370
* the new component requires rejustification (ligatures were
371
* formed or split), flags[0] will be set on exit.
372
*/
373
public TextLineComponent applyJustificationDeltas(float[] deltas, int deltaStart, boolean[] flags) {
374
return this;
375
}
376
}
377
378