author | darcy |
Tue, 28 Jan 2014 09:42:05 -0800 | |
changeset 22584 | eed64ee05369 |
parent 21278 | ef8a3a2a72f2 |
child 26020 | 68deef2ad1c9 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
22584
eed64ee05369
8032733: Fix cast lint warnings in client libraries
darcy
parents:
21278
diff
changeset
|
2 |
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.font; |
|
27 |
||
28 |
import java.lang.ref.SoftReference; |
|
2393 | 29 |
import java.lang.ref.WeakReference; |
2 | 30 |
import java.awt.Font; |
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
31 |
import java.awt.GraphicsEnvironment; |
2 | 32 |
import java.awt.Rectangle; |
33 |
import java.awt.geom.AffineTransform; |
|
34 |
import java.awt.geom.GeneralPath; |
|
35 |
import java.awt.geom.NoninvertibleTransformException; |
|
36 |
import java.awt.geom.Point2D; |
|
37 |
import java.awt.geom.Rectangle2D; |
|
38 |
import java.util.concurrent.ConcurrentHashMap; |
|
39 |
import static sun.awt.SunHints.*; |
|
40 |
||
41 |
||
42 |
public class FileFontStrike extends PhysicalStrike { |
|
43 |
||
44 |
/* fffe and ffff are values we specially interpret as meaning |
|
45 |
* invisible glyphs. |
|
46 |
*/ |
|
47 |
static final int INVISIBLE_GLYPHS = 0x0fffe; |
|
48 |
||
49 |
private FileFont fileFont; |
|
50 |
||
51 |
/* REMIND: replace this scheme with one that installs a cache |
|
52 |
* instance of the appropriate type. It will require changes in |
|
53 |
* FontStrikeDisposer and NativeStrike etc. |
|
54 |
*/ |
|
55 |
private static final int UNINITIALISED = 0; |
|
56 |
private static final int INTARRAY = 1; |
|
57 |
private static final int LONGARRAY = 2; |
|
58 |
private static final int SEGINTARRAY = 3; |
|
59 |
private static final int SEGLONGARRAY = 4; |
|
60 |
||
7750 | 61 |
private volatile int glyphCacheFormat = UNINITIALISED; |
2 | 62 |
|
7757
451411eff24b
6891551: Font rasterisation uses more heap than needed for some strikes.
prr
parents:
7750
diff
changeset
|
63 |
/* segmented arrays are blocks of 32 */ |
451411eff24b
6891551: Font rasterisation uses more heap than needed for some strikes.
prr
parents:
7750
diff
changeset
|
64 |
private static final int SEGSHIFT = 5; |
2 | 65 |
private static final int SEGSIZE = 1 << SEGSHIFT; |
66 |
||
67 |
private boolean segmentedCache; |
|
68 |
private int[][] segIntGlyphImages; |
|
69 |
private long[][] segLongGlyphImages; |
|
70 |
||
71 |
/* The "metrics" information requested by clients is usually nothing |
|
72 |
* more than the horizontal advance of the character. |
|
73 |
* In most cases this advance and other metrics information is stored |
|
74 |
* in the glyph image cache. |
|
75 |
* But in some cases we do not automatically retrieve the glyph |
|
76 |
* image when the advance is requested. In those cases we want to |
|
77 |
* cache the advances since this has been shown to be important for |
|
78 |
* performance. |
|
79 |
* The segmented cache is used in cases when the single array |
|
80 |
* would be too large. |
|
81 |
*/ |
|
82 |
private float[] horizontalAdvances; |
|
83 |
private float[][] segHorizontalAdvances; |
|
84 |
||
85 |
/* Outline bounds are used when printing and when drawing outlines |
|
86 |
* to the screen. On balance the relative rarity of these cases |
|
87 |
* and the fact that getting this requires generating a path at |
|
88 |
* the scaler level means that its probably OK to store these |
|
89 |
* in a Java-level hashmap as the trade-off between time and space. |
|
90 |
* Later can revisit whether to cache these at all, or elsewhere. |
|
91 |
* Should also profile whether subsequent to getting the bounds, the |
|
92 |
* outline itself is also requested. The 1.4 implementation doesn't |
|
93 |
* cache outlines so you could generate the path twice - once to get |
|
94 |
* the bounds and again to return the outline to the client. |
|
95 |
* If the two uses are coincident then also look into caching outlines. |
|
96 |
* One simple optimisation is that we could store the last single |
|
97 |
* outline retrieved. This assumes that bounds then outline will always |
|
98 |
* be retrieved for a glyph rather than retrieving bounds for all glyphs |
|
99 |
* then outlines for all glyphs. |
|
100 |
*/ |
|
101 |
ConcurrentHashMap<Integer, Rectangle2D.Float> boundsMap; |
|
102 |
SoftReference<ConcurrentHashMap<Integer, Point2D.Float>> |
|
103 |
glyphMetricsMapRef; |
|
104 |
||
105 |
AffineTransform invertDevTx; |
|
106 |
||
107 |
boolean useNatives; |
|
108 |
NativeStrike[] nativeStrikes; |
|
109 |
||
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
110 |
/* Used only for communication to native layer */ |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
111 |
private int intPtSize; |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
112 |
|
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
113 |
/* Perform global initialisation needed for Windows native rasterizer */ |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
114 |
private static native boolean initNative(); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
115 |
private static boolean isXPorLater = false; |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
116 |
static { |
3928 | 117 |
if (FontUtilities.isWindows && !FontUtilities.useT2K && |
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
118 |
!GraphicsEnvironment.isHeadless()) { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
119 |
isXPorLater = initNative(); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
120 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
121 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
122 |
|
2 | 123 |
FileFontStrike(FileFont fileFont, FontStrikeDesc desc) { |
124 |
super(fileFont, desc); |
|
125 |
this.fileFont = fileFont; |
|
126 |
||
127 |
if (desc.style != fileFont.style) { |
|
128 |
/* If using algorithmic styling, the base values are |
|
129 |
* boldness = 1.0, italic = 0.0. The superclass constructor |
|
130 |
* initialises these. |
|
131 |
*/ |
|
132 |
if ((desc.style & Font.ITALIC) == Font.ITALIC && |
|
133 |
(fileFont.style & Font.ITALIC) == 0) { |
|
134 |
algoStyle = true; |
|
135 |
italic = 0.7f; |
|
136 |
} |
|
137 |
if ((desc.style & Font.BOLD) == Font.BOLD && |
|
138 |
((fileFont.style & Font.BOLD) == 0)) { |
|
139 |
algoStyle = true; |
|
140 |
boldness = 1.33f; |
|
141 |
} |
|
142 |
} |
|
143 |
double[] matrix = new double[4]; |
|
144 |
AffineTransform at = desc.glyphTx; |
|
145 |
at.getMatrix(matrix); |
|
146 |
if (!desc.devTx.isIdentity() && |
|
147 |
desc.devTx.getType() != AffineTransform.TYPE_TRANSLATION) { |
|
148 |
try { |
|
149 |
invertDevTx = desc.devTx.createInverse(); |
|
150 |
} catch (NoninvertibleTransformException e) { |
|
151 |
} |
|
152 |
} |
|
153 |
||
7940
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
154 |
/* Amble fonts are better rendered unhinted although there's the |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
155 |
* inevitable fuzziness that accompanies this due to no longer |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
156 |
* snapping stems to the pixel grid. The exception is that in B&W |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
157 |
* mode they are worse without hinting. The down side to that is that |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
158 |
* B&W metrics will differ which normally isn't the case, although |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
159 |
* since AA mode is part of the measuring context that should be OK. |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
160 |
* We don't expect Amble to be installed in the Windows fonts folder. |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
161 |
* If we were to, then we'd also might want to disable using the |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
162 |
* native rasteriser path which is used for LCD mode for platform |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
163 |
* fonts. since we have no way to disable hinting by GDI. |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
164 |
* In the case of Amble, since its 'gasp' table says to disable |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
165 |
* hinting, I'd expect GDI to follow that, so likely it should |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
166 |
* all be consistent even if GDI used. |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
167 |
*/ |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
168 |
boolean disableHinting = desc.aaHint != INTVAL_TEXT_ANTIALIAS_OFF && |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
169 |
fileFont.familyName.startsWith("Amble"); |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
170 |
|
2 | 171 |
/* If any of the values is NaN then substitute the null scaler context. |
172 |
* This will return null images, zero advance, and empty outlines |
|
173 |
* as no rendering need take place in this case. |
|
174 |
* We pass in the null scaler as the singleton null context |
|
175 |
* requires it. However |
|
176 |
*/ |
|
177 |
if (Double.isNaN(matrix[0]) || Double.isNaN(matrix[1]) || |
|
178 |
Double.isNaN(matrix[2]) || Double.isNaN(matrix[3]) || |
|
179 |
fileFont.getScaler() == null) { |
|
180 |
pScalerContext = NullFontScaler.getNullScalerContext(); |
|
181 |
} else { |
|
182 |
pScalerContext = fileFont.getScaler().createScalerContext(matrix, |
|
183 |
desc.aaHint, desc.fmHint, |
|
7940
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
7938
diff
changeset
|
184 |
boldness, italic, disableHinting); |
2 | 185 |
} |
186 |
||
187 |
mapper = fileFont.getMapper(); |
|
188 |
int numGlyphs = mapper.getNumGlyphs(); |
|
189 |
||
7757
451411eff24b
6891551: Font rasterisation uses more heap than needed for some strikes.
prr
parents:
7750
diff
changeset
|
190 |
/* Always segment for fonts with > 256 glyphs, but also for smaller |
2 | 191 |
* fonts with non-typical sizes and transforms. |
21278 | 192 |
* Segmenting for all non-typical pt sizes helps to minimize memory |
2 | 193 |
* usage when very many distinct strikes are created. |
194 |
* The size range of 0->5 and 37->INF for segmenting is arbitrary |
|
195 |
* but the intention is that typical GUI integer point sizes (6->36) |
|
196 |
* should not segment unless there's another reason to do so. |
|
197 |
*/ |
|
198 |
float ptSize = (float)matrix[3]; // interpreted only when meaningful. |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
199 |
int iSize = intPtSize = (int)ptSize; |
2 | 200 |
boolean isSimpleTx = (at.getType() & complexTX) == 0; |
201 |
segmentedCache = |
|
202 |
(numGlyphs > SEGSIZE << 3) || |
|
203 |
((numGlyphs > SEGSIZE << 1) && |
|
204 |
(!isSimpleTx || ptSize != iSize || iSize < 6 || iSize > 36)); |
|
205 |
||
206 |
/* This can only happen if we failed to allocate memory for context. |
|
207 |
* NB: in such case we may still have some memory in java heap |
|
208 |
* but subsequent attempt to allocate null scaler context |
|
209 |
* may fail too (cause it is allocate in the native heap). |
|
210 |
* It is not clear how to make this more robust but on the |
|
211 |
* other hand getting NULL here seems to be extremely unlikely. |
|
212 |
*/ |
|
213 |
if (pScalerContext == 0L) { |
|
214 |
/* REMIND: when the code is updated to install cache objects |
|
215 |
* rather than using a switch this will be more efficient. |
|
216 |
*/ |
|
217 |
this.disposer = new FontStrikeDisposer(fileFont, desc); |
|
218 |
initGlyphCache(); |
|
219 |
pScalerContext = NullFontScaler.getNullScalerContext(); |
|
3928 | 220 |
SunFontManager.getInstance().deRegisterBadFont(fileFont); |
2 | 221 |
return; |
222 |
} |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
223 |
/* First, see if native code should be used to create the glyph. |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
224 |
* GDI will return the integer metrics, not fractional metrics, which |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
225 |
* may be requested for this strike, so we would require here that : |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
226 |
* desc.fmHint != INTVAL_FRACTIONALMETRICS_ON |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
227 |
* except that the advance returned by GDI is always overwritten by |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
228 |
* the JDK rasteriser supplied one (see getGlyphImageFromWindows()). |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
229 |
*/ |
3928 | 230 |
if (FontUtilities.isWindows && isXPorLater && |
231 |
!FontUtilities.useT2K && |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
232 |
!GraphicsEnvironment.isHeadless() && |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
233 |
!fileFont.useJavaRasterizer && |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
234 |
(desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB || |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
235 |
desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) && |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
236 |
(matrix[1] == 0.0 && matrix[2] == 0.0 && |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
237 |
matrix[0] == matrix[3] && |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
238 |
matrix[0] >= 3.0 && matrix[0] <= 100.0) && |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
239 |
!((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
240 |
useNatives = true; |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
241 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
242 |
else if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) { |
2 | 243 |
/* Check its a simple scale of a pt size in the range |
244 |
* where native bitmaps typically exist (6-36 pts) */ |
|
245 |
if (matrix[1] == 0.0 && matrix[2] == 0.0 && |
|
246 |
matrix[0] >= 6.0 && matrix[0] <= 36.0 && |
|
247 |
matrix[0] == matrix[3]) { |
|
248 |
useNatives = true; |
|
249 |
int numNatives = fileFont.nativeFonts.length; |
|
250 |
nativeStrikes = new NativeStrike[numNatives]; |
|
251 |
/* Maybe initialise these strikes lazily?. But we |
|
252 |
* know we need at least one |
|
253 |
*/ |
|
254 |
for (int i=0; i<numNatives; i++) { |
|
255 |
nativeStrikes[i] = |
|
256 |
new NativeStrike(fileFont.nativeFonts[i], desc, false); |
|
257 |
} |
|
258 |
} |
|
259 |
} |
|
3928 | 260 |
if (FontUtilities.isLogging() && FontUtilities.isWindows) { |
261 |
FontUtilities.getLogger().info |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
262 |
("Strike for " + fileFont + " at size = " + intPtSize + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
263 |
" use natives = " + useNatives + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
264 |
" useJavaRasteriser = " + fileFont.useJavaRasterizer + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
265 |
" AAHint = " + desc.aaHint + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
266 |
" Has Embedded bitmaps = " + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
267 |
((TrueTypeFont)fileFont). |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
268 |
useEmbeddedBitmapsForSize(intPtSize)); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
269 |
} |
2 | 270 |
this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext); |
271 |
||
272 |
/* Always get the image and the advance together for smaller sizes |
|
273 |
* that are likely to be important to rendering performance. |
|
274 |
* The pixel size of 48.0 can be thought of as |
|
275 |
* "maximumSizeForGetImageWithAdvance". |
|
276 |
* This should be no greater than OutlineTextRender.THRESHOLD. |
|
277 |
*/ |
|
546
06253731a445
6692979: VM Crash when shearing text + rect over a range of values
prr
parents:
2
diff
changeset
|
278 |
double maxSz = 48.0; |
06253731a445
6692979: VM Crash when shearing text + rect over a range of values
prr
parents:
2
diff
changeset
|
279 |
getImageWithAdvance = |
06253731a445
6692979: VM Crash when shearing text + rect over a range of values
prr
parents:
2
diff
changeset
|
280 |
Math.abs(at.getScaleX()) <= maxSz && |
06253731a445
6692979: VM Crash when shearing text + rect over a range of values
prr
parents:
2
diff
changeset
|
281 |
Math.abs(at.getScaleY()) <= maxSz && |
06253731a445
6692979: VM Crash when shearing text + rect over a range of values
prr
parents:
2
diff
changeset
|
282 |
Math.abs(at.getShearX()) <= maxSz && |
06253731a445
6692979: VM Crash when shearing text + rect over a range of values
prr
parents:
2
diff
changeset
|
283 |
Math.abs(at.getShearY()) <= maxSz; |
2 | 284 |
|
285 |
/* Some applications request advance frequently during layout. |
|
286 |
* If we are not getting and caching the image with the advance, |
|
287 |
* there is a potentially significant performance penalty if the |
|
288 |
* advance is repeatedly requested before requesting the image. |
|
289 |
* We should at least cache the horizontal advance. |
|
290 |
* REMIND: could use info in the font, eg hmtx, to retrieve some |
|
291 |
* advances. But still want to cache it here. |
|
292 |
*/ |
|
293 |
||
294 |
if (!getImageWithAdvance) { |
|
295 |
if (!segmentedCache) { |
|
296 |
horizontalAdvances = new float[numGlyphs]; |
|
297 |
/* use max float as uninitialised advance */ |
|
298 |
for (int i=0; i<numGlyphs; i++) { |
|
299 |
horizontalAdvances[i] = Float.MAX_VALUE; |
|
300 |
} |
|
301 |
} else { |
|
302 |
int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE; |
|
303 |
segHorizontalAdvances = new float[numSegments][]; |
|
304 |
} |
|
305 |
} |
|
306 |
} |
|
307 |
||
308 |
/* A number of methods are delegated by the strike to the scaler |
|
309 |
* context which is a shared resource on a physical font. |
|
310 |
*/ |
|
311 |
||
312 |
public int getNumGlyphs() { |
|
313 |
return fileFont.getNumGlyphs(); |
|
314 |
} |
|
315 |
||
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
316 |
long getGlyphImageFromNative(int glyphCode) { |
3928 | 317 |
if (FontUtilities.isWindows) { |
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
318 |
return getGlyphImageFromWindows(glyphCode); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
319 |
} else { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
320 |
return getGlyphImageFromX11(glyphCode); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
321 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
322 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
323 |
|
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
324 |
/* There's no global state conflicts, so this method is not |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
325 |
* presently synchronized. |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
326 |
*/ |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
327 |
private native long _getGlyphImageFromWindows(String family, |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
328 |
int style, |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
329 |
int size, |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
330 |
int glyphCode, |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
331 |
boolean fracMetrics); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
332 |
|
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
333 |
long getGlyphImageFromWindows(int glyphCode) { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
334 |
String family = fileFont.getFamilyName(null); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
335 |
int style = desc.style & Font.BOLD | desc.style & Font.ITALIC |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
336 |
| fileFont.getStyle(); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
337 |
int size = intPtSize; |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
338 |
long ptr = _getGlyphImageFromWindows |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
339 |
(family, style, size, glyphCode, |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
340 |
desc.fmHint == INTVAL_FRACTIONALMETRICS_ON); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
341 |
if (ptr != 0) { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
342 |
/* Get the advance from the JDK rasterizer. This is mostly |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
343 |
* necessary for the fractional metrics case, but there are |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
344 |
* also some very small number (<0.25%) of marginal cases where |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
345 |
* there is some rounding difference between windows and JDK. |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
346 |
* After these are resolved, we can restrict this extra |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
347 |
* work to the FM case. |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
348 |
*/ |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
349 |
float advance = getGlyphAdvance(glyphCode, false); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
350 |
StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset, |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
351 |
advance); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
352 |
return ptr; |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
353 |
} else { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
354 |
return fileFont.getGlyphImage(pScalerContext, glyphCode); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
355 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
356 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
357 |
|
2 | 358 |
/* Try the native strikes first, then try the fileFont strike */ |
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
359 |
long getGlyphImageFromX11(int glyphCode) { |
2 | 360 |
long glyphPtr; |
361 |
char charCode = fileFont.glyphToCharMap[glyphCode]; |
|
362 |
for (int i=0;i<nativeStrikes.length;i++) { |
|
363 |
CharToGlyphMapper mapper = fileFont.nativeFonts[i].getMapper(); |
|
364 |
int gc = mapper.charToGlyph(charCode)&0xffff; |
|
365 |
if (gc != mapper.getMissingGlyphCode()) { |
|
366 |
glyphPtr = nativeStrikes[i].getGlyphImagePtrNoCache(gc); |
|
367 |
if (glyphPtr != 0L) { |
|
368 |
return glyphPtr; |
|
369 |
} |
|
370 |
} |
|
371 |
} |
|
372 |
return fileFont.getGlyphImage(pScalerContext, glyphCode); |
|
373 |
} |
|
374 |
||
375 |
long getGlyphImagePtr(int glyphCode) { |
|
376 |
if (glyphCode >= INVISIBLE_GLYPHS) { |
|
377 |
return StrikeCache.invisibleGlyphPtr; |
|
378 |
} |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
379 |
long glyphPtr = 0L; |
2 | 380 |
if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) { |
381 |
return glyphPtr; |
|
382 |
} else { |
|
383 |
if (useNatives) { |
|
384 |
glyphPtr = getGlyphImageFromNative(glyphCode); |
|
3928 | 385 |
if (glyphPtr == 0L && FontUtilities.isLogging()) { |
386 |
FontUtilities.getLogger().info |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
387 |
("Strike for " + fileFont + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
388 |
" at size = " + intPtSize + |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
389 |
" couldn't get native glyph for code = " + glyphCode); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
390 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
391 |
} if (glyphPtr == 0L) { |
2 | 392 |
glyphPtr = fileFont.getGlyphImage(pScalerContext, |
393 |
glyphCode); |
|
394 |
} |
|
395 |
return setCachedGlyphPtr(glyphCode, glyphPtr); |
|
396 |
} |
|
397 |
} |
|
398 |
||
399 |
void getGlyphImagePtrs(int[] glyphCodes, long[] images, int len) { |
|
400 |
||
401 |
for (int i=0; i<len; i++) { |
|
402 |
int glyphCode = glyphCodes[i]; |
|
403 |
if (glyphCode >= INVISIBLE_GLYPHS) { |
|
404 |
images[i] = StrikeCache.invisibleGlyphPtr; |
|
405 |
continue; |
|
406 |
} else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) { |
|
407 |
continue; |
|
408 |
} else { |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
409 |
long glyphPtr = 0L; |
2 | 410 |
if (useNatives) { |
411 |
glyphPtr = getGlyphImageFromNative(glyphCode); |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
412 |
} if (glyphPtr == 0L) { |
2 | 413 |
glyphPtr = fileFont.getGlyphImage(pScalerContext, |
414 |
glyphCode); |
|
415 |
} |
|
416 |
images[i] = setCachedGlyphPtr(glyphCode, glyphPtr); |
|
417 |
} |
|
418 |
} |
|
419 |
} |
|
420 |
||
421 |
/* The following method is called from CompositeStrike as a special case. |
|
422 |
*/ |
|
423 |
private static final int SLOTZEROMAX = 0xffffff; |
|
424 |
int getSlot0GlyphImagePtrs(int[] glyphCodes, long[] images, int len) { |
|
425 |
||
426 |
int convertedCnt = 0; |
|
427 |
||
428 |
for (int i=0; i<len; i++) { |
|
429 |
int glyphCode = glyphCodes[i]; |
|
430 |
if (glyphCode >= SLOTZEROMAX) { |
|
431 |
return convertedCnt; |
|
432 |
} else { |
|
433 |
convertedCnt++; |
|
434 |
} |
|
435 |
if (glyphCode >= INVISIBLE_GLYPHS) { |
|
436 |
images[i] = StrikeCache.invisibleGlyphPtr; |
|
437 |
continue; |
|
438 |
} else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) { |
|
439 |
continue; |
|
440 |
} else { |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
441 |
long glyphPtr = 0L; |
2 | 442 |
if (useNatives) { |
443 |
glyphPtr = getGlyphImageFromNative(glyphCode); |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
444 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
445 |
if (glyphPtr == 0L) { |
2 | 446 |
glyphPtr = fileFont.getGlyphImage(pScalerContext, |
447 |
glyphCode); |
|
448 |
} |
|
449 |
images[i] = setCachedGlyphPtr(glyphCode, glyphPtr); |
|
450 |
} |
|
451 |
} |
|
452 |
return convertedCnt; |
|
453 |
} |
|
454 |
||
455 |
/* Only look in the cache */ |
|
456 |
long getCachedGlyphPtr(int glyphCode) { |
|
457 |
switch (glyphCacheFormat) { |
|
458 |
case INTARRAY: |
|
459 |
return intGlyphImages[glyphCode] & INTMASK; |
|
460 |
case SEGINTARRAY: |
|
461 |
int segIndex = glyphCode >> SEGSHIFT; |
|
462 |
if (segIntGlyphImages[segIndex] != null) { |
|
463 |
int subIndex = glyphCode % SEGSIZE; |
|
464 |
return segIntGlyphImages[segIndex][subIndex] & INTMASK; |
|
465 |
} else { |
|
466 |
return 0L; |
|
467 |
} |
|
468 |
case LONGARRAY: |
|
469 |
return longGlyphImages[glyphCode]; |
|
470 |
case SEGLONGARRAY: |
|
471 |
segIndex = glyphCode >> SEGSHIFT; |
|
472 |
if (segLongGlyphImages[segIndex] != null) { |
|
473 |
int subIndex = glyphCode % SEGSIZE; |
|
474 |
return segLongGlyphImages[segIndex][subIndex]; |
|
475 |
} else { |
|
476 |
return 0L; |
|
477 |
} |
|
478 |
} |
|
479 |
/* If reach here cache is UNINITIALISED. */ |
|
480 |
return 0L; |
|
481 |
} |
|
482 |
||
483 |
private synchronized long setCachedGlyphPtr(int glyphCode, long glyphPtr) { |
|
484 |
switch (glyphCacheFormat) { |
|
485 |
case INTARRAY: |
|
486 |
if (intGlyphImages[glyphCode] == 0) { |
|
487 |
intGlyphImages[glyphCode] = (int)glyphPtr; |
|
488 |
return glyphPtr; |
|
489 |
} else { |
|
490 |
StrikeCache.freeIntPointer((int)glyphPtr); |
|
491 |
return intGlyphImages[glyphCode] & INTMASK; |
|
492 |
} |
|
493 |
||
494 |
case SEGINTARRAY: |
|
495 |
int segIndex = glyphCode >> SEGSHIFT; |
|
496 |
int subIndex = glyphCode % SEGSIZE; |
|
497 |
if (segIntGlyphImages[segIndex] == null) { |
|
498 |
segIntGlyphImages[segIndex] = new int[SEGSIZE]; |
|
499 |
} |
|
500 |
if (segIntGlyphImages[segIndex][subIndex] == 0) { |
|
501 |
segIntGlyphImages[segIndex][subIndex] = (int)glyphPtr; |
|
502 |
return glyphPtr; |
|
503 |
} else { |
|
504 |
StrikeCache.freeIntPointer((int)glyphPtr); |
|
505 |
return segIntGlyphImages[segIndex][subIndex] & INTMASK; |
|
506 |
} |
|
507 |
||
508 |
case LONGARRAY: |
|
509 |
if (longGlyphImages[glyphCode] == 0L) { |
|
510 |
longGlyphImages[glyphCode] = glyphPtr; |
|
511 |
return glyphPtr; |
|
512 |
} else { |
|
513 |
StrikeCache.freeLongPointer(glyphPtr); |
|
514 |
return longGlyphImages[glyphCode]; |
|
515 |
} |
|
516 |
||
517 |
case SEGLONGARRAY: |
|
518 |
segIndex = glyphCode >> SEGSHIFT; |
|
519 |
subIndex = glyphCode % SEGSIZE; |
|
520 |
if (segLongGlyphImages[segIndex] == null) { |
|
521 |
segLongGlyphImages[segIndex] = new long[SEGSIZE]; |
|
522 |
} |
|
523 |
if (segLongGlyphImages[segIndex][subIndex] == 0L) { |
|
524 |
segLongGlyphImages[segIndex][subIndex] = glyphPtr; |
|
525 |
return glyphPtr; |
|
526 |
} else { |
|
527 |
StrikeCache.freeLongPointer(glyphPtr); |
|
528 |
return segLongGlyphImages[segIndex][subIndex]; |
|
529 |
} |
|
530 |
} |
|
531 |
||
532 |
/* Reach here only when the cache is not initialised which is only |
|
533 |
* for the first glyph to be initialised in the strike. |
|
534 |
* Initialise it and recurse. Note that we are already synchronized. |
|
535 |
*/ |
|
536 |
initGlyphCache(); |
|
537 |
return setCachedGlyphPtr(glyphCode, glyphPtr); |
|
538 |
} |
|
539 |
||
540 |
/* Called only from synchronized code or constructor */ |
|
7750 | 541 |
private synchronized void initGlyphCache() { |
2 | 542 |
|
543 |
int numGlyphs = mapper.getNumGlyphs(); |
|
7750 | 544 |
int tmpFormat = UNINITIALISED; |
2 | 545 |
if (segmentedCache) { |
546 |
int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE; |
|
3928 | 547 |
if (longAddresses) { |
7750 | 548 |
tmpFormat = SEGLONGARRAY; |
2 | 549 |
segLongGlyphImages = new long[numSegments][]; |
550 |
this.disposer.segLongGlyphImages = segLongGlyphImages; |
|
551 |
} else { |
|
7750 | 552 |
tmpFormat = SEGINTARRAY; |
2 | 553 |
segIntGlyphImages = new int[numSegments][]; |
554 |
this.disposer.segIntGlyphImages = segIntGlyphImages; |
|
555 |
} |
|
556 |
} else { |
|
3928 | 557 |
if (longAddresses) { |
7750 | 558 |
tmpFormat = LONGARRAY; |
2 | 559 |
longGlyphImages = new long[numGlyphs]; |
560 |
this.disposer.longGlyphImages = longGlyphImages; |
|
561 |
} else { |
|
7750 | 562 |
tmpFormat = INTARRAY; |
2 | 563 |
intGlyphImages = new int[numGlyphs]; |
564 |
this.disposer.intGlyphImages = intGlyphImages; |
|
565 |
} |
|
566 |
} |
|
7750 | 567 |
glyphCacheFormat = tmpFormat; |
2 | 568 |
} |
569 |
||
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
570 |
float getGlyphAdvance(int glyphCode) { |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
571 |
return getGlyphAdvance(glyphCode, true); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
572 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
573 |
|
2 | 574 |
/* Metrics info is always retrieved. If the GlyphInfo address is non-zero |
575 |
* then metrics info there is valid and can just be copied. |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
576 |
* This is in user space coordinates unless getUserAdv == false. |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
577 |
* Device space advance should not be propagated out of this class. |
2 | 578 |
*/ |
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
579 |
private float getGlyphAdvance(int glyphCode, boolean getUserAdv) { |
2 | 580 |
float advance; |
581 |
||
582 |
if (glyphCode >= INVISIBLE_GLYPHS) { |
|
583 |
return 0f; |
|
584 |
} |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
585 |
|
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
586 |
/* Notes on the (getUserAdv == false) case. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
587 |
* |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
588 |
* Setting getUserAdv == false is internal to this class. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
589 |
* If there's no graphics transform we can let |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
590 |
* getGlyphAdvance take its course, and potentially caching in |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
591 |
* advances arrays, except for signalling that |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
592 |
* getUserAdv == false means there is no need to create an image. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
593 |
* It is possible that code already calculated the user advance, |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
594 |
* and it is desirable to take advantage of that work. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
595 |
* But, if there's a transform and we want device advance, we |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
596 |
* can't use any values cached in the advances arrays - unless |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
597 |
* first re-transform them into device space using 'desc.devTx'. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
598 |
* invertDevTx is null if the graphics transform is identity, |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
599 |
* a translate, or non-invertible. The latter case should |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
600 |
* not ever occur in the getUserAdv == false path. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
601 |
* In other words its either null, or the inversion of a |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
602 |
* simple uniform scale. If its null, we can populate and |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
603 |
* use the advance caches as normal. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
604 |
* |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
605 |
* If we don't find a cached value, obtain the device advance and |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
606 |
* return it. This will get stashed on the image by the caller and any |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
607 |
* subsequent metrics calls will be able to use it as is the case |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
608 |
* whenever an image is what is initially requested. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
609 |
* |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
610 |
* Don't query if there's a value cached on the image, since this |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
611 |
* getUserAdv==false code path is entered solely when none exists. |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
612 |
*/ |
2 | 613 |
if (horizontalAdvances != null) { |
614 |
advance = horizontalAdvances[glyphCode]; |
|
615 |
if (advance != Float.MAX_VALUE) { |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
616 |
if (!getUserAdv && invertDevTx != null) { |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
617 |
Point2D.Float metrics = new Point2D.Float(advance, 0f); |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
618 |
desc.devTx.deltaTransform(metrics, metrics); |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
619 |
return metrics.x; |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
620 |
} else { |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
621 |
return advance; |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
622 |
} |
2 | 623 |
} |
624 |
} else if (segmentedCache && segHorizontalAdvances != null) { |
|
625 |
int segIndex = glyphCode >> SEGSHIFT; |
|
626 |
float[] subArray = segHorizontalAdvances[segIndex]; |
|
627 |
if (subArray != null) { |
|
628 |
advance = subArray[glyphCode % SEGSIZE]; |
|
629 |
if (advance != Float.MAX_VALUE) { |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
630 |
if (!getUserAdv && invertDevTx != null) { |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
631 |
Point2D.Float metrics = new Point2D.Float(advance, 0f); |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
632 |
desc.devTx.deltaTransform(metrics, metrics); |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
633 |
return metrics.x; |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
634 |
} else { |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
635 |
return advance; |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
636 |
} |
2 | 637 |
} |
638 |
} |
|
639 |
} |
|
640 |
||
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
641 |
if (!getUserAdv && invertDevTx != null) { |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
642 |
Point2D.Float metrics = new Point2D.Float(); |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
643 |
fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics); |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
644 |
return metrics.x; |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
645 |
} |
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
646 |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
647 |
if (invertDevTx != null || !getUserAdv) { |
2 | 648 |
/* If there is a device transform need x & y advance to |
649 |
* transform back into user space. |
|
650 |
*/ |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
651 |
advance = getGlyphMetrics(glyphCode, getUserAdv).x; |
2 | 652 |
} else { |
653 |
long glyphPtr; |
|
654 |
if (getImageWithAdvance) { |
|
655 |
/* A heuristic optimisation says that for most cases its |
|
656 |
* worthwhile retrieving the image at the same time as the |
|
657 |
* advance. So here we get the image data even if its not |
|
658 |
* already cached. |
|
659 |
*/ |
|
660 |
glyphPtr = getGlyphImagePtr(glyphCode); |
|
661 |
} else { |
|
662 |
glyphPtr = getCachedGlyphPtr(glyphCode); |
|
663 |
} |
|
664 |
if (glyphPtr != 0L) { |
|
665 |
advance = StrikeCache.unsafe.getFloat |
|
666 |
(glyphPtr + StrikeCache.xAdvanceOffset); |
|
667 |
||
668 |
} else { |
|
669 |
advance = fileFont.getGlyphAdvance(pScalerContext, glyphCode); |
|
670 |
} |
|
671 |
} |
|
672 |
||
673 |
if (horizontalAdvances != null) { |
|
674 |
horizontalAdvances[glyphCode] = advance; |
|
675 |
} else if (segmentedCache && segHorizontalAdvances != null) { |
|
676 |
int segIndex = glyphCode >> SEGSHIFT; |
|
677 |
int subIndex = glyphCode % SEGSIZE; |
|
678 |
if (segHorizontalAdvances[segIndex] == null) { |
|
679 |
segHorizontalAdvances[segIndex] = new float[SEGSIZE]; |
|
680 |
for (int i=0; i<SEGSIZE; i++) { |
|
681 |
segHorizontalAdvances[segIndex][i] = Float.MAX_VALUE; |
|
682 |
} |
|
683 |
} |
|
684 |
segHorizontalAdvances[segIndex][subIndex] = advance; |
|
685 |
} |
|
686 |
return advance; |
|
687 |
} |
|
688 |
||
689 |
float getCodePointAdvance(int cp) { |
|
690 |
return getGlyphAdvance(mapper.charToGlyph(cp)); |
|
691 |
} |
|
692 |
||
693 |
/** |
|
694 |
* Result and pt are both in device space. |
|
695 |
*/ |
|
696 |
void getGlyphImageBounds(int glyphCode, Point2D.Float pt, |
|
697 |
Rectangle result) { |
|
698 |
||
699 |
long ptr = getGlyphImagePtr(glyphCode); |
|
700 |
float topLeftX, topLeftY; |
|
701 |
||
702 |
/* With our current design NULL ptr is not possible |
|
703 |
but if we eventually allow scalers to return NULL pointers |
|
704 |
this check might be actually useful. */ |
|
705 |
if (ptr == 0L) { |
|
706 |
result.x = (int) Math.floor(pt.x); |
|
707 |
result.y = (int) Math.floor(pt.y); |
|
708 |
result.width = result.height = 0; |
|
709 |
return; |
|
710 |
} |
|
711 |
||
712 |
topLeftX = StrikeCache.unsafe.getFloat(ptr+StrikeCache.topLeftXOffset); |
|
713 |
topLeftY = StrikeCache.unsafe.getFloat(ptr+StrikeCache.topLeftYOffset); |
|
714 |
||
715 |
result.x = (int)Math.floor(pt.x + topLeftX); |
|
716 |
result.y = (int)Math.floor(pt.y + topLeftY); |
|
717 |
result.width = |
|
718 |
StrikeCache.unsafe.getShort(ptr+StrikeCache.widthOffset) &0x0ffff; |
|
719 |
result.height = |
|
720 |
StrikeCache.unsafe.getShort(ptr+StrikeCache.heightOffset) &0x0ffff; |
|
721 |
||
722 |
/* HRGB LCD text may have padding that is empty. This is almost always |
|
723 |
* going to be when topLeftX is -2 or less. |
|
724 |
* Try to return a tighter bounding box in that case. |
|
725 |
* If the first three bytes of every row are all zero, then |
|
726 |
* add 1 to "x" and reduce "width" by 1. |
|
727 |
*/ |
|
728 |
if ((desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB || |
|
729 |
desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) |
|
730 |
&& topLeftX <= -2.0f) { |
|
22584
eed64ee05369
8032733: Fix cast lint warnings in client libraries
darcy
parents:
21278
diff
changeset
|
731 |
int minx = getGlyphImageMinX(ptr, result.x); |
2 | 732 |
if (minx > result.x) { |
733 |
result.x += 1; |
|
734 |
result.width -=1; |
|
735 |
} |
|
736 |
} |
|
737 |
} |
|
738 |
||
739 |
private int getGlyphImageMinX(long ptr, int origMinX) { |
|
740 |
||
741 |
int width = StrikeCache.unsafe.getChar(ptr+StrikeCache.widthOffset); |
|
742 |
int height = StrikeCache.unsafe.getChar(ptr+StrikeCache.heightOffset); |
|
743 |
int rowBytes = |
|
744 |
StrikeCache.unsafe.getChar(ptr+StrikeCache.rowBytesOffset); |
|
745 |
||
746 |
if (rowBytes == width) { |
|
747 |
return origMinX; |
|
748 |
} |
|
749 |
||
17404
47af135a3e95
7191872: Xrender: No text displayed using 64 bit JDK on solaris11-sparc
simonis
parents:
9759
diff
changeset
|
750 |
long pixelData = |
47af135a3e95
7191872: Xrender: No text displayed using 64 bit JDK on solaris11-sparc
simonis
parents:
9759
diff
changeset
|
751 |
StrikeCache.unsafe.getAddress(ptr + StrikeCache.pixelDataOffset); |
47af135a3e95
7191872: Xrender: No text displayed using 64 bit JDK on solaris11-sparc
simonis
parents:
9759
diff
changeset
|
752 |
|
2 | 753 |
if (pixelData == 0L) { |
754 |
return origMinX; |
|
755 |
} |
|
756 |
||
757 |
for (int y=0;y<height;y++) { |
|
758 |
for (int x=0;x<3;x++) { |
|
759 |
if (StrikeCache.unsafe.getByte(pixelData+y*rowBytes+x) != 0) { |
|
760 |
return origMinX; |
|
761 |
} |
|
762 |
} |
|
763 |
} |
|
764 |
return origMinX+1; |
|
765 |
} |
|
766 |
||
767 |
/* These 3 metrics methods below should be implemented to return |
|
768 |
* values in user space. |
|
769 |
*/ |
|
770 |
StrikeMetrics getFontMetrics() { |
|
771 |
if (strikeMetrics == null) { |
|
772 |
strikeMetrics = |
|
773 |
fileFont.getFontMetrics(pScalerContext); |
|
774 |
if (invertDevTx != null) { |
|
775 |
strikeMetrics.convertToUserSpace(invertDevTx); |
|
776 |
} |
|
777 |
} |
|
778 |
return strikeMetrics; |
|
779 |
} |
|
780 |
||
781 |
Point2D.Float getGlyphMetrics(int glyphCode) { |
|
550
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
782 |
return getGlyphMetrics(glyphCode, true); |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
783 |
} |
e85f91b9bb95
6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents:
546
diff
changeset
|
784 |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
785 |
private Point2D.Float getGlyphMetrics(int glyphCode, boolean getImage) { |
2 | 786 |
Point2D.Float metrics = new Point2D.Float(); |
787 |
||
788 |
// !!! or do we force sgv user glyphs? |
|
789 |
if (glyphCode >= INVISIBLE_GLYPHS) { |
|
790 |
return metrics; |
|
791 |
} |
|
792 |
long glyphPtr; |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
793 |
if (getImageWithAdvance && getImage) { |
2 | 794 |
/* A heuristic optimisation says that for most cases its |
795 |
* worthwhile retrieving the image at the same time as the |
|
796 |
* metrics. So here we get the image data even if its not |
|
797 |
* already cached. |
|
798 |
*/ |
|
799 |
glyphPtr = getGlyphImagePtr(glyphCode); |
|
800 |
} else { |
|
801 |
glyphPtr = getCachedGlyphPtr(glyphCode); |
|
802 |
} |
|
803 |
if (glyphPtr != 0L) { |
|
804 |
metrics = new Point2D.Float(); |
|
805 |
metrics.x = StrikeCache.unsafe.getFloat |
|
806 |
(glyphPtr + StrikeCache.xAdvanceOffset); |
|
807 |
metrics.y = StrikeCache.unsafe.getFloat |
|
808 |
(glyphPtr + StrikeCache.yAdvanceOffset); |
|
809 |
/* advance is currently in device space, need to convert back |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
810 |
* into user space. |
2 | 811 |
* This must not include the translation component. */ |
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
812 |
if (invertDevTx != null) { |
2 | 813 |
invertDevTx.deltaTransform(metrics, metrics); |
814 |
} |
|
815 |
} else { |
|
816 |
/* We sometimes cache these metrics as they are expensive to |
|
817 |
* generate for large glyphs. |
|
818 |
* We never reach this path if we obtain images with advances. |
|
819 |
* But if we do not obtain images with advances its possible that |
|
820 |
* we first obtain this information, then the image, and never |
|
821 |
* will access this value again. |
|
822 |
*/ |
|
438
2ae294e4518c
6613529: Avoid duplicate object creation within JDK packages
dav
parents:
2
diff
changeset
|
823 |
Integer key = Integer.valueOf(glyphCode); |
2 | 824 |
Point2D.Float value = null; |
825 |
ConcurrentHashMap<Integer, Point2D.Float> glyphMetricsMap = null; |
|
826 |
if (glyphMetricsMapRef != null) { |
|
827 |
glyphMetricsMap = glyphMetricsMapRef.get(); |
|
828 |
} |
|
829 |
if (glyphMetricsMap != null) { |
|
830 |
value = glyphMetricsMap.get(key); |
|
831 |
if (value != null) { |
|
832 |
metrics.x = value.x; |
|
833 |
metrics.y = value.y; |
|
834 |
/* already in user space */ |
|
835 |
return metrics; |
|
836 |
} |
|
837 |
} |
|
838 |
if (value == null) { |
|
839 |
fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics); |
|
840 |
/* advance is currently in device space, need to convert back |
|
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
841 |
* into user space. |
2 | 842 |
*/ |
7938
970d0e025e57
6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents:
7757
diff
changeset
|
843 |
if (invertDevTx != null) { |
2 | 844 |
invertDevTx.deltaTransform(metrics, metrics); |
845 |
} |
|
846 |
value = new Point2D.Float(metrics.x, metrics.y); |
|
847 |
/* We aren't synchronizing here so it is possible to |
|
848 |
* overwrite the map with another one but this is harmless. |
|
849 |
*/ |
|
850 |
if (glyphMetricsMap == null) { |
|
851 |
glyphMetricsMap = |
|
852 |
new ConcurrentHashMap<Integer, Point2D.Float>(); |
|
853 |
glyphMetricsMapRef = |
|
854 |
new SoftReference<ConcurrentHashMap<Integer, |
|
855 |
Point2D.Float>>(glyphMetricsMap); |
|
856 |
} |
|
857 |
glyphMetricsMap.put(key, value); |
|
858 |
} |
|
859 |
} |
|
860 |
return metrics; |
|
861 |
} |
|
862 |
||
863 |
Point2D.Float getCharMetrics(char ch) { |
|
864 |
return getGlyphMetrics(mapper.charToGlyph(ch)); |
|
865 |
} |
|
866 |
||
867 |
/* The caller of this can be trusted to return a copy of this |
|
868 |
* return value rectangle to public API. In fact frequently it |
|
869 |
* can't use use this return value directly anyway. |
|
870 |
* This returns bounds in device space. Currently the only |
|
871 |
* caller is SGV and it converts back to user space. |
|
872 |
* We could change things so that this code does the conversion so |
|
873 |
* that all coords coming out of the font system are converted back |
|
874 |
* into user space even if they were measured in device space. |
|
875 |
* The same applies to the other methods that return outlines (below) |
|
876 |
* But it may make particular sense for this method that caches its |
|
877 |
* results. |
|
878 |
* There'd be plenty of exceptions, to this too, eg getGlyphPoint needs |
|
879 |
* device coords as its called from native layout and getGlyphImageBounds |
|
880 |
* is used by GlyphVector.getGlyphPixelBounds which is specified to |
|
881 |
* return device coordinates, the image pointers aren't really used |
|
882 |
* up in Java code either. |
|
883 |
*/ |
|
884 |
Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) { |
|
885 |
||
886 |
if (boundsMap == null) { |
|
887 |
boundsMap = new ConcurrentHashMap<Integer, Rectangle2D.Float>(); |
|
888 |
} |
|
889 |
||
438
2ae294e4518c
6613529: Avoid duplicate object creation within JDK packages
dav
parents:
2
diff
changeset
|
890 |
Integer key = Integer.valueOf(glyphCode); |
2 | 891 |
Rectangle2D.Float bounds = boundsMap.get(key); |
892 |
||
893 |
if (bounds == null) { |
|
894 |
bounds = fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode); |
|
895 |
boundsMap.put(key, bounds); |
|
896 |
} |
|
897 |
return bounds; |
|
898 |
} |
|
899 |
||
900 |
public Rectangle2D getOutlineBounds(int glyphCode) { |
|
901 |
return fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode); |
|
902 |
} |
|
903 |
||
2393 | 904 |
private |
905 |
WeakReference<ConcurrentHashMap<Integer,GeneralPath>> outlineMapRef; |
|
2390 | 906 |
|
2 | 907 |
GeneralPath getGlyphOutline(int glyphCode, float x, float y) { |
2393 | 908 |
|
909 |
GeneralPath gp = null; |
|
910 |
ConcurrentHashMap<Integer, GeneralPath> outlineMap = null; |
|
911 |
||
912 |
if (outlineMapRef != null) { |
|
913 |
outlineMap = outlineMapRef.get(); |
|
914 |
if (outlineMap != null) { |
|
22584
eed64ee05369
8032733: Fix cast lint warnings in client libraries
darcy
parents:
21278
diff
changeset
|
915 |
gp = outlineMap.get(glyphCode); |
2393 | 916 |
} |
2390 | 917 |
} |
2393 | 918 |
|
2390 | 919 |
if (gp == null) { |
920 |
gp = fileFont.getGlyphOutline(pScalerContext, glyphCode, 0, 0); |
|
2393 | 921 |
if (outlineMap == null) { |
922 |
outlineMap = new ConcurrentHashMap<Integer, GeneralPath>(); |
|
923 |
outlineMapRef = |
|
924 |
new WeakReference |
|
925 |
<ConcurrentHashMap<Integer,GeneralPath>>(outlineMap); |
|
926 |
} |
|
2390 | 927 |
outlineMap.put(glyphCode, gp); |
928 |
} |
|
929 |
gp = (GeneralPath)gp.clone(); // mutable! |
|
930 |
if (x != 0f || y != 0f) { |
|
931 |
gp.transform(AffineTransform.getTranslateInstance(x, y)); |
|
932 |
} |
|
933 |
return gp; |
|
2 | 934 |
} |
935 |
||
936 |
GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) { |
|
937 |
return fileFont.getGlyphVectorOutline(pScalerContext, |
|
938 |
glyphs, glyphs.length, x, y); |
|
939 |
} |
|
940 |
||
941 |
protected void adjustPoint(Point2D.Float pt) { |
|
942 |
if (invertDevTx != null) { |
|
943 |
invertDevTx.deltaTransform(pt, pt); |
|
944 |
} |
|
945 |
} |
|
946 |
} |