Hi all,
Attached is a patch to add support to create synthetic bold variants of a font
when using FreeType fonts. It uses FreeType's built in emboldening function but
I've added the ability to specify the boldening factor (the default is 1).
Set DFFA_STYLE_SYNTH_BOLD when loading the font and use DFDESC_EMBOLDEN if you
have set the embolden_factor member of the DFBFontDescription struct. The
embolden_factor is a 16.16 fixed point integer, so you can use the
DFB_EMBOLDEN_FACTOR macro to set it:
DFBFontDescription font_dsc;
font_dsc.flags |= DFDESC_EMBOLDEN;
font_dsc.attributes |= DFFA_STYLE_SYNTH_BOLD;
font_dsc.embolden_factor = DFB_EMBOLDEN_FACTOR(0.65);
Let me know if there are issues/problems/concerns.
Pedro Navarro
From fc1ed787a4a89bdf720f809da565c34a02da629b Mon Sep 17 00:00:00 2001
From: Pedro Navarro <pnava...@netflix.com>
Date: Thu, 7 Jul 2011 18:09:26 -0700
Subject: [PATCH] Support for synthetic bold generation for FreeType fonts
---
include/directfb.h | 9 +++
interfaces/IDirectFBFont/idirectfbfont_ft2.c | 99 ++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 0 deletions(-)
diff --git a/include/directfb.h b/include/directfb.h
index ab94b10..e8f7ca3 100644
--- a/include/directfb.h
+++ b/include/directfb.h
@@ -1116,6 +1116,7 @@ typedef enum {
DFFA_STYLE_ITALIC = 0x00000200, /* load italic style */
DFFA_VERTICAL_LAYOUT = 0x00000400, /* load vertical layout */
DFFA_STYLE_BOLD = 0x00000800, /* load bold style */
+ DFFA_STYLE_SYNTH_BOLD = 0x00001000 /* generate bold style */
} DFBFontAttributes;
/*
@@ -1134,6 +1135,7 @@ typedef enum {
DFDESC_OUTLINE_WIDTH = 0x00000080, /* outline width is set */
DFDESC_OUTLINE_OPACITY = 0x00000100, /* outline opacity is set */
DFDESC_ROTATION = 0x00000200, /* rotation is set */
+ DFDESC_EMBOLDEN = 0x00000400 /* embolden factor is set */
} DFBFontDescriptionFlags;
/*
@@ -1157,6 +1159,10 @@ typedef enum {
*
* The rotation value is a 0.24 fixed point number of rotations. Use the macros DFB_DEGREES
* and DFB_RADIANS to convert from those units.
+ *
+ * The emboldening factor is a 0.24 fixed point number used as a multiplier to add or remove strength to
+ * the autogenerated bold variant. Use the DFB_EMBODLEN_FACTOR macro to convert a regular number to this format.
+ * The default value of 1.0 will be used unless DFDESC_EMBOLDEN is set (see DFBFontAttributes).
*/
typedef struct {
DFBFontDescriptionFlags flags;
@@ -1174,10 +1180,13 @@ typedef struct {
int outline_opacity; /* Outline opacity as 16.16 fixed point integer */
int rotation;
+
+ int embolden_factor; /* Emboldening factor as 16.16 fixed point integer */
} DFBFontDescription;
#define DFB_DEGREES(deg) ((int)((deg)/360.0*(1<<24)))
#define DFB_RADIANS(rad) ((int)((rad)/(2.0*M_PI)*(1<<24)))
+#define DFB_EMBOLDEN_FACTOR(factor) ((int)(factor*(1<<24)))
/*
* @internal
diff --git a/interfaces/IDirectFBFont/idirectfbfont_ft2.c b/interfaces/IDirectFBFont/idirectfbfont_ft2.c
index 3aacc35..f0ba68d 100644
--- a/interfaces/IDirectFBFont/idirectfbfont_ft2.c
+++ b/interfaces/IDirectFBFont/idirectfbfont_ft2.c
@@ -56,6 +56,9 @@
#undef SIZEOF_LONG
#include <ft2build.h>
+#include <freetype/ftsynth.h>
+#include <freetype/ftbitmap.h>
+#include <freetype/ftoutln.h>
#include FT_GLYPH_H
#ifndef FT_LOAD_TARGET_MONO
@@ -108,6 +111,8 @@ typedef struct {
int disable_charmap;
int fixed_advance;
bool fixed_clip;
+ bool embolden;
+ int embolden_factor;
unsigned int indices[256];
} FT2ImplData;
@@ -250,6 +255,83 @@ static const CoreFontEncodingFuncs ft2Latin1Funcs = {
/**********************************************************************************************************************/
+static void ft2EmboldenGlyph(FT_GlyphSlot slot, float factor)
+{
+ // This code has been copied from ftsynth.c, following the recommendation in ftsynth.h. Multiplication by an user
+ // defined factor has been added.
+
+ FT_Library library = slot->library;
+ FT_Face face = slot->face;
+ FT_Error error;
+ FT_Pos xstr, ystr;
+
+ if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
+ slot->format != FT_GLYPH_FORMAT_BITMAP )
+ return;
+
+ /* some reasonable strength */
+ xstr = FT_MulFix( face->units_per_EM * factor,
+ face->size->metrics.y_scale ) / 24;
+ ystr = xstr;
+
+ if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) {
+ /* ignore error */
+ (void)FT_Outline_Embolden( &slot->outline, xstr );
+
+ /* this is more than enough for most glyphs; if you need accurate */
+ /* values, you have to call FT_Outline_Get_CBox */
+ xstr = xstr * 2;
+ ystr = xstr;
+ }
+ else if ( 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.
+ * unfortunately, this function return no informations
+ * about the cause of error.
+ */
+ if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
+ {
+ //FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));
+ //FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr ));
+ return;
+ }
+ error = FT_GlyphSlot_Own_Bitmap( slot );
+ if ( error )
+ return;
+
+ error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
+ if ( error )
+ return;
+ }
+
+ 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.horiBearingY += ystr;
+ slot->metrics.horiAdvance += xstr;
+ slot->metrics.vertBearingX -= xstr / 2;
+ slot->metrics.vertBearingY += ystr;
+ slot->metrics.vertAdvance += 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 );
+}
+
+/**********************************************************************************************************************/
+
static DFBResult
render_glyph( CoreFont *thiz,
unsigned int index,
@@ -277,6 +359,9 @@ render_glyph( CoreFont *thiz,
return DFB_FAILURE;
}
+ if (data->embolden)
+ ft2EmboldenGlyph(face->glyph, (float)data->embolden_factor/(1<<24));
+
pthread_mutex_unlock ( &library_mutex );
err = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
@@ -585,6 +670,9 @@ get_glyph_info( CoreFont *thiz,
return DFB_FAILURE;
}
+
+ if (data->embolden)
+ ft2EmboldenGlyph(face->glyph, (float)data->embolden_factor/(1<<24));
}
pthread_mutex_unlock ( &library_mutex );
@@ -807,6 +895,7 @@ Construct( IDirectFBFont *thiz,
bool disable_charmap = false;
bool disable_kerning = false;
bool load_mono = false;
+ bool enable_embolden = false;
u32 mask = 0;
const char *filename = ctx->filename; /* intended for printf only */
@@ -901,6 +990,8 @@ Construct( IDirectFBFont *thiz,
disable_kerning = true;
if (desc->attributes & DFFA_MONOCHROME)
load_mono = true;
+ if (desc->attributes & DFFA_STYLE_SYNTH_BOLD)
+ enable_embolden = true;
}
if (load_mono)
@@ -1029,6 +1120,14 @@ Construct( IDirectFBFont *thiz,
data->face = face;
data->disable_charmap = disable_charmap;
+ data->embolden = enable_embolden;
+ desc->flags & DFDESC_EMBOLDEN ? data->embolden_factor = desc->embolden_factor : 1;
+
+ D_DEBUG( "DirectFB/FontFT2: emboldening: %d, factor: %d\n",
+ (desc->flags & DFDESC_EMBOLDEN) ? 1 : 0,
+ (desc->flags & DFDESC_EMBOLDEN) ? (float)data->embolden_factor/(1<<24) : 1 );
+
+
if (FT_HAS_KERNING(face) && !disable_kerning)
init_kerning_cache( (FT2ImplKerningData*) data, font->up_unit_x, font->up_unit_y);
--
1.7.1
_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev