[PATCH 3/6] gdi32: Add a helper function to get a more accurate transformed outline bbox.
Byeongsik Jeon
bsjeon at hanmail.net
Mon Feb 11 02:20:18 CST 2019
Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
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
More information about the wine-devel
mailing list