Skip to content
Permalink
Browse files

8236996: Incorrect Roboto font rendering on Windows with subpixel ant…

…ialiasing

Reviewed-by: prr, serb
  • Loading branch information
Dmitry Batrak
Dmitry Batrak committed Jan 27, 2020
1 parent 785e7ec commit 1af34250aabe4d266a1e42ef5b8c403e8077f2de
@@ -328,7 +328,8 @@ private native long _getGlyphImageFromWindows(String family,
int style,
int size,
int glyphCode,
boolean fracMetrics);
boolean fracMetrics,
int fontDataSize);

long getGlyphImageFromWindows(int glyphCode) {
String family = fileFont.getFamilyName(null);
@@ -337,7 +338,8 @@ long getGlyphImageFromWindows(int glyphCode) {
int size = intPtSize;
long ptr = _getGlyphImageFromWindows
(family, style, size, glyphCode,
desc.fmHint == INTVAL_FRACTIONALMETRICS_ON);
desc.fmHint == INTVAL_FRACTIONALMETRICS_ON,
((TrueTypeFont)fileFont).fontDataSize);
if (ptr != 0) {
/* Get the advance from the JDK rasterizer. This is mostly
* necessary for the fractional metrics case, but there are
@@ -351,6 +353,12 @@ long getGlyphImageFromWindows(int glyphCode) {
advance);
return ptr;
} else {
if (FontUtilities.isLogging()) {
FontUtilities.getLogger().warning(
"Failed to render glyph using GDI: code=" + glyphCode
+ ", fontFamily=" + family + ", style=" + style
+ ", size=" + size);
}
return fileFont.getGlyphImage(pScalerContext, glyphCode);
}
}
@@ -180,6 +180,15 @@ public synchronized void dispose() {
private String localeFamilyName;
private String localeFullName;

/*
* Used on Windows to validate the font selected by GDI for (sub-pixel
* antialiased) rendering. For 'standalone' fonts it's equal to the font
* file size, for collection (TTC, OTC) members it's the number of bytes in
* the collection file from the start of this font's offset table till the
* end of the file.
*/
int fontDataSize;

public TrueTypeFont(String platname, Object nativeNames, int fIndex,
boolean javaRasterizer)
throws FontFormatException
@@ -537,11 +546,13 @@ protected void init(int fIndex) throws FontFormatException {
fontIndex = fIndex;
buffer = readBlock(TTCHEADERSIZE+4*fIndex, 4);
headerOffset = buffer.getInt();
fontDataSize = Math.max(0, fileSize - headerOffset);
break;

case v1ttTag:
case trueTag:
case ottoTag:
fontDataSize = fileSize;
break;

default:
@@ -172,7 +172,8 @@ JNIEXPORT jboolean JNICALL
JNIEXPORT jlong JNICALL
Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
(JNIEnv *env, jobject unused,
jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) {
jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm,
jint fontDataSize) {

GLYPHMETRICS glyphMetrics;
LOGFONTW lf;
@@ -188,6 +189,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
LPWSTR name;
HFONT oldFont, hFont;
MAT2 mat2;
DWORD actualFontDataSize;

unsigned short width;
unsigned short height;
@@ -254,6 +256,17 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
}
oldFont = SelectObject(hMemoryDC, hFont);

if (fontDataSize > 0) {
// GDI doesn't allow to select a specific font file for drawing, we can
// only check that it picks the file we need by validating font size.
// If it doesn't match, we cannot proceed, as the same glyph code can
// correspond to a completely different glyph in the selected font.
actualFontDataSize = GetFontData(hMemoryDC, 0, 0, NULL, 0);
if (actualFontDataSize != fontDataSize) {
FREE_AND_RETURN;
}
}

tmpBitmap = CreateCompatibleBitmap(hDesktopDC, 1, 1);
if (tmpBitmap == NULL) {
FREE_AND_RETURN;

0 comments on commit 1af3425

Please sign in to comment.