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 &&
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;
381 } else {
382 long glyphPtr = 0L;
383 if (useNatives) {
384 glyphPtr = getGlyphImageFromNative(glyphCode);
385 } if (glyphPtr == 0L) {
386 glyphPtr = fileFont.getGlyphImage(pScalerContext,
|
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.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 &&
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 if (FontUtilities.isLogging()) {
321 FontUtilities.logWarning("Failed to render glyph using GDI: code=" + glyphCode
322 + ", fontFamily=" + family + ", style=" + style
323 + ", size=" + size);
324 }
325 return fileFont.getGlyphImage(pScalerContext, glyphCode);
326 }
327 }
328
329 /* Try the native strikes first, then try the fileFont strike */
330 long getGlyphImageFromX11(int glyphCode) {
331 long glyphPtr;
332 char charCode = fileFont.glyphToCharMap[glyphCode];
333 for (int i=0;i<nativeStrikes.length;i++) {
334 CharToGlyphMapper mapper = fileFont.nativeFonts[i].getMapper();
335 int gc = mapper.charToGlyph(charCode)&0xffff;
336 if (gc != mapper.getMissingGlyphCode()) {
337 glyphPtr = nativeStrikes[i].getGlyphImagePtrNoCache(gc);
338 if (glyphPtr != 0L) {
339 return glyphPtr;
340 }
341 }
342 }
343 return fileFont.getGlyphImage(pScalerContext, glyphCode);
344 }
345
346 long getGlyphImagePtr(int glyphCode) {
347 if (glyphCode >= INVISIBLE_GLYPHS) {
348 return StrikeCache.invisibleGlyphPtr;
349 }
350 long glyphPtr = 0L;
351 if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
352 return glyphPtr;
353 } else {
354 if (useNatives) {
355 glyphPtr = getGlyphImageFromNative(glyphCode);
356 if (glyphPtr == 0L && FontUtilities.isLogging()) {
357 FontUtilities.logInfo("Strike for " + fileFont +
358 " at size = " + intPtSize +
359 " couldn't get native glyph for code = " + glyphCode);
360 }
361 }
362 if (glyphPtr == 0L) {
363 glyphPtr = fileFont.getGlyphImage(pScalerContext, glyphCode);
364 }
365 return setCachedGlyphPtr(glyphCode, glyphPtr);
366 }
367 }
368
369 void getGlyphImagePtrs(int[] glyphCodes, long[] images, int len) {
370
371 for (int i=0; i<len; i++) {
372 int glyphCode = glyphCodes[i];
373 if (glyphCode >= INVISIBLE_GLYPHS) {
374 images[i] = StrikeCache.invisibleGlyphPtr;
375 continue;
376 } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
377 continue;
378 } else {
379 long glyphPtr = 0L;
380 if (useNatives) {
381 glyphPtr = getGlyphImageFromNative(glyphCode);
382 } if (glyphPtr == 0L) {
383 glyphPtr = fileFont.getGlyphImage(pScalerContext,
|