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

This commit is contained in:
Akihiro Sagawa 2013-10-04 00:56:17 +09:00 committed by Alexandre Julliard
parent b0ccc355c3
commit 88acc9c899
2 changed files with 33 additions and 25 deletions

View File

@ -6184,6 +6184,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
const MAT2* lpmat)
{
static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)};
GLYPHMETRICS gm;
FT_Face ft_face = incoming_font->ft_face;
GdiFont *font = incoming_font;
FT_Glyph_Metrics metrics;
@ -6419,8 +6420,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
top = (metrics.horiBearingY + 63) & -64;
bottom = (metrics.horiBearingY - metrics.height) & -64;
lpgm->gmCellIncX = adv;
lpgm->gmCellIncY = 0;
gm.gmCellIncX = adv;
gm.gmCellIncY = 0;
origin_x = left;
origin_y = top;
} else {
@ -6492,14 +6493,14 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
vec.x = metrics.horiAdvance;
vec.y = 0;
pFT_Vector_Transform(&vec, &transMat);
lpgm->gmCellIncY = -((vec.y+63) >> 6);
gm.gmCellIncY = -((vec.y+63) >> 6);
if (!avgAdvance || vec.y)
lpgm->gmCellIncX = (vec.x+63) >> 6;
gm.gmCellIncX = (vec.x+63) >> 6;
else {
vec.x = incoming_font->ntmAvgWidth;
vec.y = 0;
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)
@ -6520,28 +6521,29 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
width = (right - left) >> 6;
height = (top - bottom) >> 6;
lpgm->gmBlackBoxX = width ? width : 1;
lpgm->gmBlackBoxY = height ? height : 1;
lpgm->gmptGlyphOrigin.x = origin_x >> 6;
lpgm->gmptGlyphOrigin.y = origin_y >> 6;
gm.gmBlackBoxX = width ? width : 1;
gm.gmBlackBoxY = height ? height : 1;
gm.gmptGlyphOrigin.x = origin_x >> 6;
gm.gmptGlyphOrigin.y = origin_y >> 6;
abc->abcA = left >> 6;
abc->abcB = lpgm->gmBlackBoxX;
abc->abcB = gm.gmBlackBoxX;
abc->abcC = adv - abc->abcA - abc->abcB;
TRACE("%u,%u,%s,%d,%d\n", lpgm->gmBlackBoxX, lpgm->gmBlackBoxY,
wine_dbgstr_point(&lpgm->gmptGlyphOrigin),
lpgm->gmCellIncX, lpgm->gmCellIncY);
TRACE("%u,%u,%s,%d,%d\n", gm.gmBlackBoxX, gm.gmBlackBoxY,
wine_dbgstr_point(&gm.gmptGlyphOrigin),
gm.gmCellIncX, gm.gmCellIncY);
if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) &&
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)->init = TRUE;
}
if(format == GGO_METRICS)
{
*lpgm = gm;
return 1; /* FIXME */
}
@ -6626,7 +6628,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
src += ft_face->glyph->bitmap.pitch;
dst += pitch;
}
return needed;
break;
}
case ft_glyph_format_outline:
{
@ -6654,7 +6656,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
start += pitch;
}
}
return needed;
break;
}
default:
@ -6717,7 +6719,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
if (!width || !height)
{
if (!buf || !buflen) return 0;
if (!buf || !buflen) break;
return GDI_ERROR;
}
@ -6725,18 +6727,18 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
{
if ( render_mode == FT_RENDER_MODE_LCD)
{
lpgm->gmBlackBoxX += 2;
lpgm->gmptGlyphOrigin.x -= 1;
gm.gmBlackBoxX += 2;
gm.gmptGlyphOrigin.x -= 1;
}
else
{
lpgm->gmBlackBoxY += 2;
lpgm->gmptGlyphOrigin.y += 1;
gm.gmBlackBoxY += 2;
gm.gmptGlyphOrigin.y += 1;
}
}
width = lpgm->gmBlackBoxX;
height = lpgm->gmBlackBoxY;
width = gm.gmBlackBoxX;
height = gm.gmBlackBoxY;
pitch = width * 4;
needed = pitch * height;
@ -6771,7 +6773,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
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 )
{
src += hmul * -x_shift;
@ -6783,7 +6785,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
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 )
{
src += src_pitch * vmul * -y_shift;
@ -7025,6 +7027,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
FIXME("Unsupported format %d\n", format);
return GDI_ERROR;
}
*lpgm = gm;
return needed;
}

View File

@ -4172,7 +4172,12 @@ static void test_GetGlyphOutline(void)
ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
}
else
{
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]);
}
}
}