[PATCH 06/12] gdi32: Fix the problem that GGO_METRICS ignores the aa_flags of the DC.
Byeongsik Jeon
bsjeon at hanmail.net
Tue Jan 29 03:12:30 CST 2019
Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
If we look at the behavior of GGO_METRICS, the setting of lfQuality is applied.
GGO_METIRCS is zero. So it's impossible to do 'GGO_METRICS | GGO_BITMAP',
'GGO_METRICS | GGO_GRAY4_BITMAP', etc.
dlls/gdi32/freetype.c | 45 +++++++++++++++++++++++++++--------------
dlls/gdi32/tests/font.c | 1 +
include/wingdi.h | 2 ++
3 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 292a39909e..0759a68412 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -7546,7 +7546,8 @@ static FT_Int get_load_flags( UINT format, GdiFont *font )
natural_width = font->font_desc.lf.lfQuality == CLEARTYPE_NATURAL_QUALITY;
- switch (format & ~GGO_GLYPH_INDEX)
+ format &= ~(GGO_GLYPH_INDEX | WINE_GGO_METRICS);
+ switch (format)
{
case WINE_GGO_HRGB_BITMAP:
case WINE_GGO_HBGR_BITMAP:
@@ -7584,6 +7585,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
BOOL needsTransform = FALSE;
BOOL tategaki = (font->name[0] == '@');
BOOL vertical_metrics;
+ BOOL ggo_metrics = format & WINE_GGO_METRICS;
TRACE("%p, %04x, %08x, %p, %08x, %p, %p\n", font, glyph, format, lpgm,
buflen, buf, lpmat);
@@ -7612,9 +7614,9 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
tategaki = check_unicode_tategaki(glyph);
}
- format &= ~GGO_UNHINTED;
+ format &= ~(WINE_GGO_METRICS | GGO_UNHINTED);
- if (format == GGO_METRICS && is_identity_MAT2(lpmat) &&
+ if (ggo_metrics && is_identity_MAT2(lpmat) &&
get_cached_gm_abc_metrics( font, glyph_index, lpgm, abc ))
return 1; /* FIXME */
@@ -7663,11 +7665,11 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
&transMat, &transMatTategaki, &transMatUnrotated,
&gm, abc );
- if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) &&
+ if ((ggo_metrics || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) &&
is_identity_MAT2(lpmat)) /* don't cache custom transforms */
cache_gm_abc_metrics( font, glyph_index, &gm, abc );
- if(format == GGO_METRICS)
+ if (ggo_metrics)
{
*lpgm = gm;
return 1; /* FIXME */
@@ -8230,7 +8232,11 @@ static DWORD freetype_GetGlyphOutline( PHYSDEV dev, UINT glyph, UINT format,
GDI_CheckNotLock();
EnterCriticalSection( &freetype_cs );
+
+ if (GGO_METRICS == (format & ~(GGO_UNHINTED | GGO_GLYPH_INDEX)))
+ format |= get_physdev_dc( dev )->aa_flags | WINE_GGO_METRICS;
ret = get_glyph_outline( physdev->font, glyph, format, lpgm, &abc, buflen, buf, lpmat );
+
LeaveCriticalSection( &freetype_cs );
return ret;
}
@@ -8386,7 +8392,7 @@ done:
static BOOL freetype_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar, LPINT buffer )
{
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
- UINT c;
+ UINT c, format;
GLYPHMETRICS gm;
ABC abc;
struct freetype_physdev *physdev = get_freetype_dev( dev );
@@ -8401,10 +8407,14 @@ static BOOL freetype_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar, L
GDI_CheckNotLock();
EnterCriticalSection( &freetype_cs );
- for(c = firstChar; c <= lastChar; c++) {
- get_glyph_outline( physdev->font, c, GGO_METRICS, &gm, &abc, 0, NULL, &identity );
+
+ format = get_physdev_dc( dev )->aa_flags | WINE_GGO_METRICS;
+ for (c = firstChar; c <= lastChar; c++)
+ {
+ get_glyph_outline( physdev->font, c, format, &gm, &abc, 0, NULL, &identity );
buffer[c - firstChar] = abc.abcA + abc.abcB + abc.abcC;
}
+
LeaveCriticalSection( &freetype_cs );
return TRUE;
}
@@ -8415,7 +8425,7 @@ static BOOL freetype_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar, L
static BOOL freetype_GetCharABCWidths( PHYSDEV dev, UINT firstChar, UINT lastChar, LPABC buffer )
{
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
- UINT c;
+ UINT c, format;
GLYPHMETRICS gm;
struct freetype_physdev *physdev = get_freetype_dev( dev );
@@ -8430,8 +8440,9 @@ static BOOL freetype_GetCharABCWidths( PHYSDEV dev, UINT firstChar, UINT lastCha
GDI_CheckNotLock();
EnterCriticalSection( &freetype_cs );
+ format = get_physdev_dc( dev )->aa_flags | WINE_GGO_METRICS;
for(c = firstChar; c <= lastChar; c++, buffer++)
- get_glyph_outline( physdev->font, c, GGO_METRICS, &gm, buffer, 0, NULL, &identity );
+ get_glyph_outline( physdev->font, c, format, &gm, buffer, 0, NULL, &identity );
LeaveCriticalSection( &freetype_cs );
return TRUE;
@@ -8443,7 +8454,7 @@ static BOOL freetype_GetCharABCWidths( PHYSDEV dev, UINT firstChar, UINT lastCha
static BOOL freetype_GetCharABCWidthsI( PHYSDEV dev, UINT firstChar, UINT count, LPWORD pgi, LPABC buffer )
{
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
- UINT c;
+ UINT c, format;
GLYPHMETRICS gm;
struct freetype_physdev *physdev = get_freetype_dev( dev );
@@ -8459,8 +8470,9 @@ static BOOL freetype_GetCharABCWidthsI( PHYSDEV dev, UINT firstChar, UINT count,
GDI_CheckNotLock();
EnterCriticalSection( &freetype_cs );
+ format = get_physdev_dc( dev )->aa_flags | WINE_GGO_METRICS | GGO_GLYPH_INDEX;
for(c = 0; c < count; c++, buffer++)
- get_glyph_outline( physdev->font, pgi ? pgi[c] : firstChar + c, GGO_METRICS | GGO_GLYPH_INDEX,
+ get_glyph_outline( physdev->font, pgi ? pgi[c] : firstChar + c, format,
&gm, buffer, 0, NULL, &identity );
LeaveCriticalSection( &freetype_cs );
@@ -8474,6 +8486,7 @@ static BOOL freetype_GetTextExtentExPoint( PHYSDEV dev, LPCWSTR wstr, INT count,
{
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
INT idx, pos;
+ UINT format;
ABC abc;
GLYPHMETRICS gm;
struct freetype_physdev *physdev = get_freetype_dev( dev );
@@ -8489,9 +8502,10 @@ static BOOL freetype_GetTextExtentExPoint( PHYSDEV dev, LPCWSTR wstr, INT count,
GDI_CheckNotLock();
EnterCriticalSection( &freetype_cs );
+ format = get_physdev_dc( dev )->aa_flags | WINE_GGO_METRICS;
for (idx = pos = 0; idx < count; idx++)
{
- get_glyph_outline( physdev->font, wstr[idx], GGO_METRICS, &gm, &abc, 0, NULL, &identity );
+ get_glyph_outline( physdev->font, wstr[idx], format, &gm, &abc, 0, NULL, &identity );
pos += abc.abcA + abc.abcB + abc.abcC;
dxs[idx] = pos;
}
@@ -8507,6 +8521,7 @@ static BOOL freetype_GetTextExtentExPointI( PHYSDEV dev, const WORD *indices, IN
{
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
INT idx, pos;
+ UINT format;
ABC abc;
GLYPHMETRICS gm;
struct freetype_physdev *physdev = get_freetype_dev( dev );
@@ -8522,10 +8537,10 @@ static BOOL freetype_GetTextExtentExPointI( PHYSDEV dev, const WORD *indices, IN
GDI_CheckNotLock();
EnterCriticalSection( &freetype_cs );
+ format = get_physdev_dc( dev )->aa_flags | WINE_GGO_METRICS | GGO_GLYPH_INDEX;
for (idx = pos = 0; idx < count; idx++)
{
- get_glyph_outline( physdev->font, indices[idx], GGO_METRICS | GGO_GLYPH_INDEX,
- &gm, &abc, 0, NULL, &identity );
+ get_glyph_outline( physdev->font, indices[idx], format, &gm, &abc, 0, NULL, &identity );
pos += abc.abcA + abc.abcB + abc.abcC;
dxs[idx] = pos;
}
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 67e8941b5e..6e7ac1e8e5 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -4839,6 +4839,7 @@ static void test_GetGlyphOutline(void)
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError());
trace("Tests with height=%d,avg=%d,full=%d,face=%s,charset=%d\n",
-lf.lfHeight, tm.tmAveCharWidth, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+ todo_wine
ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
"expected %d, got %d (%s:%d)\n",
tm.tmAveCharWidth * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
diff --git a/include/wingdi.h b/include/wingdi.h
index 1851654194..8a7453e92c 100644
--- a/include/wingdi.h
+++ b/include/wingdi.h
@@ -1337,6 +1337,8 @@ typedef struct
#define WINE_GGO_HBGR_BITMAP 0x12
#define WINE_GGO_VRGB_BITMAP 0x13
#define WINE_GGO_VBGR_BITMAP 0x14
+
+#define WINE_GGO_METRICS 0x40
#endif
typedef struct
--
2.20.1
More information about the wine-devel
mailing list