summaryrefslogtreecommitdiffstats
path: root/src/sfnt/sfobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sfnt/sfobjs.c')
-rw-r--r--src/sfnt/sfobjs.c278
1 files changed, 146 insertions, 132 deletions
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index c25b87d..c826b92 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -123,14 +123,20 @@
/* */
/* nameid :: The name id of the name record to return. */
/* */
+ /* <InOut> */
+ /* name :: The address of a string pointer. NULL if no name is */
+ /* present. */
+ /* */
/* <Return> */
- /* Character string. NULL if no name is present. */
+ /* FreeType error code. 0 means success. */
/* */
- static FT_String*
- tt_face_get_name( TT_Face face,
- FT_UShort nameid )
+ static FT_Error
+ tt_face_get_name( TT_Face face,
+ FT_UShort nameid,
+ FT_String** name )
{
FT_Memory memory = face->root.memory;
+ FT_Error error = SFNT_Err_Ok;
FT_String* result = NULL;
FT_UShort n;
TT_NameEntryRec* rec;
@@ -145,6 +151,8 @@
TT_NameEntry_ConvertFunc convert;
+ FT_ASSERT( name );
+
rec = face->name_table.names;
for ( n = 0; n < face->num_names; n++, rec++ )
{
@@ -256,11 +264,8 @@
{
if ( rec->string == NULL )
{
- FT_Error error = SFNT_Err_Ok;
FT_Stream stream = face->name_table.stream;
- FT_UNUSED( error );
-
if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||
FT_STREAM_SEEK( rec->stringOffset ) ||
@@ -277,7 +282,8 @@
}
Exit:
- return result;
+ *name = result;
+ return error;
}
@@ -363,11 +369,12 @@
if ( FT_READ_ULONG( tag ) )
return error;
- if ( tag != 0x00010000UL &&
- tag != TTAG_ttcf &&
- tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) &&
- tag != TTAG_true &&
- tag != 0x00020000UL )
+ if ( tag != 0x00010000UL &&
+ tag != TTAG_ttcf &&
+ tag != TTAG_OTTO &&
+ tag != TTAG_true &&
+ tag != TTAG_typ1 &&
+ tag != 0x00020000UL )
return SFNT_Err_Unknown_File_Format;
face->ttc_header.tag = TTAG_ttcf;
@@ -401,7 +408,7 @@
face->ttc_header.version = 1 << 16;
face->ttc_header.count = 1;
- if ( FT_NEW( face->ttc_header.offsets) )
+ if ( FT_NEW( face->ttc_header.offsets ) )
return error;
face->ttc_header.offsets[0] = offset;
@@ -451,7 +458,7 @@
face_index = 0;
if ( face_index >= face->ttc_header.count )
- return SFNT_Err_Bad_Argument;
+ return SFNT_Err_Invalid_Argument;
if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
return error;
@@ -461,7 +468,8 @@
if ( error )
return error;
- face->root.num_faces = face->ttc_header.count;
+ face->root.num_faces = face->ttc_header.count;
+ face->root.face_index = face_index;
return error;
}
@@ -498,6 +506,13 @@
FT_TRACE3(( "\n" )); \
} while ( 0 )
+#define GET_NAME( id, field ) \
+ do { \
+ error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \
+ if ( error ) \
+ goto Exit; \
+ } while ( 0 )
+
FT_LOCAL_DEF( FT_Error )
sfnt_load_face( FT_Stream stream,
@@ -506,7 +521,10 @@
FT_Int num_params,
FT_Parameter* params )
{
- FT_Error error, psnames_error;
+ FT_Error error;
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+ FT_Error psnames_error;
+#endif
FT_Bool has_outline;
FT_Bool is_apple_sbit;
@@ -581,7 +599,10 @@
/* don't check for errors */
LOAD_( name );
LOAD_( post );
+
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
psnames_error = error;
+#endif
/* do not load the metrics headers and tables if this is an Apple */
/* sbit font file */
@@ -660,19 +681,20 @@
face->os2.version = 0xFFFFU;
}
-
}
/* the optional tables */
- /* embedded bitmap support. */
+ /* embedded bitmap support */
if ( sfnt->load_eblc )
{
LOAD_( eblc );
if ( error )
{
- /* return an error if this font file has no outlines */
- if ( error == SFNT_Err_Table_Missing && has_outline )
+ /* a font which contains neither bitmaps nor outlines is */
+ /* still valid (although rather useless in most cases); */
+ /* however, you can find such stripped fonts in PDFs */
+ if ( error == SFNT_Err_Table_Missing )
error = SFNT_Err_Ok;
else
goto Exit;
@@ -692,59 +714,38 @@
LOAD_( gasp );
LOAD_( kern );
- error = SFNT_Err_Ok;
-
face->root.num_glyphs = face->max_profile.numGlyphs;
-#if 0
/* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */
/* a WWS-only font face. `WWS' stands for `weight', width', and */
/* `slope', a term used by Microsoft's Windows Presentation */
- /* Foundation (WPF). This flag will be introduced in version */
- /* 1.5 of the OpenType specification (but is already in use). */
+ /* Foundation (WPF). This flag has been introduced in version */
+ /* 1.5 of the OpenType specification (May 2008). */
if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
-#endif
{
- face->root.family_name =
- tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY );
+ GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
if ( !face->root.family_name )
- face->root.family_name =
- tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY );
+ GET_NAME( FONT_FAMILY, &face->root.family_name );
- face->root.style_name =
- tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY );
+ GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
if ( !face->root.style_name )
- face->root.style_name =
- tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY );
+ GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
}
-#if 0
else
{
- /* Support for `name' table ID 21 (WWS family) and 22 (WWS */
- /* subfamily) is still under consideration by Microsoft and */
- /* not implemented in the current version of WPF. */
-
- face->root.family_name =
- tt_face_get_name( face, TT_NAME_ID_WWS_FAMILY );
+ GET_NAME( WWS_FAMILY, &face->root.family_name );
if ( !face->root.family_name )
- face->root.family_name =
- tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY );
+ GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
if ( !face->root.family_name )
- face->root.family_name =
- tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY );
+ GET_NAME( FONT_FAMILY, &face->root.family_name );
- face->root.style_name =
- tt_face_get_name( face, TT_NAME_ID_WWS_SUBFAMILY );
+ GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
if ( !face->root.style_name )
- face->root.style_name =
- tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY );
+ GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
if ( !face->root.style_name )
- face->root.style_name =
- tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY );
+ GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
}
-#endif
-
/* now set up root fields */
{
@@ -801,10 +802,9 @@
flags = 0;
if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
{
- /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */
- /* indicates an oblique font face. This flag will be */
- /* introduced in version 1.5 of the OpenType specification (but */
- /* is already in use). */
+ /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */
+ /* indicates an oblique font face. This flag has been */
+ /* introduced in version 1.5 of the OpenType specification. */
if ( face->os2.fsSelection & 512 ) /* bit 9 */
flags |= FT_STYLE_FLAG_ITALIC;
@@ -817,6 +817,7 @@
else
{
/* this is an old Mac font, use the header field */
+
if ( face->header.Mac_Style & 1 )
flags |= FT_STYLE_FLAG_BOLD;
@@ -861,12 +862,78 @@
}
}
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+ /*
+ * Now allocate the root array of FT_Bitmap_Size records and
+ * populate them. Unfortunately, it isn't possible to indicate bit
+ * depths in the FT_Bitmap_Size record. This is a design error.
+ */
+ {
+ FT_UInt i, count;
+
+
+#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
+ count = face->sbit_num_strikes;
+#else
+ count = (FT_UInt)face->num_sbit_strikes;
+#endif
+
+ if ( count > 0 )
+ {
+ FT_Memory memory = face->root.stream->memory;
+ FT_UShort em_size = face->header.Units_Per_EM;
+ FT_Short avgwidth = face->os2.xAvgCharWidth;
+ FT_Size_Metrics metrics;
+
+
+ if ( em_size == 0 || face->os2.version == 0xFFFFU )
+ {
+ avgwidth = 0;
+ em_size = 1;
+ }
+
+ if ( FT_NEW_ARRAY( root->available_sizes, count ) )
+ goto Exit;
+
+ for ( i = 0; i < count; i++ )
+ {
+ FT_Bitmap_Size* bsize = root->available_sizes + i;
+
+
+ error = sfnt->load_strike_metrics( face, i, &metrics );
+ if ( error )
+ goto Exit;
+
+ bsize->height = (FT_Short)( metrics.height >> 6 );
+ bsize->width = (FT_Short)(
+ ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
+
+ bsize->x_ppem = metrics.x_ppem << 6;
+ bsize->y_ppem = metrics.y_ppem << 6;
+
+ /* assume 72dpi */
+ bsize->size = metrics.y_ppem << 6;
+ }
+
+ root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
+ root->num_fixed_sizes = (FT_Int)count;
+ }
+ }
+
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+
+ /* a font with no bitmaps and no outlines is scalable; */
+ /* it has only empty glyphs then */
+ if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
+ root->face_flags |= FT_FACE_FLAG_SCALABLE;
+
/*********************************************************************/
/* */
/* Set up metrics. */
/* */
- if ( has_outline == TRUE )
+ if ( FT_IS_SCALABLE( root ) )
{
/* XXX What about if outline header is missing */
/* (e.g. sfnt wrapped bitmap)? */
@@ -919,10 +986,9 @@
/* this computation is based on various versions of Times New Roman */
if ( face->horizontal.Line_Gap == 0 )
root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 );
-#endif
+#endif /* 0 */
#if 0
-
/* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */
/* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */
if ( face->os2.version != 0xFFFFU && root->ascender )
@@ -937,80 +1003,21 @@
if ( height > root->height )
root->height = height;
}
-
#endif /* 0 */
- root->max_advance_width = face->horizontal.advance_Width_Max;
+ root->max_advance_width = face->horizontal.advance_Width_Max;
+ root->max_advance_height = (FT_Short)( face->vertical_info
+ ? face->vertical.advance_Height_Max
+ : root->height );
- root->max_advance_height = (FT_Short)( face->vertical_info
- ? face->vertical.advance_Height_Max
- : root->height );
-
- root->underline_position = face->postscript.underlinePosition;
+ /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */
+ /* Adjust underline position from top edge to centre of */
+ /* stroke to convert TrueType meaning to FreeType meaning. */
+ root->underline_position = face->postscript.underlinePosition -
+ face->postscript.underlineThickness / 2;
root->underline_thickness = face->postscript.underlineThickness;
}
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
- /*
- * Now allocate the root array of FT_Bitmap_Size records and
- * populate them. Unfortunately, it isn't possible to indicate bit
- * depths in the FT_Bitmap_Size record. This is a design error.
- */
- {
- FT_UInt i, count;
-
-
-#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
- count = face->sbit_num_strikes;
-#else
- count = (FT_UInt)face->num_sbit_strikes;
-#endif
-
- if ( count > 0 )
- {
- FT_Memory memory = face->root.stream->memory;
- FT_UShort em_size = face->header.Units_Per_EM;
- FT_Short avgwidth = face->os2.xAvgCharWidth;
- FT_Size_Metrics metrics;
-
-
- if ( em_size == 0 || face->os2.version == 0xFFFFU )
- {
- avgwidth = 0;
- em_size = 1;
- }
-
- if ( FT_NEW_ARRAY( root->available_sizes, count ) )
- goto Exit;
-
- for ( i = 0; i < count; i++ )
- {
- FT_Bitmap_Size* bsize = root->available_sizes + i;
-
-
- error = sfnt->load_strike_metrics( face, i, &metrics );
- if ( error )
- goto Exit;
-
- bsize->height = (FT_Short)( metrics.height >> 6 );
- bsize->width = (FT_Short)(
- ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
-
- bsize->x_ppem = metrics.x_ppem << 6;
- bsize->y_ppem = metrics.y_ppem << 6;
-
- /* assume 72dpi */
- bsize->size = metrics.y_ppem << 6;
- }
-
- root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
- root->num_fixed_sizes = (FT_Int)count;
- }
- }
-
-#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
-
}
Exit:
@@ -1022,14 +1029,21 @@
#undef LOAD_
#undef LOADM_
+#undef GET_NAME
FT_LOCAL_DEF( void )
sfnt_done_face( TT_Face face )
{
- FT_Memory memory = face->root.memory;
- SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+ FT_Memory memory;
+ SFNT_Service sfnt;
+
+
+ if ( !face )
+ return;
+ memory = face->root.memory;
+ sfnt = (SFNT_Service)face->sfnt;
if ( sfnt )
{
@@ -1068,7 +1082,7 @@
}
/* freeing the horizontal metrics */
-#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
+#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
{
FT_Stream stream = FT_FACE_STREAM( face );