Add embedded bitmap support to CFF driver.
* src/cff/cffobjs.h (CFF_SizeRec): New structure.
* src/cff/cffgload.c (cff_builder_init): Updated.
(cff_slot_load): Updated.
[TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: Load sbit.
* src/cff/cffobjs.c (sbit_size_reset)
[TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: New function.
(cff_size_get_globals_funcs, cff_size_done, cff_size_init): Updated.
(cff_size_reset): Updated.
[TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: Call sbit_size_reset.
* src/cff/cffdrivr.c (Load_Glyph): Updated.
(cff_driver_class): Use CFF_SizeRec.
* docs/CHANGES: Updated.
diff --git a/ChangeLog b/ChangeLog
index 7f1539d..d373cca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,31 @@
+2004-03-02 Werner Lemberg <wl@gnu.org>
+
+ Add embedded bitmap support to CFF driver.
+
+ * src/cff/cffobjs.h (CFF_SizeRec): New structure.
+
+ * src/cff/cffgload.c (cff_builder_init): Updated.
+ (cff_slot_load): Updated.
+ [TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: Load sbit.
+
+ * src/cff/cffobjs.c (sbit_size_reset)
+ [TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: New function.
+ (cff_size_get_globals_funcs, cff_size_done, cff_size_init): Updated.
+ (cff_size_reset): Updated.
+ [TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: Call sbit_size_reset.
+
+ * src/cff/cffdrivr.c (Load_Glyph): Updated.
+ (cff_driver_class): Use CFF_SizeRec.
+
+ * docs/CHANGES: Updated.
+
2004-03-01 Werner Lemberg <wl@gnu.org>
* src/pshinter/pshglob.c (psh_globals_scale_widths): Don't use
FT_RoundFix but FT_PIX_ROUND.
(psh_blues_snap_stem): Don't use blue_shift but blue_threshold.
- *src/pshinter/pshalgo.c (PSH_STRONG_THRESHOLD_MAXIMUM): New macro.
+ * src/pshinter/pshalgo.c (PSH_STRONG_THRESHOLD_MAXIMUM): New macro.
(psh_glyph_find_string_points): Use PSH_STRONG_THRESHOLD_MAXIMUM.
(psh_glyph_find_blue_points): New function. Needed for fonts like
p052003l.pfb (URW Palladio L Roman) which have flex curves at the
diff --git a/docs/CHANGES b/docs/CHANGES
index 7c53264..4420df0 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -16,6 +16,8 @@
correctly treated as a CID, similar to FreeType's CID driver
module. Note that CID CMap support is still missing.
+ - Embedded bitmaps in SFNT-based CFF fonts are now supported.
+
- The FT_FACE_FLAGS_GLYPH_NAMES is now set correctly for all font
formats.
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index 0c2e44e..82e04d2 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -200,7 +200,7 @@
if ( new_count != count && new_count < count / 2 )
{
(void)FT_RENEW_ARRAY( cmap->pairs, count, new_count );
- error = 0;
+ error = CFF_Err_Ok;
}
/* sort the pairs table to allow efficient binary searches */
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 75c072b..60ee90a 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -201,7 +201,7 @@
if ( size )
{
/* these two object must have the same parent */
- if ( size->face != slot->root.face )
+ if ( size->root.face != slot->root.face )
return CFF_Err_Invalid_Face_Handle;
}
@@ -453,7 +453,7 @@
/* now the specific driver fields */
sizeof( TT_FaceRec ),
- sizeof( FT_SizeRec ),
+ sizeof( CFF_SizeRec ),
sizeof( CFF_GlyphSlotRec ),
(FT_Face_InitFunc) cff_face_init,
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index f8d6110..c5bf79e 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -251,15 +251,15 @@
if ( hinting && size )
{
- builder->hints_globals = size->internal;
+ builder->hints_globals = size->root.internal;
builder->hints_funcs = glyph->root.internal->glyph_hints;
}
}
if ( size )
{
- builder->scale_x = size->metrics.x_scale;
- builder->scale_y = size->metrics.y_scale;
+ builder->scale_x = size->root.metrics.x_scale;
+ builder->scale_y = size->root.metrics.y_scale;
}
builder->pos_x = 0;
@@ -485,7 +485,7 @@
FT_Pos x,
FT_Pos y )
{
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
/* test whether we are building a new contour */
@@ -2219,7 +2219,7 @@
cff_compute_max_advance( TT_Face face,
FT_Int* max_advance )
{
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
CFF_Decoder decoder;
FT_Int glyph_index;
CFF_Font cff = (CFF_Font)face->other;
@@ -2255,7 +2255,7 @@
}
/* ignore the error if one has occurred -- skip to next glyph */
- error = 0;
+ error = CFF_Err_Ok;
}
*max_advance = decoder.builder.advance.x;
@@ -2289,14 +2289,19 @@
FT_Int glyph_index,
FT_Int32 load_flags )
{
- FT_Error error;
- CFF_Decoder decoder;
- TT_Face face = (TT_Face)glyph->root.face;
- FT_Bool hinting;
- CFF_Font cff = (CFF_Font)face->extra.data;
+ FT_Error error;
+ CFF_Decoder decoder;
+ TT_Face face = (TT_Face)glyph->root.face;
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+ CFF_Face cff_face = (CFF_Face)size->root.face;
+ SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt;
+ FT_Stream stream = cff_face->root.stream;
+#endif
+ FT_Bool hinting;
+ CFF_Font cff = (CFF_Font)face->extra.data;
- FT_Matrix font_matrix;
- FT_Vector font_offset;
+ FT_Matrix font_matrix;
+ FT_Vector font_offset;
if ( load_flags & FT_LOAD_NO_RECURSE )
@@ -2306,10 +2311,70 @@
glyph->y_scale = 0x10000L;
if ( size )
{
- glyph->x_scale = size->metrics.x_scale;
- glyph->y_scale = size->metrics.y_scale;
+ glyph->x_scale = size->root.metrics.x_scale;
+ glyph->y_scale = size->root.metrics.y_scale;
}
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+ /* try to load embedded bitmap if any */
+ /* */
+ /* XXX: The convention should be emphasized in */
+ /* the documents because it can be confusing. */
+ if ( size &&
+ size->strike_index != 0xFFFFU &&
+ sfnt->load_sbits &&
+ ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
+ {
+ TT_SBit_MetricsRec metrics;
+
+
+ error = sfnt->load_sbit_image( face,
+ (FT_ULong)size->strike_index,
+ (FT_UInt)glyph_index,
+ (FT_Int)load_flags,
+ stream,
+ &glyph->root.bitmap,
+ &metrics );
+
+ if ( !error )
+ {
+ glyph->root.outline.n_points = 0;
+ glyph->root.outline.n_contours = 0;
+
+ glyph->root.metrics.width = (FT_Pos)metrics.width << 6;
+ glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
+
+ glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
+ glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
+ glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
+
+ glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
+ glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
+ glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
+
+ glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
+
+ if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
+ {
+ glyph->root.bitmap_left = metrics.vertBearingX;
+ glyph->root.bitmap_top = metrics.vertBearingY;
+ }
+ else
+ {
+ glyph->root.bitmap_left = metrics.horiBearingX;
+ glyph->root.bitmap_top = metrics.horiBearingY;
+ }
+ return error;
+ }
+ }
+
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+
+ /* return immediately if we only want the embedded bitmaps */
+ if ( load_flags & FT_LOAD_SBITS_ONLY )
+ return CFF_Err_Invalid_Argument;
+
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
@@ -2444,7 +2509,7 @@
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
glyph->root.outline.flags = 0;
- if ( size && size->metrics.y_ppem < 24 )
+ if ( size && size->root.metrics.y_ppem < 24 )
glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index bbec294..44f3254 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1177,7 +1177,7 @@
cff_index_get_pointers( CFF_Index idx,
FT_Byte*** table )
{
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
FT_Memory memory = idx->stream->memory;
FT_ULong n, offset, old_offset;
FT_Byte** t;
@@ -1516,7 +1516,7 @@
FT_Bool invert )
{
FT_Memory memory = stream->memory;
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
FT_UShort glyph_sid;
@@ -1722,7 +1722,7 @@
FT_ULong base_offset,
FT_ULong offset )
{
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
FT_UInt count;
FT_UInt j;
FT_UShort glyph_sid;
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 6abb84b..5e9e70a 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003 by */
+/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -52,16 +52,81 @@
/*************************************************************************/
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+ static FT_Error
+ sbit_size_reset( CFF_Size size )
+ {
+ CFF_Face face;
+ FT_Error error = CFF_Err_Ok;
+
+ FT_ULong strike_index;
+ FT_Size_Metrics* metrics;
+ FT_Size_Metrics* sbit_metrics;
+ SFNT_Service sfnt;
+
+
+ metrics = &size->root.metrics;
+
+ face = (CFF_Face)size->root.face;
+ sfnt = (SFNT_Service)face->sfnt;
+
+ sbit_metrics = &size->strike_metrics;
+
+ error = sfnt->set_sbit_strike( face,
+ metrics->x_ppem, metrics->y_ppem,
+ &strike_index );
+
+ if ( !error )
+ {
+ TT_SBit_Strike strike = face->sbit_strikes + strike_index;
+
+
+ sbit_metrics->x_ppem = metrics->x_ppem;
+ sbit_metrics->y_ppem = metrics->y_ppem;
+
+ sbit_metrics->ascender = strike->hori.ascender << 6;
+ sbit_metrics->descender = strike->hori.descender << 6;
+
+ /* XXX: Is this correct? */
+ sbit_metrics->height = sbit_metrics->ascender -
+ sbit_metrics->descender;
+
+ /* XXX: Is this correct? */
+ sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
+ strike->hori.max_width +
+ strike->hori.min_advance_SB ) << 6;
+
+ size->strike_index = (FT_UInt)strike_index;
+ }
+ else
+ {
+ size->strike_index = 0xFFFFU;
+
+ sbit_metrics->x_ppem = 0;
+ sbit_metrics->y_ppem = 0;
+ sbit_metrics->ascender = 0;
+ sbit_metrics->descender = 0;
+ sbit_metrics->height = 0;
+ sbit_metrics->max_advance = 0;
+ }
+
+ return error;
+ }
+
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+
+
static PSH_Globals_Funcs
cff_size_get_globals_funcs( CFF_Size size )
{
- CFF_Face face = (CFF_Face)size->face;
+ CFF_Face face = (CFF_Face)size->root.face;
CFF_Font font = (CFF_FontRec *)face->extra.data;
PSHinter_Service pshinter = (PSHinter_Service)font->pshinter;
FT_Module module;
- module = FT_Get_Module( size->face->driver->root.library,
+ module = FT_Get_Module( size->root.face->driver->root.library,
"pshinter" );
return ( module && pshinter && pshinter->get_globals_funcs )
? pshinter->get_globals_funcs( module )
@@ -72,16 +137,16 @@
FT_LOCAL_DEF( void )
cff_size_done( CFF_Size size )
{
- if ( size->internal )
+ if ( size->root.internal )
{
PSH_Globals_Funcs funcs;
funcs = cff_size_get_globals_funcs( size );
if ( funcs )
- funcs->destroy( (PSH_Globals)size->internal );
+ funcs->destroy( (PSH_Globals)size->root.internal );
- size->internal = 0;
+ size->root.internal = 0;
}
}
@@ -89,14 +154,14 @@
FT_LOCAL_DEF( FT_Error )
cff_size_init( CFF_Size size )
{
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size );
if ( funcs )
{
PSH_Globals globals;
- CFF_Face face = (CFF_Face)size->face;
+ CFF_Face face = (CFF_Face)size->root.face;
CFF_Font font = (CFF_FontRec *)face->extra.data;
CFF_SubFont subfont = &font->top_font;
@@ -150,9 +215,9 @@
priv.lenIV = cpriv->lenIV;
}
- error = funcs->create( size->face->memory, &priv, &globals );
+ error = funcs->create( size->root.face->memory, &priv, &globals );
if ( !error )
- size->internal = (FT_Size_Internal)(void*)globals;
+ size->root.internal = (FT_Size_Internal)(void*)globals;
}
return error;
@@ -163,15 +228,32 @@
cff_size_reset( CFF_Size size )
{
PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size );
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
+ FT_Face face = size->root.face;
if ( funcs )
- error = funcs->set_scale( (PSH_Globals)size->internal,
- size->metrics.x_scale,
- size->metrics.y_scale,
+ error = funcs->set_scale( (PSH_Globals)size->root.internal,
+ size->root.metrics.x_scale,
+ size->root.metrics.y_scale,
0, 0 );
- return error;
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+ if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+ {
+ error = sbit_size_reset( size );
+
+ if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
+ size->root.metrics = size->strike_metrics;
+ }
+
+#endif
+
+ if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
+ return CFF_Err_Ok;
+ else
+ return error;
}
diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
index 49d5665..f02a5d7 100644
--- a/src/cff/cffobjs.h
+++ b/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003 by */
+/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -51,7 +51,18 @@
/* <Description> */
/* A handle to an OpenType size object. */
/* */
- typedef FT_Size CFF_Size;
+ typedef struct CFF_SizeRec_
+ {
+ FT_SizeRec root;
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+ FT_UInt strike_index; /* 0xFFFF to indicate invalid */
+ FT_Size_Metrics strike_metrics; /* current strike's metrics */
+
+#endif
+
+ } CFF_SizeRec, *CFF_Size;
/*************************************************************************/