From: Byeongsik Jeon Subject: [PATCH 3/6] gdi32: Add a helper function to get a more accurate transformed outline bbox. Message-Id: <20190211082021.12986-3-bsjeon@hanmail.net> Date: Mon, 11 Feb 2019 17:20:18 +0900 In-Reply-To: <20190211082021.12986-1-bsjeon@hanmail.net> References: <20190211082021.12986-1-bsjeon@hanmail.net> Signed-off-by: Byeongsik Jeon --- For example, the rotation of 'O', the slant of 'V'. get_transformed_bitmap() implementation will be posted separately: WINFNT bitmap transform(scale, slant, ...). dlls/gdi32/freetype.c | 73 ++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index d099f6cb44..1f1957f2ca 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -6992,8 +6992,30 @@ static void compute_metrics( GdiFont *incoming_font, GdiFont *font, static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; -static DWORD get_mono_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, - BOOL fake_bold, BOOL needs_transform, FT_Matrix matrices[3], +static FT_BBox get_transformed_outline( FT_Outline *outline, FT_BBox bbox, + BOOL needs_transform, const FT_Matrix matrices[3] ) +{ + FT_BBox cbox; + + if (needs_transform) + pFT_Outline_Transform( outline, &matrices[matrix_vert] ); + pFT_Outline_Get_CBox( outline, &cbox ); + + /* Respect the poorly created fonts metrics fixing. */ + bbox.xMin = max( bbox.xMin, cbox.xMin ); + bbox.xMax = min( bbox.xMax, cbox.xMax ); + bbox.yMin = max( bbox.yMin, cbox.yMin ); + bbox.yMax = min( bbox.yMax, cbox.yMax ); + + bbox.xMin = bbox.xMin & -64; + bbox.xMax = (bbox.xMax + 63) & -64; + bbox.yMax = (bbox.yMax + 63) & -64; + bbox.yMin = bbox.yMin & -64; + + return bbox; +} + +static DWORD get_mono_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, BOOL fake_bold, DWORD buflen, BYTE *buf ) { DWORD width = (bbox.xMax - bbox.xMin ) >> 6; @@ -7041,12 +7063,9 @@ static DWORD get_mono_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO; ft_bitmap.buffer = buf; - if (needs_transform) - pFT_Outline_Transform( &glyph->outline, &matrices[matrix_vert] ); - pFT_Outline_Translate( &glyph->outline, -bbox.xMin, -bbox.yMin ); - /* Note: FreeType will only set 'black' bits for us. */ memset( buf, 0, buflen ); + pFT_Outline_Translate( &glyph->outline, -bbox.xMin, -bbox.yMin ); pFT_Outline_Get_Bitmap( library, &glyph->outline, &ft_bitmap ); break; @@ -7059,8 +7078,7 @@ static DWORD get_mono_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, } static DWORD get_antialias_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, UINT format, - BOOL fake_bold, BOOL needs_transform, FT_Matrix matrices[3], - DWORD buflen, BYTE *buf ) + BOOL fake_bold, DWORD buflen, BYTE *buf ) { DWORD width = (bbox.xMax - bbox.xMin ) >> 6; DWORD height = (bbox.yMax - bbox.yMin ) >> 6; @@ -7107,11 +7125,8 @@ static DWORD get_antialias_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, UINT ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; ft_bitmap.buffer = buf; - if (needs_transform) - pFT_Outline_Transform( &glyph->outline, &matrices[matrix_vert] ); - pFT_Outline_Translate( &glyph->outline, -bbox.xMin, -bbox.yMin ); - memset( buf, 0, buflen ); + pFT_Outline_Translate( &glyph->outline, -bbox.xMin, -bbox.yMin ); pFT_Outline_Get_Bitmap( library, &glyph->outline, &ft_bitmap ); if (max_level != 255) @@ -7137,8 +7152,7 @@ static DWORD get_antialias_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, UINT } static DWORD get_subpixel_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox *bbox, UINT format, - BOOL fake_bold, BOOL needs_transform, FT_Matrix matrices[3], - DWORD buflen, BYTE *buf ) + BOOL fake_bold, DWORD buflen, BYTE *buf ) { DWORD width = (bbox->xMax - bbox->xMin ) >> 6; DWORD height = (bbox->yMax - bbox->yMin ) >> 6; @@ -7213,9 +7227,6 @@ static DWORD get_subpixel_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox *bbox, UINT if (!buf || !buflen) return needed; if (needed > buflen) return GDI_ERROR; - if (needs_transform) - pFT_Outline_Transform( &glyph->outline, &matrices[matrix_vert] ); - #ifdef FT_LCD_FILTER_H if (pFT_Library_SetLcdFilter) pFT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT ); @@ -7612,11 +7623,23 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, return GDI_ERROR; } + switch (ft_face->glyph->format) + { + case FT_GLYPH_FORMAT_OUTLINE: + bbox = get_transformed_outline( &ft_face->glyph->outline, bbox, needsTransform, matrices ); + break; + case FT_GLYPH_FORMAT_BITMAP: + /* TODO: winfnt, embedded bitmap transform(scale, slant, ...). */ + break; + default: + FIXME( "loaded glyph format %x\n", ft_face->glyph->format ); + return GDI_ERROR; + } + switch (format) { case GGO_BITMAP: - needed = get_mono_glyph_bitmap( ft_face->glyph, bbox, font->fake_bold, - needsTransform, matrices, buflen, buf ); + needed = get_mono_glyph_bitmap( ft_face->glyph, bbox, font->fake_bold, buflen, buf ); break; case GGO_GRAY2_BITMAP: @@ -7624,7 +7647,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, case GGO_GRAY8_BITMAP: case WINE_GGO_GRAY16_BITMAP: needed = get_antialias_glyph_bitmap( ft_face->glyph, bbox, format, font->fake_bold, - needsTransform, matrices, buflen, buf ); + buflen, buf ); break; case WINE_GGO_HRGB_BITMAP: @@ -7632,7 +7655,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, case WINE_GGO_VRGB_BITMAP: case WINE_GGO_VBGR_BITMAP: needed = get_subpixel_glyph_bitmap( ft_face->glyph, &bbox, format, font->fake_bold, - needsTransform, matrices, buflen, buf ); + buflen, buf ); break; case GGO_NATIVE: @@ -7640,10 +7663,6 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, FT_Outline *outline = &ft_face->glyph->outline; if(buflen == 0) buf = NULL; - - if (needsTransform && buf) - pFT_Outline_Transform( outline, &matrices[matrix_vert] ); - needed = get_native_glyph_outline(outline, buflen, NULL); if (!buf || !buflen) @@ -7658,10 +7677,6 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, { FT_Outline *outline = &ft_face->glyph->outline; if(buflen == 0) buf = NULL; - - if (needsTransform && buf) - pFT_Outline_Transform( outline, &matrices[matrix_vert] ); - needed = get_bezier_glyph_outline(outline, buflen, NULL); if (!buf || !buflen) -- 2.20.1