diff --git a/ChangeLog b/ChangeLog index 061475f63..f7f715bef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2008-03-31 Werner Lemberg + + Fix support for subsetted CID-keyed CFFs. + + * include/freetype/freetype.h (FT_FACE_FLAG_CID_KEYED, + FT_IS_CID_KEYED): New macros. + + * src/cff/cffobjs.c (cff_face_init): Set number of glyphs to the + maximum CID value in CID-keyed CFFs. + Handle FT_FACE_FLAG_CID_KEYED flag. + + * docs/CHANGES: Document it. + + + Fix CFF font matrix calculation and improve precision. + + * src/cff/cffparse.c (cff_parse_real): Increase precision if integer + part is zero. + (cff_parse_font_matrix): Simplify computation of `units_per_em'; + this prevents overflow also. + + + Support FT_Get_CID_Registry_Ordering_Supplement for PS CID fonts. + + * src/cid/cidriver.c: Include FT_SERVICE_CID_H. + (cid_get_ros): New function. + (cid_service_cid_info): New service structure. + (cid_services): Register it. + 2008-03-23 Werner Lemberg Adjustments for Visual C++ 8.0, as reported by Rainer Deyke. diff --git a/docs/CHANGES b/docs/CHANGES index 2158cf492..c11802fe3 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -12,6 +12,8 @@ CHANGES BETWEEN 2.3.6 and 2.3.5 - Improved Mac support. + - Subsetted CID-keyed CFFs are now supported correctly. + II. IMPORTANT CHANGES @@ -26,6 +28,10 @@ CHANGES BETWEEN 2.3.6 and 2.3.5 - An API for cmap 14 support (for Unicode Variant Selectors, UVS) has been contributed by George Williams. + - A new face flag FT_FACE_FLAG_CID_KEYED has been added, together + with a macro FT_IS_CID_KEYED which evaluates to 1 if the font is + CID-keyed. + III. MISCELLANEOUS diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index fcafdc347..a81f34a00 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -1021,6 +1021,15 @@ FT_BEGIN_HEADER /* the SFNT `gasp' table only if the native TrueType hinting engine */ /* (with the bytecode interpreter) is available and active. */ /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) @@ -1033,6 +1042,7 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) #define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) #define FT_FACE_FLAG_HINTER ( 1L << 11 ) +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) /* */ @@ -1189,6 +1199,24 @@ FT_BEGIN_HEADER ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + /*************************************************************************/ /* */ /* */ @@ -2194,6 +2222,11 @@ FT_BEGIN_HEADER /* The loaded glyph may be transformed. See @FT_Set_Transform for */ /* the details. */ /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values which */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index d2f0a4d76..3ef0eb54b 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -38,6 +38,7 @@ #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_GLYPH_DICT_H + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -165,10 +166,10 @@ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + /* reset the size object if necessary */ if ( load_flags & FT_LOAD_NO_SCALE ) size = NULL; - /* reset the size object if necessary */ if ( size ) { /* these two objects must have the same parent */ @@ -186,10 +187,10 @@ } - /* - * GLYPH DICT SERVICE - * - */ + /* + * GLYPH DICT SERVICE + * + */ static FT_Error cff_get_glyph_name( CFF_Face face, @@ -286,10 +287,10 @@ }; - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Int cff_ps_has_glyph_names( FT_Face face ) @@ -356,9 +357,9 @@ /* - * POSTSCRIPT NAME SERVICE - * - */ + * POSTSCRIPT NAME SERVICE + * + */ static const char* cff_get_ps_name( CFF_Face face ) @@ -422,7 +423,7 @@ /* - * CID INFO SERVICE + * CID INFO SERVICE * */ static FT_Error @@ -467,11 +468,10 @@ if ( supplement ) *supplement = dict->cid_supplement; - } - Fail: - return error; + Fail: + return error; } diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index 544deeaa6..56d14c86b 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -446,7 +446,7 @@ /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = dict->cid_count; + cffface->num_glyphs = cff->charset.max_cid; else cffface->num_glyphs = cff->charstrings_index.count; @@ -647,11 +647,15 @@ #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ - /* has unset this flag because of the 3.0 `post' table */ + /* has unset this flag because of the 3.0 `post' table. */ if ( dict->cid_registry == 0xFFFFU ) cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif + if ( dict->cid_registry != 0xFFFFU ) + cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; + + /*******************************************************************/ /* */ /* Compute char maps. */ diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c index 15e0a5ee8..af276f7f3 100644 --- a/src/cff/cffparse.c +++ b/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -202,10 +202,20 @@ if ( nib >= 10 ) break; - if ( divider < 10000000L ) + /* Increase precision if the integer part is zero */ + /* and we have to scale the real number. */ + if ( !result && power_ten ) { - num = num * 10 + nib; - divider *= 10; + power_ten--; + num = num * 10 + nib; + } + else + { + if ( divider < 10000000L ) + { + num = num * 10 + nib; + divider *= 10; + } } } @@ -248,10 +258,10 @@ power_ten += (FT_Int)exponent; } - /* Move the integer part into the high 16 bits. */ + /* Move the integer part into the higher 16 bits. */ result <<= 16; - /* Place the decimal part into the low 16 bits. */ + /* Place the decimal part into the lower 16 bits. */ if ( num ) result |= FT_DivFix( num, divider ); @@ -337,7 +347,10 @@ temp = FT_ABS( matrix->yy ); - *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); + *upm = (FT_UShort)FT_DivFix( 1000, temp ); + + /* we normalize the matrix so that `matrix->xx' is 1; */ + /* the scaling is done with `units_per_em' then */ if ( temp != 0x10000L ) { diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c index 5c5a72957..85ee6cf19 100644 --- a/src/cid/cidriver.c +++ b/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,6 +27,8 @@ #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_CID_H + /*************************************************************************/ /* */ @@ -38,10 +40,10 @@ #define FT_COMPONENT trace_ciddriver - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* cid_get_postscript_name( CID_Face face ) @@ -62,10 +64,10 @@ }; - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error cid_ps_get_font_info( FT_Face face, @@ -84,16 +86,49 @@ }; - /* - * SERVICE LIST - * - */ + /* + * CID INFO SERVICE + * + */ + static FT_Error + cid_get_ros( CID_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + CID_FaceInfo cid = &face->cid; + + + if ( registry ) + *registry = cid->registry; + + if ( ordering ) + *ordering = cid->ordering; + + if ( supplement ) + *supplement = cid->supplement; + + return CID_Err_Ok; + } + + + static const FT_Service_CIDRec cid_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros + }; + + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec cid_services[] = { - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { FT_SERVICE_ID_CID, &cid_service_cid_info }, { NULL, NULL } };