205 }
206 /* First, see if native code should be used to create the glyph.
207 * GDI will return the integer metrics, not fractional metrics, which
208 * may be requested for this strike, so we would require here that :
209 * desc.fmHint != INTVAL_FRACTIONALMETRICS_ON
210 * except that the advance returned by GDI is always overwritten by
211 * the JDK rasteriser supplied one (see getGlyphImageFromWindows()).
212 */
213 if (FontUtilities.isWindows && isXPorLater &&
214 !FontUtilities.useJDKScaler &&
215 !GraphicsEnvironment.isHeadless() &&
216 !fileFont.useJavaRasterizer &&
217 (desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
218 desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) &&
219 (matrix[1] == 0.0 && matrix[2] == 0.0 &&
220 matrix[0] == matrix[3] &&
221 matrix[0] >= 3.0 && matrix[0] <= 100.0) &&
222 !((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) {
223 useNatives = true;
224 }
225 if (FontUtilities.isLogging() && FontUtilities.isWindows) {
226 FontUtilities.getLogger().info
227 ("Strike for " + fileFont + " at size = " + intPtSize +
228 " use natives = " + useNatives +
229 " useJavaRasteriser = " + fileFont.useJavaRasterizer +
230 " AAHint = " + desc.aaHint +
231 " Has Embedded bitmaps = " +
232 ((TrueTypeFont)fileFont).
233 useEmbeddedBitmapsForSize(intPtSize));
234 }
235 this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext);
236
237 /* Always get the image and the advance together for smaller sizes
238 * that are likely to be important to rendering performance.
239 * The pixel size of 48.0 can be thought of as
240 * "maximumSizeForGetImageWithAdvance".
241 * This should be no greater than OutlineTextRender.THRESHOLD.
242 */
243 double maxSz = 48.0;
244 getImageWithAdvance =
245 Math.abs(at.getScaleX()) <= maxSz &&
246 Math.abs(at.getScaleY()) <= maxSz &&
247 Math.abs(at.getShearX()) <= maxSz &&
301 int style = desc.style & Font.BOLD | desc.style & Font.ITALIC
302 | fileFont.getStyle();
303 int size = intPtSize;
304 long ptr = _getGlyphImageFromWindows
305 (family, style, size, glyphCode,
306 desc.fmHint == INTVAL_FRACTIONALMETRICS_ON,
307 ((TrueTypeFont)fileFont).fontDataSize);
308 if (ptr != 0) {
309 /* Get the advance from the JDK rasterizer. This is mostly
310 * necessary for the fractional metrics case, but there are
311 * also some very small number (<0.25%) of marginal cases where
312 * there is some rounding difference between windows and JDK.
313 * After these are resolved, we can restrict this extra
314 * work to the FM case.
315 */
316 float advance = getGlyphAdvance(glyphCode, false);
317 StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset,
318 advance);
319 return ptr;
320 } else {
321 if (FontUtilities.isLogging()) {
322 FontUtilities.getLogger().warning(
323 "Failed to render glyph using GDI: code=" + glyphCode
324 + ", fontFamily=" + family + ", style=" + style
325 + ", size=" + size);
326 }
327 return fileFont.getGlyphImage(pScalerContext, glyphCode);
328 }
329 }
330
331 /* Try the native strikes first, then try the fileFont strike */
332 long getGlyphImageFromX11(int glyphCode) {
333 long glyphPtr;
334 char charCode = fileFont.glyphToCharMap[glyphCode];
335 for (int i=0;i<nativeStrikes.length;i++) {
336 CharToGlyphMapper mapper = fileFont.nativeFonts[i].getMapper();
337 int gc = mapper.charToGlyph(charCode)&0xffff;
338 if (gc != mapper.getMissingGlyphCode()) {
339 glyphPtr = nativeStrikes[i].getGlyphImagePtrNoCache(gc);
340 if (glyphPtr != 0L) {
341 return glyphPtr;
342 }
343 }
344 }
345 return fileFont.getGlyphImage(pScalerContext, glyphCode);
346 }
347
348 long getGlyphImagePtr(int glyphCode) {
349 if (glyphCode >= INVISIBLE_GLYPHS) {
350 return StrikeCache.invisibleGlyphPtr;
351 }
352 long glyphPtr = 0L;
353 if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
354 return glyphPtr;
355 } else {
356 if (useNatives) {
357 glyphPtr = getGlyphImageFromNative(glyphCode);
358 if (glyphPtr == 0L && FontUtilities.isLogging()) {
359 FontUtilities.getLogger().info
360 ("Strike for " + fileFont +
361 " at size = " + intPtSize +
362 " couldn't get native glyph for code = " + glyphCode);
363 }
364 } if (glyphPtr == 0L) {
365 glyphPtr = fileFont.getGlyphImage(pScalerContext,
366 glyphCode);
367 }
368 return setCachedGlyphPtr(glyphCode, glyphPtr);
369 }
370 }
371
372 void getGlyphImagePtrs(int[] glyphCodes, long[] images, int len) {
373
374 for (int i=0; i<len; i++) {
375 int glyphCode = glyphCodes[i];
376 if (glyphCode >= INVISIBLE_GLYPHS) {
377 images[i] = StrikeCache.invisibleGlyphPtr;
378 continue;
379 } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
380 continue;
|
205 }
206 /* First, see if native code should be used to create the glyph.
207 * GDI will return the integer metrics, not fractional metrics, which
208 * may be requested for this strike, so we would require here that :
209 * desc.fmHint != INTVAL_FRACTIONALMETRICS_ON
210 * except that the advance returned by GDI is always overwritten by
211 * the JDK rasteriser supplied one (see getGlyphImageFromWindows()).
212 */
213 if (FontUtilities.isWindows && isXPorLater &&
214 !FontUtilities.useJDKScaler &&
215 !GraphicsEnvironment.isHeadless() &&
216 !fileFont.useJavaRasterizer &&
217 (desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
218 desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) &&
219 (matrix[1] == 0.0 && matrix[2] == 0.0 &&
220 matrix[0] == matrix[3] &&
221 matrix[0] >= 3.0 && matrix[0] <= 100.0) &&
222 !((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) {
223 useNatives = true;
224 }
225 if (FontUtilities.isWindows) {
226 FontUtilities.logInfo("Strike for " + fileFont + " at size = " + intPtSize +
227 " use natives = " + useNatives +
228 " useJavaRasteriser = " + fileFont.useJavaRasterizer +
229 " AAHint = " + desc.aaHint +
230 " Has Embedded bitmaps = " +
231 ((TrueTypeFont)fileFont).
232 useEmbeddedBitmapsForSize(intPtSize));
233 }
234 this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext);
235
236 /* Always get the image and the advance together for smaller sizes
237 * that are likely to be important to rendering performance.
238 * The pixel size of 48.0 can be thought of as
239 * "maximumSizeForGetImageWithAdvance".
240 * This should be no greater than OutlineTextRender.THRESHOLD.
241 */
242 double maxSz = 48.0;
243 getImageWithAdvance =
244 Math.abs(at.getScaleX()) <= maxSz &&
245 Math.abs(at.getScaleY()) <= maxSz &&
246 Math.abs(at.getShearX()) <= maxSz &&
300 int style = desc.style & Font.BOLD | desc.style & Font.ITALIC
301 | fileFont.getStyle();
302 int size = intPtSize;
303 long ptr = _getGlyphImageFromWindows
304 (family, style, size, glyphCode,
305 desc.fmHint == INTVAL_FRACTIONALMETRICS_ON,
306 ((TrueTypeFont)fileFont).fontDataSize);
307 if (ptr != 0) {
308 /* Get the advance from the JDK rasterizer. This is mostly
309 * necessary for the fractional metrics case, but there are
310 * also some very small number (<0.25%) of marginal cases where
311 * there is some rounding difference between windows and JDK.
312 * After these are resolved, we can restrict this extra
313 * work to the FM case.
314 */
315 float advance = getGlyphAdvance(glyphCode, false);
316 StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset,
317 advance);
318 return ptr;
319 } else {
320 FontUtilities.logWarning("Failed to render glyph using GDI: code=" + glyphCode
321 + ", fontFamily=" + family + ", style=" + style
322 + ", size=" + size);
323 return fileFont.getGlyphImage(pScalerContext, glyphCode);
324 }
325 }
326
327 /* Try the native strikes first, then try the fileFont strike */
328 long getGlyphImageFromX11(int glyphCode) {
329 long glyphPtr;
330 char charCode = fileFont.glyphToCharMap[glyphCode];
331 for (int i=0;i<nativeStrikes.length;i++) {
332 CharToGlyphMapper mapper = fileFont.nativeFonts[i].getMapper();
333 int gc = mapper.charToGlyph(charCode)&0xffff;
334 if (gc != mapper.getMissingGlyphCode()) {
335 glyphPtr = nativeStrikes[i].getGlyphImagePtrNoCache(gc);
336 if (glyphPtr != 0L) {
337 return glyphPtr;
338 }
339 }
340 }
341 return fileFont.getGlyphImage(pScalerContext, glyphCode);
342 }
343
344 long getGlyphImagePtr(int glyphCode) {
345 if (glyphCode >= INVISIBLE_GLYPHS) {
346 return StrikeCache.invisibleGlyphPtr;
347 }
348 long glyphPtr = 0L;
349 if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
350 return glyphPtr;
351 } else {
352 if (useNatives) {
353 glyphPtr = getGlyphImageFromNative(glyphCode);
354 if (glyphPtr == 0L) {
355 FontUtilities.logInfo("Strike for " + fileFont +
356 " at size = " + intPtSize +
357 " couldn't get native glyph for code = " + glyphCode);
358 }
359 } if (glyphPtr == 0L) {
360 glyphPtr = fileFont.getGlyphImage(pScalerContext,
361 glyphCode);
362 }
363 return setCachedGlyphPtr(glyphCode, glyphPtr);
364 }
365 }
366
367 void getGlyphImagePtrs(int[] glyphCodes, long[] images, int len) {
368
369 for (int i=0; i<len; i++) {
370 int glyphCode = glyphCodes[i];
371 if (glyphCode >= INVISIBLE_GLYPHS) {
372 images[i] = StrikeCache.invisibleGlyphPtr;
373 continue;
374 } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
375 continue;
|