Commit 88acc9c8 authored by Akihiro Sagawa's avatar Akihiro Sagawa Committed by Alexandre Julliard

gdi32: Don't modify output glyph metrics unless the function succeeds.

parent b0ccc355
...@@ -6184,6 +6184,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6184,6 +6184,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
const MAT2* lpmat) const MAT2* lpmat)
{ {
static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)}; static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)};
GLYPHMETRICS gm;
FT_Face ft_face = incoming_font->ft_face; FT_Face ft_face = incoming_font->ft_face;
GdiFont *font = incoming_font; GdiFont *font = incoming_font;
FT_Glyph_Metrics metrics; FT_Glyph_Metrics metrics;
...@@ -6419,8 +6420,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6419,8 +6420,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
top = (metrics.horiBearingY + 63) & -64; top = (metrics.horiBearingY + 63) & -64;
bottom = (metrics.horiBearingY - metrics.height) & -64; bottom = (metrics.horiBearingY - metrics.height) & -64;
lpgm->gmCellIncX = adv; gm.gmCellIncX = adv;
lpgm->gmCellIncY = 0; gm.gmCellIncY = 0;
origin_x = left; origin_x = left;
origin_y = top; origin_y = top;
} else { } else {
...@@ -6492,14 +6493,14 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6492,14 +6493,14 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
vec.x = metrics.horiAdvance; vec.x = metrics.horiAdvance;
vec.y = 0; vec.y = 0;
pFT_Vector_Transform(&vec, &transMat); pFT_Vector_Transform(&vec, &transMat);
lpgm->gmCellIncY = -((vec.y+63) >> 6); gm.gmCellIncY = -((vec.y+63) >> 6);
if (!avgAdvance || vec.y) if (!avgAdvance || vec.y)
lpgm->gmCellIncX = (vec.x+63) >> 6; gm.gmCellIncX = (vec.x+63) >> 6;
else { else {
vec.x = incoming_font->ntmAvgWidth; vec.x = incoming_font->ntmAvgWidth;
vec.y = 0; vec.y = 0;
pFT_Vector_Transform(&vec, &transMat); pFT_Vector_Transform(&vec, &transMat);
lpgm->gmCellIncX = pFT_MulFix(vec.x, em_scale) * 2; gm.gmCellIncX = pFT_MulFix(vec.x, em_scale) * 2;
} }
if (vertical_metrics) if (vertical_metrics)
...@@ -6520,28 +6521,29 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6520,28 +6521,29 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
width = (right - left) >> 6; width = (right - left) >> 6;
height = (top - bottom) >> 6; height = (top - bottom) >> 6;
lpgm->gmBlackBoxX = width ? width : 1; gm.gmBlackBoxX = width ? width : 1;
lpgm->gmBlackBoxY = height ? height : 1; gm.gmBlackBoxY = height ? height : 1;
lpgm->gmptGlyphOrigin.x = origin_x >> 6; gm.gmptGlyphOrigin.x = origin_x >> 6;
lpgm->gmptGlyphOrigin.y = origin_y >> 6; gm.gmptGlyphOrigin.y = origin_y >> 6;
abc->abcA = left >> 6; abc->abcA = left >> 6;
abc->abcB = lpgm->gmBlackBoxX; abc->abcB = gm.gmBlackBoxX;
abc->abcC = adv - abc->abcA - abc->abcB; abc->abcC = adv - abc->abcA - abc->abcB;
TRACE("%u,%u,%s,%d,%d\n", lpgm->gmBlackBoxX, lpgm->gmBlackBoxY, TRACE("%u,%u,%s,%d,%d\n", gm.gmBlackBoxX, gm.gmBlackBoxY,
wine_dbgstr_point(&lpgm->gmptGlyphOrigin), wine_dbgstr_point(&gm.gmptGlyphOrigin),
lpgm->gmCellIncX, lpgm->gmCellIncY); gm.gmCellIncX, gm.gmCellIncY);
if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) && if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) &&
is_identity_MAT2(lpmat)) /* don't cache custom transforms */ is_identity_MAT2(lpmat)) /* don't cache custom transforms */
{ {
FONT_GM(font,original_index)->gm = *lpgm; FONT_GM(font,original_index)->gm = gm;
FONT_GM(font,original_index)->abc = *abc; FONT_GM(font,original_index)->abc = *abc;
FONT_GM(font,original_index)->init = TRUE; FONT_GM(font,original_index)->init = TRUE;
} }
if(format == GGO_METRICS) if(format == GGO_METRICS)
{ {
*lpgm = gm;
return 1; /* FIXME */ return 1; /* FIXME */
} }
...@@ -6626,7 +6628,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6626,7 +6628,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
src += ft_face->glyph->bitmap.pitch; src += ft_face->glyph->bitmap.pitch;
dst += pitch; dst += pitch;
} }
return needed; break;
} }
case ft_glyph_format_outline: case ft_glyph_format_outline:
{ {
...@@ -6654,7 +6656,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6654,7 +6656,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
start += pitch; start += pitch;
} }
} }
return needed; break;
} }
default: default:
...@@ -6717,7 +6719,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6717,7 +6719,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
if (!width || !height) if (!width || !height)
{ {
if (!buf || !buflen) return 0; if (!buf || !buflen) break;
return GDI_ERROR; return GDI_ERROR;
} }
...@@ -6725,18 +6727,18 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6725,18 +6727,18 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
{ {
if ( render_mode == FT_RENDER_MODE_LCD) if ( render_mode == FT_RENDER_MODE_LCD)
{ {
lpgm->gmBlackBoxX += 2; gm.gmBlackBoxX += 2;
lpgm->gmptGlyphOrigin.x -= 1; gm.gmptGlyphOrigin.x -= 1;
} }
else else
{ {
lpgm->gmBlackBoxY += 2; gm.gmBlackBoxY += 2;
lpgm->gmptGlyphOrigin.y += 1; gm.gmptGlyphOrigin.y += 1;
} }
} }
width = lpgm->gmBlackBoxX; width = gm.gmBlackBoxX;
height = lpgm->gmBlackBoxY; height = gm.gmBlackBoxY;
pitch = width * 4; pitch = width * 4;
needed = pitch * height; needed = pitch * height;
...@@ -6771,7 +6773,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6771,7 +6773,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
vmul = 3; vmul = 3;
} }
x_shift = ft_face->glyph->bitmap_left - lpgm->gmptGlyphOrigin.x; x_shift = ft_face->glyph->bitmap_left - gm.gmptGlyphOrigin.x;
if ( x_shift < 0 ) if ( x_shift < 0 )
{ {
src += hmul * -x_shift; src += hmul * -x_shift;
...@@ -6783,7 +6785,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -6783,7 +6785,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
width -= x_shift; width -= x_shift;
} }
y_shift = lpgm->gmptGlyphOrigin.y - ft_face->glyph->bitmap_top; y_shift = gm.gmptGlyphOrigin.y - ft_face->glyph->bitmap_top;
if ( y_shift < 0 ) if ( y_shift < 0 )
{ {
src += src_pitch * vmul * -y_shift; src += src_pitch * vmul * -y_shift;
...@@ -7025,6 +7027,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, ...@@ -7025,6 +7027,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
FIXME("Unsupported format %d\n", format); FIXME("Unsupported format %d\n", format);
return GDI_ERROR; return GDI_ERROR;
} }
*lpgm = gm;
return needed; return needed;
} }
......
...@@ -4172,7 +4172,12 @@ static void test_GetGlyphOutline(void) ...@@ -4172,7 +4172,12 @@ static void test_GetGlyphOutline(void)
ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY); ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
} }
else else
{
ok(ret == GDI_ERROR, "%2d:GetGlyphOutlineW should return GDI_ERROR, got %d\n", fmt[i], ret); ok(ret == GDI_ERROR, "%2d:GetGlyphOutlineW should return GDI_ERROR, got %d\n", fmt[i], ret);
memset(&gm2, 0xab, sizeof(gm2));
ok(memcmp(&gm, &gm2, sizeof(GLYPHMETRICS)) == 0,
"%2d:GLYPHMETRICS shouldn't be touched on error\n", fmt[i]);
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment