Module: wine Branch: master Commit: 0acfe68864db9caa8d018c44f08040def7b09532 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0acfe68864db9caa8d018c44f0...
Author: Dmitry Timoshkov dmitry@codeweavers.com Date: Sun Jan 20 21:21:45 2008 +0800
gdi32: Actually perform the fractional scaling test, make it pass under Wine.
---
dlls/gdi32/freetype.c | 67 +++++++++++++++++++++++++--------------------- dlls/gdi32/tests/font.c | 27 +++++++++++++----- 2 files changed, 55 insertions(+), 39 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 3e21a45..4b54699 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -324,7 +324,7 @@ struct tagGdiFont { struct list hfontlist; FONT_DESC font_desc; LONG aveWidth, ppem; - float scale_x, scale_y; + float scale_y; SHORT yMax; SHORT yMin; 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) WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err); } else { + font->ppem = height; if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0) 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), 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);
if(!face->scalable) { - ret->ppem = face->size.height; - if (height != 0) ret->ppem += diff; + /* Windows uses integer scaling factors for bitmap fonts */ + 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; 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);
if (!ret->ft_face) @@ -3312,6 +3324,7 @@ static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf, height = face->size.y_ppem >> 6; width = face->size.x_ppem >> 6; } + font->scale_y = 1.0;
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; FT_Angle angle = 0; 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; BOOL needsTransform = FALSE;
@@ -3661,11 +3674,13 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, } /* Scaling factor */ - if (font->scale_x != 0.0) + if (font->aveWidth && font->potm) { - widthRatio = font->scale_x; - heightRatio = font->scale_y; + widthRatio = (float)font->aveWidth * font->font_desc.matrix.eM11; + widthRatio /= (float)font->potm->otmTextMetrics.tmAveCharWidth; } + else + widthRatio = font->scale_y;
left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -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.xy = 0; scaleMat.yx = 0; - scaleMat.yy = FT_FixedFromFloat(heightRatio); + scaleMat.yy = FT_FixedFromFloat(font->scale_y);
pFT_Matrix_Multiply(&scaleMat, &transMat); needsTransform = TRUE; @@ -4161,34 +4176,24 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
static void scale_font_metrics(GdiFont *font, LPTEXTMETRICW ptm) { - if (font->scale_x == 0.0) - { - if (FT_IS_SCALABLE(font->ft_face) || !font->ppem) - font->scale_y = 1.0; - 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; + float scale_x;
- TRACE("font scale x: %f y: %f\n", font->scale_x, font->scale_y); + if (font->aveWidth) + { + scale_x = (float)font->aveWidth * font->font_desc.matrix.eM11; + scale_x /= (float)font->potm->otmTextMetrics.tmAveCharWidth; } + else + scale_x = font->scale_y; + ptm->tmHeight = (float)ptm->tmHeight * font->scale_y; ptm->tmAscent = (float)ptm->tmAscent * font->scale_y; ptm->tmDescent = (float)ptm->tmDescent * font->scale_y; ptm->tmInternalLeading = (float)ptm->tmInternalLeading * font->scale_y; ptm->tmExternalLeading = (float)ptm->tmExternalLeading * font->scale_y;
- ptm->tmAveCharWidth = (float)ptm->tmAveCharWidth * font->scale_x; - ptm->tmMaxCharWidth = (float)ptm->tmMaxCharWidth * font->scale_x; + ptm->tmAveCharWidth = (float)ptm->tmAveCharWidth * scale_x; + ptm->tmMaxCharWidth = (float)ptm->tmMaxCharWidth * scale_x; }
/************************************************************* diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index ee577c6..08725de 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -156,7 +156,7 @@ static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DW 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, const SIZE *size_orig, INT width_of_A_orig, 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; TEXTMETRICA tm; SIZE size; - INT width_of_A; + INT width_of_A, cx, cy;
if (!hfont) return; @@ -176,13 +176,17 @@ static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str,
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.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.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(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) 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; TEXTMETRICA tm_orig; SIZE size_orig; - INT ret, i, width_orig, height_orig; + INT ret, i, width_orig, height_orig, scale;
hdc = GetDC(0);
@@ -233,10 +237,17 @@ static void test_bitmap_font(void) DeleteObject(hfont);
/* 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); - 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); }
@@ -244,14 +255,14 @@ static void test_bitmap_font(void) bitmap_lf.lfHeight = height_orig * 2; bitmap_lf.lfWidth *= 3; 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);
/* test integer scaling 3x3 */ bitmap_lf.lfHeight = height_orig * 3; bitmap_lf.lfWidth = 0; 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);
ReleaseDC(0, hdc);