Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=46512 -- 'ClearType compatible advance width'[1] is introduced by Microsoft to ensure that it is compatible with previous GRAY and B/W antialias metric. This can be specified as CLEARTYPE_QUALITY. Unfortunately, Freetype does not have 'ClearType compatible advance widths'[2].
So, we need to use FT_LOAD_TARGET_MONO to get the right advance value. Please note that this flag is a hinting flag, not a rendering flag.
FT_LOAD_TARGET_LCD can be used for CLEARTYPE_NATURAL_QUALITY [3].
[1] http://rastertragedy.com/RTRCh4.htm#Sec2
[2] Freetype interpreter V38(A.K.A. Infinality patch) is trying to implement it, but there are many bugs and no further improvements. This is not included in the default build option, and is documented as being deprecated in the future.
[3] With CLEARTYPE_NATURAL_QUALITY(ClearType natural advance widths), some legacy fonts are not ( integer ) linear with the advance width. To avoid the subpixel color blending problem between the small side-bearing characters, Microsoft seems to have modified the right-side-bearing. Also, there are issues that pointed out in [1].
This may be a text layout issue, but FT_LOAD_TARGET_LCD is still valid. To solve this, Wine need an additional advance correction patch, but it's not yet an interesting issue compared to other issues.
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- dlls/gdi32/freetype.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index c38108eece..85cff28c22 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -6897,31 +6897,28 @@ static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int b return needed; }
-static FT_Int get_load_flags( UINT format ) +static FT_Int get_load_flags( UINT format, GdiFont *font ) { + BOOL natural_width; FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
if (format & GGO_UNHINTED) return load_flags | FT_LOAD_NO_HINTING;
+ natural_width = font->font_desc.lf.lfQuality == CLEARTYPE_NATURAL_QUALITY; + switch (format & ~GGO_GLYPH_INDEX) { - case GGO_BITMAP: - load_flags |= FT_LOAD_TARGET_MONO; - break; - case GGO_GRAY2_BITMAP: - case GGO_GRAY4_BITMAP: - case GGO_GRAY8_BITMAP: - case WINE_GGO_GRAY16_BITMAP: - load_flags |= FT_LOAD_TARGET_NORMAL; - break; case WINE_GGO_HRGB_BITMAP: case WINE_GGO_HBGR_BITMAP: - load_flags |= FT_LOAD_TARGET_LCD; + load_flags |= natural_width ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_MONO; break; case WINE_GGO_VRGB_BITMAP: case WINE_GGO_VBGR_BITMAP: - load_flags |= FT_LOAD_TARGET_LCD_V; + load_flags |= natural_width ? FT_LOAD_TARGET_LCD_V : FT_LOAD_TARGET_MONO; + break; + default: + load_flags |= FT_LOAD_TARGET_MONO; break; }
@@ -6947,7 +6944,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, FT_Vector adv; INT origin_x = 0, origin_y = 0; FT_Angle angle = 0; - FT_Int load_flags = get_load_flags(format); + FT_Int load_flags = get_load_flags(format, incoming_font); double widthRatio = 1.0; FT_Matrix transMat = identityMat; FT_Matrix transMatUnrotated;