gdi32: Actually perform the fractional scaling test, make it pass under Wine.
This commit is contained in:
parent
5af6012fba
commit
0acfe68864
|
@ -324,7 +324,7 @@ struct tagGdiFont {
|
||||||
struct list hfontlist;
|
struct list hfontlist;
|
||||||
FONT_DESC font_desc;
|
FONT_DESC font_desc;
|
||||||
LONG aveWidth, ppem;
|
LONG aveWidth, ppem;
|
||||||
float scale_x, scale_y;
|
float scale_y;
|
||||||
SHORT yMax;
|
SHORT yMax;
|
||||||
SHORT yMin;
|
SHORT yMin;
|
||||||
OUTLINETEXTMETRICW *potm;
|
OUTLINETEXTMETRICW *potm;
|
||||||
|
@ -2471,6 +2471,7 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
|
||||||
if((err = pFT_Set_Pixel_Sizes(ft_face, 0, font->ppem)) != 0)
|
if((err = pFT_Set_Pixel_Sizes(ft_face, 0, font->ppem)) != 0)
|
||||||
WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err);
|
WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err);
|
||||||
} else {
|
} else {
|
||||||
|
font->ppem = height;
|
||||||
if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0)
|
if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0)
|
||||||
WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", width, height, err);
|
WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", width, height, err);
|
||||||
}
|
}
|
||||||
|
@ -3157,18 +3158,29 @@ found:
|
||||||
TRACE("Chosen: %s %s (%s/%p:%ld)\n", debugstr_w(family->FamilyName),
|
TRACE("Chosen: %s %s (%s/%p:%ld)\n", debugstr_w(family->FamilyName),
|
||||||
debugstr_w(face->StyleName), face->file, face->font_data_ptr, face->face_index);
|
debugstr_w(face->StyleName), face->file, face->font_data_ptr, face->face_index);
|
||||||
|
|
||||||
ret->scale_x = 0.0;
|
|
||||||
ret->scale_y = 0.0;
|
|
||||||
|
|
||||||
ret->aveWidth = abs(lf.lfWidth);
|
ret->aveWidth = abs(lf.lfWidth);
|
||||||
|
|
||||||
if(!face->scalable) {
|
if(!face->scalable) {
|
||||||
ret->ppem = face->size.height;
|
/* Windows uses integer scaling factors for bitmap fonts */
|
||||||
if (height != 0) ret->ppem += diff;
|
INT scale, scaled_height;
|
||||||
|
|
||||||
|
if (height != 0) height = diff;
|
||||||
|
else height = 0;
|
||||||
|
height += face->size.height;
|
||||||
|
|
||||||
|
scale = (height + face->size.height - 1) / face->size.height;
|
||||||
|
scaled_height = scale * face->size.height;
|
||||||
|
/* XP allows not more than 10% deviation */
|
||||||
|
if (scale > 1 && scaled_height - height > scaled_height / 10) scale--;
|
||||||
|
ret->scale_y = scale;
|
||||||
|
|
||||||
width = face->size.x_ppem >> 6;
|
width = face->size.x_ppem >> 6;
|
||||||
height = face->size.y_ppem >> 6;
|
height = face->size.y_ppem >> 6;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ret->scale_y = 1.0;
|
||||||
|
TRACE("font scale y: %f\n", ret->scale_y);
|
||||||
|
|
||||||
ret->ft_face = OpenFontFace(ret, face, width, height);
|
ret->ft_face = OpenFontFace(ret, face, width, height);
|
||||||
|
|
||||||
if (!ret->ft_face)
|
if (!ret->ft_face)
|
||||||
|
@ -3312,6 +3324,7 @@ static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
|
||||||
height = face->size.y_ppem >> 6;
|
height = face->size.y_ppem >> 6;
|
||||||
width = face->size.x_ppem >> 6;
|
width = face->size.x_ppem >> 6;
|
||||||
}
|
}
|
||||||
|
font->scale_y = 1.0;
|
||||||
|
|
||||||
if (!(font->ft_face = OpenFontFace(font, face, width, height)))
|
if (!(font->ft_face = OpenFontFace(font, face, width, height)))
|
||||||
{
|
{
|
||||||
|
@ -3620,7 +3633,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
||||||
INT left, right, top = 0, bottom = 0, adv, lsb, bbx;
|
INT left, right, top = 0, bottom = 0, adv, lsb, bbx;
|
||||||
FT_Angle angle = 0;
|
FT_Angle angle = 0;
|
||||||
FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
||||||
float widthRatio = 1.0, heightRatio = 1.0;
|
float widthRatio = 1.0;
|
||||||
FT_Matrix transMat = identityMat;
|
FT_Matrix transMat = identityMat;
|
||||||
BOOL needsTransform = FALSE;
|
BOOL needsTransform = FALSE;
|
||||||
|
|
||||||
|
@ -3661,11 +3674,13 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scaling factor */
|
/* Scaling factor */
|
||||||
if (font->scale_x != 0.0)
|
if (font->aveWidth && font->potm)
|
||||||
{
|
{
|
||||||
widthRatio = font->scale_x;
|
widthRatio = (float)font->aveWidth * font->font_desc.matrix.eM11;
|
||||||
heightRatio = font->scale_y;
|
widthRatio /= (float)font->potm->otmTextMetrics.tmAveCharWidth;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
widthRatio = font->scale_y;
|
||||||
|
|
||||||
left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
|
left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
|
||||||
right = (INT)((ft_face->glyph->metrics.horiBearingX + ft_face->glyph->metrics.width) * widthRatio + 63) & -64;
|
right = (INT)((ft_face->glyph->metrics.horiBearingX + ft_face->glyph->metrics.width) * widthRatio + 63) & -64;
|
||||||
|
@ -3680,7 +3695,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
||||||
scaleMat.xx = FT_FixedFromFloat(widthRatio);
|
scaleMat.xx = FT_FixedFromFloat(widthRatio);
|
||||||
scaleMat.xy = 0;
|
scaleMat.xy = 0;
|
||||||
scaleMat.yx = 0;
|
scaleMat.yx = 0;
|
||||||
scaleMat.yy = FT_FixedFromFloat(heightRatio);
|
scaleMat.yy = FT_FixedFromFloat(font->scale_y);
|
||||||
|
|
||||||
pFT_Matrix_Multiply(&scaleMat, &transMat);
|
pFT_Matrix_Multiply(&scaleMat, &transMat);
|
||||||
needsTransform = TRUE;
|
needsTransform = TRUE;
|
||||||
|
@ -4161,34 +4176,24 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
|
||||||
|
|
||||||
static void scale_font_metrics(GdiFont *font, LPTEXTMETRICW ptm)
|
static void scale_font_metrics(GdiFont *font, LPTEXTMETRICW ptm)
|
||||||
{
|
{
|
||||||
if (font->scale_x == 0.0)
|
float scale_x;
|
||||||
|
|
||||||
|
if (font->aveWidth)
|
||||||
{
|
{
|
||||||
if (FT_IS_SCALABLE(font->ft_face) || !font->ppem)
|
scale_x = (float)font->aveWidth * font->font_desc.matrix.eM11;
|
||||||
font->scale_y = 1.0;
|
scale_x /= (float)font->potm->otmTextMetrics.tmAveCharWidth;
|
||||||
else
|
|
||||||
{
|
|
||||||
font->scale_y = (float)font->ppem * font->font_desc.matrix.eM22;
|
|
||||||
font->scale_y /= (float)font->potm->otmTextMetrics.tmHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (font->aveWidth)
|
|
||||||
{
|
|
||||||
font->scale_x = (float)font->aveWidth * font->font_desc.matrix.eM11;
|
|
||||||
font->scale_x /= (float)font->potm->otmTextMetrics.tmAveCharWidth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
font->scale_x = font->scale_y;
|
|
||||||
|
|
||||||
TRACE("font scale x: %f y: %f\n", font->scale_x, font->scale_y);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
scale_x = font->scale_y;
|
||||||
|
|
||||||
ptm->tmHeight = (float)ptm->tmHeight * font->scale_y;
|
ptm->tmHeight = (float)ptm->tmHeight * font->scale_y;
|
||||||
ptm->tmAscent = (float)ptm->tmAscent * font->scale_y;
|
ptm->tmAscent = (float)ptm->tmAscent * font->scale_y;
|
||||||
ptm->tmDescent = (float)ptm->tmDescent * font->scale_y;
|
ptm->tmDescent = (float)ptm->tmDescent * font->scale_y;
|
||||||
ptm->tmInternalLeading = (float)ptm->tmInternalLeading * font->scale_y;
|
ptm->tmInternalLeading = (float)ptm->tmInternalLeading * font->scale_y;
|
||||||
ptm->tmExternalLeading = (float)ptm->tmExternalLeading * font->scale_y;
|
ptm->tmExternalLeading = (float)ptm->tmExternalLeading * font->scale_y;
|
||||||
|
|
||||||
ptm->tmAveCharWidth = (float)ptm->tmAveCharWidth * font->scale_x;
|
ptm->tmAveCharWidth = (float)ptm->tmAveCharWidth * scale_x;
|
||||||
ptm->tmMaxCharWidth = (float)ptm->tmMaxCharWidth * font->scale_x;
|
ptm->tmMaxCharWidth = (float)ptm->tmMaxCharWidth * scale_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
|
|
@ -156,7 +156,7 @@ static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DW
|
||||||
return 1; /* continue enumeration */
|
return 1; /* continue enumeration */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str,
|
static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight, const char *test_str,
|
||||||
INT test_str_len, const TEXTMETRICA *tm_orig,
|
INT test_str_len, const TEXTMETRICA *tm_orig,
|
||||||
const SIZE *size_orig, INT width_of_A_orig,
|
const SIZE *size_orig, INT width_of_A_orig,
|
||||||
INT scale_x, INT scale_y)
|
INT scale_x, INT scale_y)
|
||||||
|
@ -165,7 +165,7 @@ static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str,
|
||||||
LOGFONTA lf;
|
LOGFONTA lf;
|
||||||
TEXTMETRICA tm;
|
TEXTMETRICA tm;
|
||||||
SIZE size;
|
SIZE size;
|
||||||
INT width_of_A;
|
INT width_of_A, cx, cy;
|
||||||
|
|
||||||
if (!hfont)
|
if (!hfont)
|
||||||
return;
|
return;
|
||||||
|
@ -176,13 +176,17 @@ static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str,
|
||||||
|
|
||||||
GetTextMetricsA(hdc, &tm);
|
GetTextMetricsA(hdc, &tm);
|
||||||
|
|
||||||
|
cx = tm.tmAveCharWidth / tm_orig->tmAveCharWidth;
|
||||||
|
cy = tm.tmHeight / tm_orig->tmHeight;
|
||||||
|
ok(cx == scale_x && cy == scale_y, "expected scale_x %d, scale_y %d, got cx %d, cy %d\n",
|
||||||
|
scale_x, scale_y, cx, cy);
|
||||||
ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%d != %d\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
|
ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%d != %d\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
|
||||||
ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%d != %d\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
|
ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%d != %d\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
|
||||||
ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%d != %d\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
|
ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%d != %d\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
|
||||||
ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
|
ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
|
||||||
ok(tm.tmMaxCharWidth == tm_orig->tmMaxCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmMaxCharWidth * scale_x);
|
ok(tm.tmMaxCharWidth == tm_orig->tmMaxCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmMaxCharWidth * scale_x);
|
||||||
|
|
||||||
ok(lf.lfHeight == tm.tmHeight, "lf %d != tm %d\n", lf.lfHeight, tm.tmHeight);
|
ok(lf.lfHeight == lfHeight, "lf %d != %d\n", lf.lfHeight, lfHeight);
|
||||||
if (lf.lfWidth)
|
if (lf.lfWidth)
|
||||||
ok(lf.lfWidth == tm.tmAveCharWidth, "lf %d != tm %d\n", lf.lfWidth, tm.tmAveCharWidth);
|
ok(lf.lfWidth == tm.tmAveCharWidth, "lf %d != tm %d\n", lf.lfWidth, tm.tmAveCharWidth);
|
||||||
|
|
||||||
|
@ -207,7 +211,7 @@ static void test_bitmap_font(void)
|
||||||
HFONT hfont, old_hfont;
|
HFONT hfont, old_hfont;
|
||||||
TEXTMETRICA tm_orig;
|
TEXTMETRICA tm_orig;
|
||||||
SIZE size_orig;
|
SIZE size_orig;
|
||||||
INT ret, i, width_orig, height_orig;
|
INT ret, i, width_orig, height_orig, scale;
|
||||||
|
|
||||||
hdc = GetDC(0);
|
hdc = GetDC(0);
|
||||||
|
|
||||||
|
@ -233,10 +237,17 @@ static void test_bitmap_font(void)
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
|
|
||||||
/* test fractional scaling */
|
/* test fractional scaling */
|
||||||
for (i = 1; i < height_orig; i++)
|
for (i = 1; i <= height_orig * 3; i++)
|
||||||
{
|
{
|
||||||
|
INT nearest_height;
|
||||||
|
|
||||||
|
bitmap_lf.lfHeight = i;
|
||||||
hfont = create_font("fractional", &bitmap_lf);
|
hfont = create_font("fractional", &bitmap_lf);
|
||||||
test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1);
|
scale = (i + height_orig - 1) / height_orig;
|
||||||
|
nearest_height = scale * height_orig;
|
||||||
|
/* XP allows not more than 10% deviation */
|
||||||
|
if (scale > 1 && nearest_height - i > nearest_height / 10) scale--;
|
||||||
|
test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, scale);
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,14 +255,14 @@ static void test_bitmap_font(void)
|
||||||
bitmap_lf.lfHeight = height_orig * 2;
|
bitmap_lf.lfHeight = height_orig * 2;
|
||||||
bitmap_lf.lfWidth *= 3;
|
bitmap_lf.lfWidth *= 3;
|
||||||
hfont = create_font("3x2", &bitmap_lf);
|
hfont = create_font("3x2", &bitmap_lf);
|
||||||
test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2);
|
test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2);
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
|
|
||||||
/* test integer scaling 3x3 */
|
/* test integer scaling 3x3 */
|
||||||
bitmap_lf.lfHeight = height_orig * 3;
|
bitmap_lf.lfHeight = height_orig * 3;
|
||||||
bitmap_lf.lfWidth = 0;
|
bitmap_lf.lfWidth = 0;
|
||||||
hfont = create_font("3x3", &bitmap_lf);
|
hfont = create_font("3x3", &bitmap_lf);
|
||||||
test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
|
test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
|
|
||||||
ReleaseDC(0, hdc);
|
ReleaseDC(0, hdc);
|
||||||
|
|
Loading…
Reference in New Issue