8233097: Fontmetrics for large Fonts has zero width
Reviewed-by: jdv, serb
This commit is contained in:
parent
7d0e14178d
commit
00426d6cb0
src/java.desktop/share/native/libfontmanager
test/jdk/java/awt/FontClass
@ -611,6 +611,12 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative(
|
||||
return metrics;
|
||||
}
|
||||
|
||||
static jlong
|
||||
getGlyphImageNativeInternal(
|
||||
JNIEnv *env, jobject scaler, jobject font2D,
|
||||
jlong pScalerContext, jlong pScaler, jint glyphCode,
|
||||
jboolean renderImage);
|
||||
|
||||
/*
|
||||
* Class: sun_font_FreetypeFontScaler
|
||||
* Method: getGlyphAdvanceNative
|
||||
@ -622,24 +628,23 @@ Java_sun_font_FreetypeFontScaler_getGlyphAdvanceNative(
|
||||
jlong pScalerContext, jlong pScaler, jint glyphCode) {
|
||||
|
||||
/* This method is rarely used because requests for metrics are usually
|
||||
coupled with request for bitmap and to large extend work can be reused
|
||||
(to find out metrics we need to hint glyph).
|
||||
So, we typically go through getGlyphImage code path.
|
||||
|
||||
For initial freetype implementation we delegate
|
||||
all work to getGlyphImage but drop result image.
|
||||
This is waste of work related to scan conversion and conversion from
|
||||
freetype format to our format but for now this seems to be ok.
|
||||
|
||||
NB: investigate performance benefits of refactoring code
|
||||
to avoid unnecesary work with bitmaps. */
|
||||
* coupled with a request for the bitmap and to a large extent the
|
||||
* work can be reused (to find out metrics we may need to hint the glyph).
|
||||
* So, we typically go through the getGlyphImage code path.
|
||||
* When we do get here, we need to pass a parameter which indicates
|
||||
* that we don't need freetype to render the bitmap, and consequently
|
||||
* don't need to allocate our own storage either.
|
||||
* This is also important when enter here requesting metrics for sizes
|
||||
* of text which a large size would be rejected for a bitmap but we
|
||||
* still need the metrics.
|
||||
*/
|
||||
|
||||
GlyphInfo *info;
|
||||
jfloat advance = 0.0f;
|
||||
jlong image;
|
||||
|
||||
image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
env, scaler, font2D, pScalerContext, pScaler, glyphCode);
|
||||
image = getGlyphImageNativeInternal(
|
||||
env, scaler, font2D, pScalerContext, pScaler, glyphCode, JNI_FALSE);
|
||||
info = (GlyphInfo*) jlong_to_ptr(image);
|
||||
|
||||
if (info != NULL) {
|
||||
@ -660,17 +665,12 @@ Java_sun_font_FreetypeFontScaler_getGlyphMetricsNative(
|
||||
JNIEnv *env, jobject scaler, jobject font2D, jlong pScalerContext,
|
||||
jlong pScaler, jint glyphCode, jobject metrics) {
|
||||
|
||||
/* As initial implementation we delegate all work to getGlyphImage
|
||||
but drop result image. This is clearly waste of resorces.
|
||||
|
||||
TODO: investigate performance benefits of refactoring code
|
||||
by avoiding bitmap generation and conversion from FT
|
||||
bitmap format. */
|
||||
/* See the comments in getGlyphMetricsNative. They apply here too. */
|
||||
GlyphInfo *info;
|
||||
|
||||
jlong image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
jlong image = getGlyphImageNativeInternal(
|
||||
env, scaler, font2D,
|
||||
pScalerContext, pScaler, glyphCode);
|
||||
pScalerContext, pScaler, glyphCode, JNI_FALSE);
|
||||
info = (GlyphInfo*) jlong_to_ptr(image);
|
||||
|
||||
if (info != NULL) {
|
||||
@ -804,6 +804,17 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
JNIEnv *env, jobject scaler, jobject font2D,
|
||||
jlong pScalerContext, jlong pScaler, jint glyphCode) {
|
||||
|
||||
return getGlyphImageNativeInternal(
|
||||
env, scaler, font2D,
|
||||
pScalerContext, pScaler, glyphCode, JNI_TRUE);
|
||||
}
|
||||
|
||||
static jlong
|
||||
getGlyphImageNativeInternal(
|
||||
JNIEnv *env, jobject scaler, jobject font2D,
|
||||
jlong pScalerContext, jlong pScaler, jint glyphCode,
|
||||
jboolean renderImage) {
|
||||
|
||||
int error, imageSize;
|
||||
UInt16 width, height;
|
||||
GlyphInfo *glyphInfo;
|
||||
@ -866,7 +877,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
|
||||
/* generate bitmap if it is not done yet
|
||||
e.g. if algorithmic styling is performed and style was added to outline */
|
||||
if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
if (renderImage && (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
|
||||
FT_BBox bbox;
|
||||
FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
|
||||
int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
|
||||
@ -881,12 +892,17 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
}
|
||||
}
|
||||
|
||||
width = (UInt16) ftglyph->bitmap.width;
|
||||
height = (UInt16) ftglyph->bitmap.rows;
|
||||
if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
|
||||
glyphInfo = getNullGlyphImage();
|
||||
return ptr_to_jlong(glyphInfo);
|
||||
}
|
||||
if (renderImage) {
|
||||
width = (UInt16) ftglyph->bitmap.width;
|
||||
height = (UInt16) ftglyph->bitmap.rows;
|
||||
if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
|
||||
glyphInfo = getNullGlyphImage();
|
||||
return ptr_to_jlong(glyphInfo);
|
||||
}
|
||||
} else {
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
|
||||
imageSize = width*height;
|
||||
@ -900,13 +916,16 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
glyphInfo->rowBytes = width;
|
||||
glyphInfo->width = width;
|
||||
glyphInfo->height = height;
|
||||
glyphInfo->topLeftX = (float) ftglyph->bitmap_left;
|
||||
glyphInfo->topLeftY = (float) -ftglyph->bitmap_top;
|
||||
|
||||
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) {
|
||||
glyphInfo->width = width/3;
|
||||
} else if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) {
|
||||
glyphInfo->height = glyphInfo->height/3;
|
||||
if (renderImage) {
|
||||
glyphInfo->topLeftX = (float) ftglyph->bitmap_left;
|
||||
glyphInfo->topLeftY = (float) -ftglyph->bitmap_top;
|
||||
|
||||
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) {
|
||||
glyphInfo->width = width/3;
|
||||
} else if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) {
|
||||
glyphInfo->height = glyphInfo->height/3;
|
||||
}
|
||||
}
|
||||
|
||||
if (context->fmType == TEXT_FM_ON) {
|
||||
|
69
test/jdk/java/awt/FontClass/MassiveMetricsTest.java
Normal file
69
test/jdk/java/awt/FontClass/MassiveMetricsTest.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8233097
|
||||
* @summary Test we get non-zero metrics with large sizes.
|
||||
* @run main MassiveMetricsTest
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class MassiveMetricsTest {
|
||||
|
||||
public static void main(String [] args) {
|
||||
|
||||
GraphicsEnvironment ge =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Font[] fonts = ge.getAllFonts();
|
||||
BufferedImage bi = new BufferedImage(1,1,1);
|
||||
Graphics2D g2d = bi.createGraphics();
|
||||
int[] sizes = { 80, 100, 120, 600, 1600, 2400, 3600, 7200, 12000 };
|
||||
String s = "m";
|
||||
|
||||
for (Font f : fonts) {
|
||||
Font sz12Font = f.deriveFont(Font.PLAIN, 12);
|
||||
FontMetrics sz12 = g2d.getFontMetrics(sz12Font);
|
||||
if (sz12.stringWidth(s) == 0) {
|
||||
continue; // code point not supported or similar.
|
||||
}
|
||||
boolean fail = false;
|
||||
for (int sz : sizes) {
|
||||
Font font = f.deriveFont(Font.PLAIN, sz);
|
||||
FontMetrics fm = g2d.getFontMetrics(font);
|
||||
if (fm.stringWidth(s) == 0) {
|
||||
fail = true;
|
||||
System.err.println("zero for " + font);
|
||||
}
|
||||
}
|
||||
if (fail) {
|
||||
throw new RuntimeException("Zero stringwidth");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user