ref: 210d61894b416ccf6b3bb0700eff34f1a4d7138d
parent: a56e526671f9d124744de69760e86543cb4c52e2
author: Werner Lemberg <[email protected]>
date: Tue Apr 1 01:55:48 EDT 2008
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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2008-03-31 Werner Lemberg <[email protected]>
+
+ 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 <[email protected]>
Adjustments for Visual C++ 8.0, as reported by Rainer Deyke.
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -12,7 +12,9 @@
- Improved Mac support.
+ - Subsetted CID-keyed CFFs are now supported correctly.
+
II. IMPORTANT CHANGES
- The new function `FT_Get_CID_Registry_Ordering_Supplement' gives
@@ -25,6 +27,10 @@
- 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
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -1021,6 +1021,15 @@
/* 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 @@
#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 @@
( 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 )
+
+
/*************************************************************************/
/* */
/* <Constant> */
@@ -2193,6 +2221,11 @@
/* <Note> */
/* 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,
--- 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;
}
--- 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,10 +647,14 @@
#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;
+
/*******************************************************************/
/* */
--- 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,11 +202,21 @@
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;
+ }
+ }
}
/* read exponent, if any */
@@ -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 )
{
--- 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,7 +27,9 @@
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_XFREE86_NAME_H
#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include FT_SERVICE_CID_H
+
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
@@ -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 }
};