[PATCH] gdi32: Allow the embedded bitmap loading of the CJK font at the subpixel rendering mode.

Byeongsik Jeon bsjeon at hanmail.net
Tue Feb 12 08:04:36 CST 2019


https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-taglogfonta#remarks
----
The following situations do not support ClearType antialiasing:
The font has tuned embedded bitmaps, for any font sizes that contain the
embedded bitmaps. For example, this occurs commonly in East Asian fonts.
----

I'll post some independent patches first.

I looked at some real cases, and thought the embedded bitmap loading was
affected by the gasp table flag. As a result, it is wrong.

To make it more obvious, I tested it with some manipulated fonts. The bitmap
loading is affected by a specific bit of OS/2 table ulCodePageRange1.
I looked at these bits one by one. This works regardless of whether the font
CJK region glyph actually exists.

This issue is a very old issue, but we were not finding the right solution.
So we had to apply a temporary patch based on font names for a long time.

Windows built-in CJK classic fonts have the embedded bitmap. And some wrong
applications programmed under the assumption that they are rendered as B/W
bitmap. For example: wine-bug#28009

Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=28009
Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
 dlls/gdi32/freetype.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 0fc41f3902..be0e5424f1 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -7482,6 +7482,41 @@ static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int b
     return needed;
 }
 
+static BOOL is_marked_as_cjk_font( GdiFont *font )
+{
+    return font->fs.fsCsb[0] & (FS_JISJAPAN | FS_CHINESESIMP | FS_WANSUNG | FS_CHINESETRAD);
+}
+
+static FT_Int get_embedded_bitmap_load_flags( UINT format, GdiFont *font, BOOL needsTransform )
+{
+    FT_Int load_flags = 0;
+
+    if (needsTransform)
+	return FT_LOAD_NO_BITMAP;
+
+    switch (format)
+    {
+	case GGO_BITMAP:
+	    break;
+	case GGO_GRAY2_BITMAP:
+	case GGO_GRAY4_BITMAP:
+	case GGO_GRAY8_BITMAP:
+	case GGO_NATIVE:
+	case GGO_BEZIER:
+	    load_flags = FT_LOAD_NO_BITMAP;
+	    break;
+	case WINE_GGO_GRAY16_BITMAP:
+	case WINE_GGO_HRGB_BITMAP:
+	case WINE_GGO_HBGR_BITMAP:
+	case WINE_GGO_VRGB_BITMAP:
+	case WINE_GGO_VBGR_BITMAP:
+	    if (!is_marked_as_cjk_font( font )) load_flags = FT_LOAD_NO_BITMAP;
+	    break;
+    }
+
+    return load_flags;
+}
+
 static FT_Int get_load_flags( UINT format )
 {
     FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
@@ -7572,7 +7607,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
     if (vertical_metrics && FT_SimpleVersion < FT_VERSION_VALUE(2, 4, 0))
         vertical_metrics = FALSE;
 
-    if (needsTransform || format != GGO_BITMAP) load_flags |= FT_LOAD_NO_BITMAP;
+    load_flags |= get_embedded_bitmap_load_flags( format, font, needsTransform );
     if (vertical_metrics) load_flags |= FT_LOAD_VERTICAL_LAYOUT;
 
     err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
-- 
2.20.1




More information about the wine-devel mailing list