Akihiro Sagawa : gdi32: Synthesize bold glyphs for outline fonts.
Alexandre Julliard
julliard at winehq.org
Mon Oct 21 14:58:26 CDT 2013
Module: wine
Branch: master
Commit: 99ceb599bb055abb461680bf7a7ae295fe724ec2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=99ceb599bb055abb461680bf7a7ae295fe724ec2
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Thu Oct 17 21:25:10 2013 +0900
gdi32: Synthesize bold glyphs for outline fonts.
---
dlls/gdi32/freetype.c | 49 +++++++++++++++++++++++++++++++++++++++++++++-
dlls/gdi32/tests/font.c | 2 +-
2 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 45723d3..fb4f2af 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -175,6 +175,7 @@ MAKE_FUNCPTR(FT_MulFix);
MAKE_FUNCPTR(FT_New_Face);
MAKE_FUNCPTR(FT_New_Memory_Face);
MAKE_FUNCPTR(FT_Outline_Get_Bitmap);
+MAKE_FUNCPTR(FT_Outline_Get_CBox);
MAKE_FUNCPTR(FT_Outline_Transform);
MAKE_FUNCPTR(FT_Outline_Translate);
MAKE_FUNCPTR(FT_Render_Glyph);
@@ -183,6 +184,7 @@ MAKE_FUNCPTR(FT_Set_Charmap);
MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
MAKE_FUNCPTR(FT_Vector_Transform);
MAKE_FUNCPTR(FT_Vector_Unit);
+static FT_Error (*pFT_Outline_Embolden)(FT_Outline *, FT_Pos);
static FT_TrueTypeEngineType (*pFT_Get_TrueType_Engine_Type)(FT_Library);
#ifdef HAVE_FREETYPE_FTLCDFIL_H
static FT_Error (*pFT_Library_SetLcdFilter)(FT_Library, FT_LcdFilter);
@@ -3903,6 +3905,7 @@ static BOOL init_freetype(void)
LOAD_FUNCPTR(FT_New_Face)
LOAD_FUNCPTR(FT_New_Memory_Face)
LOAD_FUNCPTR(FT_Outline_Get_Bitmap)
+ LOAD_FUNCPTR(FT_Outline_Get_CBox)
LOAD_FUNCPTR(FT_Outline_Transform)
LOAD_FUNCPTR(FT_Outline_Translate)
LOAD_FUNCPTR(FT_Render_Glyph)
@@ -3913,6 +3916,7 @@ static BOOL init_freetype(void)
LOAD_FUNCPTR(FT_Vector_Unit)
#undef LOAD_FUNCPTR
/* Don't warn if these ones are missing */
+ pFT_Outline_Embolden = wine_dlsym(ft_handle, "FT_Outline_Embolden", NULL, 0);
pFT_Get_TrueType_Engine_Type = wine_dlsym(ft_handle, "FT_Get_TrueType_Engine_Type", NULL, 0);
#ifdef HAVE_FREETYPE_FTLCDFIL_H
pFT_Library_SetLcdFilter = wine_dlsym(ft_handle, "FT_Library_SetLcdFilter", NULL, 0);
@@ -6106,6 +6110,44 @@ static inline BOOL is_identity_MAT2(const MAT2 *matrix)
return !memcmp(matrix, &identity, sizeof(MAT2));
}
+static void synthesize_bold_glyph(FT_GlyphSlot glyph, LONG ppem, FT_Glyph_Metrics *metrics)
+{
+ FT_Error err;
+ static UINT once;
+
+ switch(glyph->format) {
+ case FT_GLYPH_FORMAT_OUTLINE:
+ {
+ FT_Pos strength;
+ FT_BBox bbox;
+ if(!pFT_Outline_Embolden)
+ break;
+
+ strength = MulDiv(ppem, 1 << 6, 24);
+ err = pFT_Outline_Embolden(&glyph->outline, strength);
+ if(err) {
+ TRACE("FT_Ouline_Embolden returns %d, ignored\n", err);
+ break;
+ }
+
+ pFT_Outline_Get_CBox(&glyph->outline, &bbox);
+ metrics->width = bbox.xMax - bbox.xMin;
+ metrics->height = bbox.yMax - bbox.yMin;
+ metrics->horiBearingX = bbox.xMin;
+ metrics->horiBearingY = bbox.yMax;
+ metrics->horiAdvance += (1 << 6);
+ metrics->vertAdvance += (1 << 6);
+ metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
+ metrics->vertBearingY = (metrics->vertAdvance - metrics->height) / 2;
+ break;
+ }
+ default:
+ if (!once++)
+ WARN("Emboldening format 0x%x is not supported\n", glyph->format);
+ return;
+ }
+}
+
static inline BYTE get_max_level( UINT format )
{
switch( format )
@@ -6370,10 +6412,13 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
return GDI_ERROR;
}
+ metrics = ft_face->glyph->metrics;
+ if(font->fake_bold)
+ synthesize_bold_glyph(ft_face->glyph, font->ppem, &metrics);
+
/* Some poorly-created fonts contain glyphs that exceed the boundaries set
* by the text metrics. The proper behavior is to clip the glyph metrics to
* fit within the maximums specified in the text metrics. */
- metrics = ft_face->glyph->metrics;
if(incoming_font->potm || get_outline_text_metrics(incoming_font) ||
get_bitmap_text_metrics(incoming_font)) {
TEXTMETRICW *ptm = &incoming_font->potm->otmTextMetrics;
@@ -6388,7 +6433,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
em_scale = MulDiv(incoming_font->ppem, 1 << 16, incoming_font->ft_face->units_per_EM);
- if(FT_IS_SCALABLE(incoming_font->ft_face)) {
+ if(FT_IS_SCALABLE(incoming_font->ft_face) && !font->fake_bold) {
TEXTMETRICW tm;
if (get_text_metrics(incoming_font, &tm) &&
!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 17608ce..a629b10 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -5700,7 +5700,7 @@ static void test_fake_bold_font(void)
ok(tm[0].tmOverhang == tm[1].tmOverhang, "expected %d, got %d\n", tm[0].tmOverhang, tm[1].tmOverhang);
w[0] = abc[0].abcA + abc[0].abcB + abc[0].abcC;
w[1] = abc[1].abcA + abc[1].abcB + abc[1].abcC;
- todo_wine ok((w[0] + 1) == w[1], "expected %d, got %d\n", w[0] + 1, w[1]);
+ ok((w[0] + 1) == w[1], "expected %d, got %d\n", w[0] + 1, w[1]);
}
More information about the wine-cvs
mailing list