[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft-devel] [PATCH 2/2] Improve FT_GlyphSlot_Embolden to match more with
From: |
Byeongsik Jeon |
Subject: |
[ft-devel] [PATCH 2/2] Improve FT_GlyphSlot_Embolden to match more with Microsoft Windows looks. |
Date: |
Fri, 5 Oct 2018 03:45:59 +0900 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0 |
---
src/base/ftsynth.c | 92 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 70 insertions(+), 22 deletions(-)
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index ec7b93510..7d599c118 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -22,6 +22,7 @@
#include FT_INTERNAL_OBJECTS_H
#include FT_OUTLINE_H
#include FT_BITMAP_H
+#include FT_TRUETYPE_TABLES_H
/**************************************************************************
@@ -92,7 +93,7 @@
FT_Library library;
FT_Face face;
FT_Error error;
- FT_Pos xstr, ystr;
+ FT_Pos xstr, ystr, ppem;
if ( !slot )
@@ -105,22 +106,68 @@
slot->format != FT_GLYPH_FORMAT_BITMAP )
return;
- /* some reasonable strength */
- xstr = FT_MulFix( face->units_per_EM,
- face->size->metrics.y_scale ) / 24;
- ystr = xstr;
+ /* the value that matches the MS Windows embolden looks.
+ the larger strength value, the more unintended artifacts increase.
+ using the integer pixel strength inhibits the blurred outlines.
+ */
+ ppem = face->size->metrics.y_ppem;
+ ystr = (( ppem - 1 ) / 50 ) << 6;
+ xstr = ystr + 64;
+
+ /* match to the MS.
+ the important factor that reduces the text layout difference. */
+ slot->metrics.horiAdvance += 1 << 6;
+ slot->linearHoriAdvance += 1 << 16;
if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
- FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
+ {
+ error = FT_Outline_EmboldenXY( &slot->outline, xstr, ystr);
+ if ( error )
+ return;
+#if 1
+ /* MS Windows DirectWrite looks. */
+
+ slot->metrics.width += xstr;
+ slot->metrics.height += ystr;
+ slot->metrics.horiBearingY += ystr;
+#else
+ /* MS Windows GDI looks. */
+ if ( ystr != 0 ) /* ppem > 50px */
+ {
+ TT_Header *head_table;
+ FT_Matrix scale = { 1 << 16, 0, 0, 1 << 16 };
+
+ /* Elboldened EM square box only increase the width of one pixel.
+ ( ppem, ppem ) -> embolden -> scale -> ( ppem + 1px, ppem )
+
+ ( ppem + xstr ) * scale.xx = ppem + 1px
+ ( ppem + ystr ) * scale.yy = ppem
+ */
+ ppem = ppem << 6;
+ scale.xx = FT_MulDiv( 1 << 16, ppem + 64, ppem + xstr );
+ scale.yy = FT_MulDiv( 1 << 16, ppem , ppem + ystr );
+ FT_Outline_Transform( &slot->outline, &scale );
+
+ /* Undocumented behavior in truetype spec. */
+ head_table = FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
+ if ( head_table && head_table->Flags & ( 1 << 4 | 1 << 2 ) )
+ slot->metrics.horiAdvance =
+ FT_MulFix( slot->metrics.horiAdvance, scale.xx );
+ }
+
+ {
+ FT_BBox bbox;
+ FT_Outline_Get_CBox( &slot->outline, &bbox );
+ slot->metrics.width = bbox.xMax - bbox.xMin;
+ slot->metrics.height = bbox.yMax - bbox.yMin;
+ slot->metrics.horiBearingX = bbox.xMin;
+ slot->metrics.horiBearingY = bbox.yMax;
+ }
+#endif
+ }
else /* slot->format == FT_GLYPH_FORMAT_BITMAP */
{
- /* round to full pixels */
- xstr &= ~63;
- if ( xstr == 0 )
- xstr = 1 << 6;
- ystr &= ~63;
-
/*
* XXX: overflow check for 16-bit system, for compatibility
* with FT_GlyphSlot_Embolden() since FreeType 2.1.10.
@@ -140,23 +187,24 @@
error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
if ( error )
return;
+
+ slot->metrics.width += xstr;
+ slot->metrics.height += ystr;
+ slot->metrics.horiBearingY += ystr;
+
+ /* XXX: 16-bit overflow case must be excluded before here */
+ slot->bitmap_top += (FT_Int)( ystr >> 6 );
}
+ /* XXX: FT_Set_Transform, FT_GlyphSlot_Embolden combination can
+ produce different results from intention. Recommend the
+ FT_Outline_Transform and a manual metrics modification.
+ */
if ( slot->advance.x )
slot->advance.x += xstr;
if ( slot->advance.y )
slot->advance.y += ystr;
-
- slot->metrics.width += xstr;
- slot->metrics.height += ystr;
- slot->metrics.horiAdvance += xstr;
- slot->metrics.vertAdvance += ystr;
- slot->metrics.horiBearingY += ystr;
-
- /* XXX: 16-bit overflow case must be excluded before here */
- if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
- slot->bitmap_top += (FT_Int)( ystr >> 6 );
}
-- 2.19.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [ft-devel] [PATCH 2/2] Improve FT_GlyphSlot_Embolden to match more with Microsoft Windows looks.,
Byeongsik Jeon <=