gdi32: Add support for scaling font metrics
Dmitry Timoshkov
dmitry at codeweavers.com
Tue Jan 8 09:02:09 CST 2008
Hello,
Changelog:
gdi32: Add support for scaling font metrics.
---
dlls/gdi32/freetype.c | 67 ++++++++++++++++++++++++++++++++++++++--------
dlls/gdi32/tests/font.c | 6 ----
2 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 4d51341..480b8e5 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -319,7 +319,8 @@ struct tagGdiFont {
DWORD gmsize;
struct list hfontlist;
FONT_DESC font_desc;
- LONG aveWidth;
+ LONG aveWidth, ppem;
+ float scale_x, scale_y;
SHORT yMax;
SHORT yMin;
OUTLINETEXTMETRICW *potm;
@@ -329,7 +330,6 @@ struct tagGdiFont {
FONTSIGNATURE fs;
GdiFont *base_font;
struct list child_fonts;
- LONG ppem;
};
typedef struct {
@@ -2439,7 +2439,6 @@ 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);
}
@@ -3126,6 +3125,12 @@ 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->ppem = height;
+ ret->aveWidth = abs(lf.lfWidth);
+
+ ret->scale_x = 0.0;
+ ret->scale_y = 0.0;
+
if(!face->scalable) {
width = face->size.x_ppem >> 6;
height = face->size.y_ppem >> 6;
@@ -3159,7 +3164,6 @@ found:
TRACE("caching: gdiFont=%p hfont=%p\n", ret, hfont);
- ret->aveWidth = FT_IS_SCALABLE(ret->ft_face) ? abs(lf.lfWidth) : 0;
list_add_head(&gdi_font_list, &ret->entry);
return ret;
}
@@ -3594,7 +3598,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;
+ float widthRatio = 1.0, heightRatio = 1.0;
FT_Matrix transMat = identityMat;
BOOL needsTransform = FALSE;
@@ -3624,7 +3628,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
if (!font->gm[glyph_index / GM_BLOCK_SIZE])
font->gm[glyph_index / GM_BLOCK_SIZE] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
- if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || font->aveWidth || lpmat)
+ if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || lpmat)
load_flags |= FT_LOAD_NO_BITMAP;
err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
@@ -3635,8 +3639,10 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
}
/* Scaling factor */
- if (font->aveWidth && font->potm) {
- widthRatio = (float)font->aveWidth * font->font_desc.matrix.eM11 / (float) font->potm->otmTextMetrics.tmAveCharWidth;
+ if (font->scale_x != 0.0)
+ {
+ widthRatio = font->scale_x;
+ heightRatio = font->scale_y;
}
left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
@@ -3652,7 +3658,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
scaleMat.xx = FT_FixedFromFloat(widthRatio);
scaleMat.xy = 0;
scaleMat.yx = 0;
- scaleMat.yy = (1 << 16);
+ scaleMat.yy = FT_FixedFromFloat(heightRatio);
pFT_Matrix_Multiply(&scaleMat, &transMat);
needsTransform = TRUE;
@@ -4130,6 +4136,39 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
return TRUE;
}
+
+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;
+
+ TRACE("font scale x: %f y: %f\n", font->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;
+}
+
/*************************************************************
* WineEngGetTextMetrics
*
@@ -4143,10 +4182,8 @@ BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
}
if(!font->potm) return FALSE;
memcpy(ptm, &font->potm->otmTextMetrics, sizeof(*ptm));
+ scale_font_metrics(font, ptm);
- if (font->aveWidth) {
- ptm->tmAveCharWidth = font->aveWidth * font->font_desc.matrix.eM11;
- }
return TRUE;
}
@@ -4176,7 +4213,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
if(font->potm) {
if(cbSize >= font->potm->otmSize)
+ {
memcpy(potm, font->potm, font->potm->otmSize);
+ scale_font_metrics(font, &potm->otmTextMetrics);
+ }
return font->potm->otmSize;
}
@@ -4404,7 +4444,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
ret = needed;
if(potm && needed <= cbSize)
+ {
memcpy(potm, font->potm, font->potm->otmSize);
+ scale_font_metrics(font, &potm->otmTextMetrics);
+ }
end:
HeapFree(GetProcessHeap(), 0, style_nameW);
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index b6e8327..7d73c19 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -244,20 +244,14 @@ static void test_bitmap_font(void)
bitmap_lf.lfHeight = height_orig * 2;
bitmap_lf.lfWidth *= 3;
hfont = create_font("3x2", &bitmap_lf);
-todo_wine
-{
test_font_metrics(hdc, hfont, 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);
-todo_wine
-{
test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
-}
DeleteObject(hfont);
ReleaseDC(0, hdc);
--
1.5.3.7
More information about the wine-patches
mailing list