summaryrefslogtreecommitdiff
path: root/src/freetype2/cff
diff options
context:
space:
mode:
authorscuri <scuri>2009-10-20 17:20:18 +0000
committerscuri <scuri>2009-10-20 17:20:18 +0000
commit27a4f9c4ac45ff65f941964f7351b64b1e6a9f35 (patch)
tree2f68c5d9ce5bf6cbc320ac17aef0a65a3ceb99a1 /src/freetype2/cff
parent2b70507615b2611fce4294c65bec7264644e2665 (diff)
*** empty log message ***
Diffstat (limited to 'src/freetype2/cff')
-rw-r--r--src/freetype2/cff/cff.c1
-rw-r--r--src/freetype2/cff/cffcmap.c25
-rw-r--r--src/freetype2/cff/cffcmap.h6
-rw-r--r--src/freetype2/cff/cffdrivr.c329
-rw-r--r--src/freetype2/cff/cffdrivr.h3
-rw-r--r--src/freetype2/cff/cffgload.c706
-rw-r--r--src/freetype2/cff/cffgload.h17
-rw-r--r--src/freetype2/cff/cffload.c98
-rw-r--r--src/freetype2/cff/cffload.h8
-rw-r--r--src/freetype2/cff/cffobjs.c431
-rw-r--r--src/freetype2/cff/cffobjs.h22
-rw-r--r--src/freetype2/cff/cffparse.c459
-rw-r--r--src/freetype2/cff/cffparse.h35
-rw-r--r--src/freetype2/cff/cffpic.c99
-rw-r--r--src/freetype2/cff/cffpic.h80
-rw-r--r--src/freetype2/cff/cfftypes.h10
16 files changed, 1702 insertions, 627 deletions
diff --git a/src/freetype2/cff/cff.c b/src/freetype2/cff/cff.c
index e6d8954..fccfd44 100644
--- a/src/freetype2/cff/cff.c
+++ b/src/freetype2/cff/cff.c
@@ -19,6 +19,7 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
+#include "cffpic.c"
#include "cffdrivr.c"
#include "cffparse.c"
#include "cffload.c"
diff --git a/src/freetype2/cff/cffcmap.c b/src/freetype2/cff/cffcmap.c
index fffc5fc..46d603e 100644
--- a/src/freetype2/cff/cffcmap.c
+++ b/src/freetype2/cff/cffcmap.c
@@ -4,7 +4,7 @@
/* */
/* CFF character mapping table (cmap) support (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2006 by */
+/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -65,7 +65,7 @@
}
- FT_CALLBACK_DEF( FT_UInt )
+ FT_CALLBACK_DEF( FT_UInt32 )
cff_cmap_encoding_char_next( CFF_CMapStd cmap,
FT_UInt32 *pchar_code )
{
@@ -99,16 +99,16 @@
}
- FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
- cff_cmap_encoding_class_rec =
- {
+ FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec,
sizeof ( CFF_CMapStdRec ),
(FT_CMap_InitFunc) cff_cmap_encoding_init,
(FT_CMap_DoneFunc) cff_cmap_encoding_done,
(FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index,
- (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next
- };
+ (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
+ )
/*************************************************************************/
@@ -192,7 +192,7 @@
}
- FT_CALLBACK_DEF( FT_UInt )
+ FT_CALLBACK_DEF( FT_UInt32 )
cff_cmap_unicode_char_next( PS_Unicodes unicodes,
FT_UInt32 *pchar_code )
{
@@ -205,16 +205,15 @@
}
- FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
- cff_cmap_unicode_class_rec =
- {
+ FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec,
sizeof ( PS_UnicodesRec ),
(FT_CMap_InitFunc) cff_cmap_unicode_init,
(FT_CMap_DoneFunc) cff_cmap_unicode_done,
(FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index,
- (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next
- };
+ (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,
+ NULL, NULL, NULL, NULL, NULL
+ )
/* END */
diff --git a/src/freetype2/cff/cffcmap.h b/src/freetype2/cff/cffcmap.h
index 3809b85..3f7f67b 100644
--- a/src/freetype2/cff/cffcmap.h
+++ b/src/freetype2/cff/cffcmap.h
@@ -43,8 +43,7 @@ FT_BEGIN_HEADER
} CFF_CMapStdRec;
- FT_CALLBACK_TABLE const FT_CMap_ClassRec
- cff_cmap_encoding_class_rec;
+ FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec)
/*************************************************************************/
@@ -57,8 +56,7 @@ FT_BEGIN_HEADER
/* unicode (synthetic) cmaps */
- FT_CALLBACK_TABLE const FT_CMap_ClassRec
- cff_cmap_unicode_class_rec;
+ FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec)
FT_END_HEADER
diff --git a/src/freetype2/cff/cffdrivr.c b/src/freetype2/cff/cffdrivr.c
index 952e88e..217adf2 100644
--- a/src/freetype2/cff/cffdrivr.c
+++ b/src/freetype2/cff/cffdrivr.c
@@ -4,7 +4,7 @@
/* */
/* OpenType font driver implementation (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -21,21 +21,25 @@
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_IDS_H
+#include FT_SERVICE_CID_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_TT_CMAP_H
#include "cffdrivr.h"
#include "cffgload.h"
#include "cffload.h"
#include "cffcmap.h"
+#include "cffparse.h"
#include "cfferrs.h"
+#include "cffpic.h"
#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 */
@@ -151,7 +155,7 @@
FT_UInt glyph_index,
FT_Int32 load_flags )
{
- FT_Error error;
+ FT_Error error;
CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot;
CFF_Size size = (CFF_Size)cffsize;
@@ -163,10 +167,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 */
@@ -184,10 +188,39 @@
}
- /*
- * GLYPH DICT SERVICE
- *
- */
+ FT_CALLBACK_DEF( FT_Error )
+ cff_get_advances( FT_Face face,
+ FT_UInt start,
+ FT_UInt count,
+ FT_Int32 flags,
+ FT_Fixed* advances )
+ {
+ FT_UInt nn;
+ FT_Error error = CFF_Err_Ok;
+ FT_GlyphSlot slot = face->glyph;
+
+
+ flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
+
+ for ( nn = 0; nn < count; nn++ )
+ {
+ error = Load_Glyph( slot, face->size, start + nn, flags );
+ if ( error )
+ break;
+
+ advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
+ ? slot->linearVertAdvance
+ : slot->linearHoriAdvance;
+ }
+
+ return error;
+ }
+
+
+ /*
+ * GLYPH DICT SERVICE
+ *
+ */
static FT_Error
cff_get_glyph_name( CFF_Face face,
@@ -206,10 +239,10 @@
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
if ( !psnames )
{
- FT_ERROR(( "cff_get_glyph_name:" ));
- FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" ));
- FT_ERROR(( " " ));
- FT_ERROR(( " without the `PSNames' module\n" ));
+ FT_ERROR(( "cff_get_glyph_name:"
+ " cannot get glyph name from CFF & CEF fonts\n"
+ " "
+ " without the `PSNames' module\n" ));
error = CFF_Err_Unknown_File_Format;
goto Exit;
}
@@ -226,8 +259,8 @@
FT_FREE( gname );
error = CFF_Err_Ok;
- Exit:
- return error;
+ Exit:
+ return error;
}
@@ -277,17 +310,16 @@
}
- static const FT_Service_GlyphDictRec cff_service_glyph_dict =
- {
+ FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
(FT_GlyphDict_GetNameFunc) cff_get_glyph_name,
- (FT_GlyphDict_NameIndexFunc)cff_get_name_index,
- };
+ (FT_GlyphDict_NameIndexFunc)cff_get_name_index
+ )
- /*
- * POSTSCRIPT INFO SERVICE
- *
- */
+ /*
+ * POSTSCRIPT INFO SERVICE
+ *
+ */
static FT_Int
cff_ps_has_glyph_names( FT_Face face )
@@ -306,9 +338,10 @@
if ( cff && cff->font_info == NULL )
{
- CFF_FontRecDict dict = &cff->top_font.font_dict;
- PS_FontInfoRec *font_info;
- FT_Memory memory = face->root.memory;
+ CFF_FontRecDict dict = &cff->top_font.font_dict;
+ PS_FontInfoRec *font_info;
+ FT_Memory memory = face->root.memory;
+ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
@@ -316,19 +349,19 @@
font_info->version = cff_index_get_sid_string( &cff->string_index,
dict->version,
- cff->psnames );
+ psnames );
font_info->notice = cff_index_get_sid_string( &cff->string_index,
dict->notice,
- cff->psnames );
+ psnames );
font_info->full_name = cff_index_get_sid_string( &cff->string_index,
dict->full_name,
- cff->psnames );
+ psnames );
font_info->family_name = cff_index_get_sid_string( &cff->string_index,
dict->family_name,
- cff->psnames );
+ psnames );
font_info->weight = cff_index_get_sid_string( &cff->string_index,
dict->weight,
- cff->psnames );
+ psnames );
font_info->italic_angle = dict->italic_angle;
font_info->is_fixed_pitch = dict->is_fixed_pitch;
font_info->underline_position = (FT_Short)dict->underline_position;
@@ -337,19 +370,40 @@
cff->font_info = font_info;
}
- *afont_info = *cff->font_info;
+ if ( cff )
+ *afont_info = *cff->font_info;
Fail:
return error;
}
- static const FT_Service_PsInfoRec cff_service_ps_info =
- {
+ FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
(PS_GetFontInfoFunc) cff_ps_get_font_info,
+ (PS_GetFontExtraFunc) NULL,
(PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
(PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
- };
+ )
+
+
+ /*
+ * POSTSCRIPT NAME SERVICE
+ *
+ */
+
+ static const char*
+ cff_get_ps_name( CFF_Face face )
+ {
+ CFF_Font cff = (CFF_Font)face->extra.data;
+
+
+ return (const char*)cff->font_name;
+ }
+
+
+ FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,
+ (FT_PsName_GetFunc)cff_get_ps_name
+ )
/*
@@ -368,15 +422,16 @@
{
FT_CMap cmap = FT_CMAP( charmap );
FT_Error error = CFF_Err_Ok;
+ FT_Face face = FT_CMAP_FACE( cmap );
+ FT_Library library = FT_FACE_LIBRARY( face );
cmap_info->language = 0;
+ cmap_info->format = 0;
- if ( cmap->clazz != &cff_cmap_encoding_class_rec &&
- cmap->clazz != &cff_cmap_unicode_class_rec )
+ if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&
+ cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET )
{
- FT_Face face = FT_CMAP_FACE( cmap );
- FT_Library library = FT_FACE_LIBRARY( face );
FT_Module sfnt = FT_Get_Module( library, "sfnt" );
FT_Service_TTCMaps service =
(FT_Service_TTCMaps)ft_module_get_service( sfnt,
@@ -391,10 +446,143 @@
}
- static const FT_Service_TTCMapsRec cff_service_get_cmap_info =
- {
+ FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,
(TT_CMap_Info_GetFunc)cff_get_cmap_info
- };
+ )
+
+
+ /*
+ * CID INFO SERVICE
+ *
+ */
+ static FT_Error
+ cff_get_ros( CFF_Face face,
+ const char* *registry,
+ const char* *ordering,
+ FT_Int *supplement )
+ {
+ FT_Error error = CFF_Err_Ok;
+ CFF_Font cff = (CFF_Font)face->extra.data;
+
+
+ if ( cff )
+ {
+ CFF_FontRecDict dict = &cff->top_font.font_dict;
+ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
+
+
+ if ( dict->cid_registry == 0xFFFFU )
+ {
+ error = CFF_Err_Invalid_Argument;
+ goto Fail;
+ }
+
+ if ( registry )
+ {
+ if ( cff->registry == NULL )
+ cff->registry = cff_index_get_sid_string( &cff->string_index,
+ dict->cid_registry,
+ psnames );
+ *registry = cff->registry;
+ }
+
+ if ( ordering )
+ {
+ if ( cff->ordering == NULL )
+ cff->ordering = cff_index_get_sid_string( &cff->string_index,
+ dict->cid_ordering,
+ psnames );
+ *ordering = cff->ordering;
+ }
+
+ /*
+ * XXX: According to Adobe TechNote #5176, the supplement in CFF
+ * can be a real number. We truncate it to fit public API
+ * since freetype-2.3.6.
+ */
+ if ( supplement )
+ {
+ if ( dict->cid_supplement < FT_INT_MIN ||
+ dict->cid_supplement > FT_INT_MAX )
+ FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
+ dict->cid_supplement ));
+ *supplement = (FT_Int)dict->cid_supplement;
+ }
+ }
+
+ Fail:
+ return error;
+ }
+
+
+ static FT_Error
+ cff_get_is_cid( CFF_Face face,
+ FT_Bool *is_cid )
+ {
+ FT_Error error = CFF_Err_Ok;
+ CFF_Font cff = (CFF_Font)face->extra.data;
+
+
+ *is_cid = 0;
+
+ if ( cff )
+ {
+ CFF_FontRecDict dict = &cff->top_font.font_dict;
+
+
+ if ( dict->cid_registry != 0xFFFFU )
+ *is_cid = 1;
+ }
+
+ return error;
+ }
+
+
+ static FT_Error
+ cff_get_cid_from_glyph_index( CFF_Face face,
+ FT_UInt glyph_index,
+ FT_UInt *cid )
+ {
+ FT_Error error = CFF_Err_Ok;
+ CFF_Font cff;
+
+
+ cff = (CFF_Font)face->extra.data;
+
+ if ( cff )
+ {
+ FT_UInt c;
+ CFF_FontRecDict dict = &cff->top_font.font_dict;
+
+
+ if ( dict->cid_registry == 0xFFFFU )
+ {
+ error = CFF_Err_Invalid_Argument;
+ goto Fail;
+ }
+
+ if ( glyph_index > cff->num_glyphs )
+ {
+ error = CFF_Err_Invalid_Argument;
+ goto Fail;
+ }
+
+ c = cff->charset.sids[glyph_index];
+
+ if ( cid )
+ *cid = c;
+ }
+
+ Fail:
+ return error;
+ }
+
+
+ FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,
+ (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
+ (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid,
+ (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index
+ )
/*************************************************************************/
@@ -408,18 +596,24 @@
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
-
- static const FT_ServiceDescRec cff_services[] =
- {
- { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF },
- { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info },
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
- { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict },
+ FT_DEFINE_SERVICEDESCREC6(cff_services,
+ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
+ FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
+ )
+#else
+ FT_DEFINE_SERVICEDESCREC5(cff_services,
+ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
+ FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
+ )
#endif
- { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info },
- { NULL, NULL }
- };
-
FT_CALLBACK_DEF( FT_Module_Interface )
cff_get_interface( FT_Module driver, /* CFF_Driver */
@@ -427,9 +621,11 @@
{
FT_Module sfnt;
FT_Module_Interface result;
+ FT_Library library = driver->library;
+ FT_UNUSED(library);
- result = ft_service_list_lookup( cff_services, module_interface );
+ result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
if ( result != NULL )
return result;
@@ -442,11 +638,13 @@
/* The FT_DriverInterface structure is defined in ftdriver.h. */
- FT_CALLBACK_TABLE_DEF
- const FT_Driver_ClassRec cff_driver_class =
- {
- /* begin with the FT_Module_Class fields */
- {
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#define CFF_SIZE_SELECT cff_size_select
+#else
+#define CFF_SIZE_SELECT 0
+#endif
+
+ FT_DEFINE_DRIVER(cff_driver_class,
FT_MODULE_FONT_DRIVER |
FT_MODULE_DRIVER_SCALABLE |
FT_MODULE_DRIVER_HAS_HINTER,
@@ -461,7 +659,6 @@
cff_driver_init,
cff_driver_done,
cff_get_interface,
- },
/* now the specific driver fields */
sizeof( TT_FaceRec ),
@@ -475,25 +672,19 @@
cff_slot_init,
cff_slot_done,
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- ft_stub_set_char_sizes,
- ft_stub_set_pixel_sizes,
-#endif
+ ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
Load_Glyph,
cff_get_kerning,
0, /* FT_Face_AttachFunc */
- 0, /* FT_Face_GetAdvancesFunc */
+ cff_get_advances, /* FT_Face_GetAdvancesFunc */
cff_size_request,
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
- cff_size_select
-#else
- 0 /* FT_Size_SelectFunc */
-#endif
- };
+ CFF_SIZE_SELECT
+ )
/* END */
diff --git a/src/freetype2/cff/cffdrivr.h b/src/freetype2/cff/cffdrivr.h
index 553848c..50e8138 100644
--- a/src/freetype2/cff/cffdrivr.h
+++ b/src/freetype2/cff/cffdrivr.h
@@ -27,8 +27,7 @@
FT_BEGIN_HEADER
- FT_CALLBACK_TABLE
- const FT_Driver_ClassRec cff_driver_class;
+ FT_DECLARE_DRIVER( cff_driver_class )
FT_END_HEADER
diff --git a/src/freetype2/cff/cffgload.c b/src/freetype2/cff/cffgload.c
index 0e2a179..40fa20b 100644
--- a/src/freetype2/cff/cffgload.c
+++ b/src/freetype2/cff/cffgload.c
@@ -4,7 +4,7 @@
/* */
/* OpenType Glyph Loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,11 +18,9 @@
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
#include FT_OUTLINE_H
-#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include "cffobjs.h"
@@ -110,6 +108,12 @@
cff_op_callgsubr,
cff_op_return,
+ /* Type 1 opcodes: invalid but seen in real life */
+ cff_op_hsbw,
+ cff_op_closepath,
+ cff_op_callothersubr,
+ cff_op_pop,
+
/* do not remove */
cff_op_max
@@ -120,6 +124,11 @@
#define CFF_COUNT_EXACT 0x40
#define CFF_COUNT_CLEAR_STACK 0x20
+ /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
+ /* used for checking the width and requested numbers of arguments */
+ /* only; they are set to zero afterwards */
+
+ /* the other two flags are informative only and unused currently */
static const FT_Byte cff_argument_counts[] =
{
@@ -187,6 +196,11 @@
1, /* callsubr */
1,
+ 0,
+
+ 2, /* hsbw */
+ 0,
+ 0,
0
};
@@ -222,6 +236,8 @@
/* */
/* glyph :: The current glyph object. */
/* */
+ /* hinting :: Whether hinting is active. */
+ /* */
static void
cff_builder_init( CFF_Builder* builder,
TT_Face face,
@@ -251,17 +267,14 @@
if ( hinting && size )
{
- builder->hints_globals = size->root.internal;
+ CFF_Internal internal = (CFF_Internal)size->root.internal;
+
+
+ builder->hints_globals = (void *)internal->topfont;
builder->hints_funcs = glyph->root.internal->glyph_hints;
}
}
- if ( size )
- {
- builder->scale_x = size->root.metrics.x_scale;
- builder->scale_y = size->root.metrics.y_scale;
- }
-
builder->pos_x = 0;
builder->pos_y = 0;
@@ -339,11 +352,15 @@
/* decoder :: A pointer to the glyph builder to initialize. */
/* */
/* <Input> */
- /* face :: The current face object. */
+ /* face :: The current face object. */
/* */
- /* size :: The current size object. */
+ /* size :: The current size object. */
+ /* */
+ /* slot :: The current glyph object. */
/* */
- /* slot :: The current glyph object. */
+ /* hinting :: Whether hinting is active. */
+ /* */
+ /* hint_mode :: The hinting mode. */
/* */
FT_LOCAL_DEF( void )
cff_decoder_init( CFF_Decoder* decoder,
@@ -371,18 +388,21 @@
}
- /* this function is used to select the locals subrs array */
+ /* this function is used to select the subfont */
+ /* and the locals subrs array */
FT_LOCAL_DEF( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder,
+ CFF_Size size,
FT_UInt glyph_index )
{
- CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data;
- CFF_SubFont sub = &cff->top_font;
- FT_Error error = CFF_Err_Ok;
+ CFF_Builder *builder = &decoder->builder;
+ CFF_Font cff = (CFF_Font)builder->face->extra.data;
+ CFF_SubFont sub = &cff->top_font;
+ FT_Error error = CFF_Err_Ok;
/* manage CID fonts */
- if ( cff->num_subfonts >= 1 )
+ if ( cff->num_subfonts )
{
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
@@ -393,9 +413,24 @@
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
-
+
+ FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
+
sub = cff->subfonts[fd_index];
+
+ if ( builder->hints_funcs && size )
+ {
+ CFF_Internal internal = (CFF_Internal)size->root.internal;
+
+
+ /* for CFFs without subfonts, this value has already been set */
+ builder->hints_globals = (void *)internal->subfonts[fd_index];
+ }
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+ else
+ FT_TRACE4(( "glyph index %d:\n", glyph_index ));
+#endif
decoder->num_locals = sub->num_local_subrs;
decoder->locals = sub->local_subrs;
@@ -437,8 +472,6 @@
point->x = x >> 16;
point->y = y >> 16;
*control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
-
- builder->last = *point;
}
outline->n_points++;
@@ -517,27 +550,24 @@
cff_builder_close_contour( CFF_Builder* builder )
{
FT_Outline* outline = builder->current;
+ FT_Int first;
if ( !outline )
return;
- /* XXXX: We must not include the last point in the path if it */
- /* is located on the first point. */
+ first = outline->n_contours <= 1
+ ? 0 : outline->contours[outline->n_contours - 2] + 1;
+
+ /* We must not include the last point in the path if it */
+ /* is located on the first point. */
if ( outline->n_points > 1 )
{
- FT_Int first = 0;
FT_Vector* p1 = outline->points + first;
FT_Vector* p2 = outline->points + outline->n_points - 1;
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
- if ( outline->n_contours > 1 )
- {
- first = outline->contours[outline->n_contours - 2] + 1;
- p1 = outline->points + first;
- }
-
/* `delete' last point only if it coincides with the first */
/* point and if it is not a control point (which can happen). */
if ( p1->x == p2->x && p1->y == p2->y )
@@ -546,8 +576,18 @@
}
if ( outline->n_contours > 0 )
- outline->contours[outline->n_contours - 1] =
- (short)( outline->n_points - 1 );
+ {
+ /* Don't add contours only consisting of one point, i.e., */
+ /* check whether begin point and last point are the same. */
+ if ( first == outline->n_points - 1 )
+ {
+ outline->n_contours--;
+ outline->n_points--;
+ }
+ else
+ outline->contours[outline->n_contours - 1] =
+ (short)( outline->n_points - 1 );
+ }
}
@@ -667,6 +707,12 @@
FT_ULong charstring_len;
+ if ( decoder->seac )
+ {
+ FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
+ return CFF_Err_Syntax_Error;
+ }
+
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Incremental fonts don't necessarily have valid charsets. */
/* They use the character code, not the glyph index, in this case. */
@@ -687,8 +733,8 @@
if ( bchar_index < 0 || achar_index < 0 )
{
- FT_ERROR(( "cff_operator_seac:" ));
- FT_ERROR(( " invalid seac character code arguments\n" ));
+ FT_ERROR(( "cff_operator_seac:"
+ " invalid seac character code arguments\n" ));
return CFF_Err_Syntax_Error;
}
@@ -737,8 +783,11 @@
&charstring, &charstring_len );
if ( !error )
{
+ /* the seac operator must not be nested */
+ decoder->seac = TRUE;
error = cff_decoder_parse_charstrings( decoder, charstring,
charstring_len );
+ decoder->seac = FALSE;
if ( error )
goto Exit;
@@ -763,8 +812,11 @@
&charstring, &charstring_len );
if ( !error )
{
+ /* the seac operator must not be nested */
+ decoder->seac = TRUE;
error = cff_decoder_parse_charstrings( decoder, charstring,
charstring_len );
+ decoder->seac = FALSE;
if ( error )
goto Exit;
@@ -826,9 +878,10 @@
decoder->read_width = 1;
/* compute random seed from stack address of parameter */
- seed = (FT_Fixed)(char*)&seed ^
- (FT_Fixed)(char*)&decoder ^
- (FT_Fixed)(char*)&charstring_base;
+ seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^
+ (FT_PtrDist)(char*)&decoder ^
+ (FT_PtrDist)(char*)&charstring_base ) &
+ FT_ULONG_MAX ) ;
seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
if ( seed == 0 )
seed = 0x7384;
@@ -883,18 +936,18 @@
ip += 2;
}
else if ( v < 247 )
- val = (FT_Long)v - 139;
+ val = (FT_Int32)v - 139;
else if ( v < 251 )
{
if ( ip >= limit )
goto Syntax_Error;
- val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108;
+ val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
}
else if ( v < 255 )
{
if ( ip >= limit )
goto Syntax_Error;
- val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108;
+ val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
}
else
{
@@ -923,6 +976,11 @@
}
else
{
+ /* The specification says that normally arguments are to be taken */
+ /* from the bottom of the stack. However, this seems not to be */
+ /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
+ /* arguments similar to a PS interpreter. */
+
FT_Fixed* args = decoder->top;
FT_Int num_args = (FT_Int)( args - decoder->stack );
FT_Int req_args;
@@ -954,6 +1012,9 @@
case 8:
op = cff_op_rrcurveto;
break;
+ case 9:
+ op = cff_op_closepath;
+ break;
case 10:
op = cff_op_callsubr;
break;
@@ -1004,6 +1065,12 @@
case 15:
op = cff_op_eq;
break;
+ case 16:
+ op = cff_op_callothersubr;
+ break;
+ case 17:
+ op = cff_op_pop;
+ break;
case 18:
op = cff_op_drop;
break;
@@ -1055,6 +1122,9 @@
}
}
break;
+ case 13:
+ op = cff_op_hsbw;
+ break;
case 14:
op = cff_op_endchar;
break;
@@ -1103,6 +1173,7 @@
default:
;
}
+
if ( op == cff_op_unknown )
goto Syntax_Error;
@@ -1110,8 +1181,6 @@
req_args = cff_argument_counts[op];
if ( req_args & CFF_COUNT_CHECK_WIDTH )
{
- args = stack;
-
if ( num_args > 0 && decoder->read_width )
{
/* If `nominal_width' is non-zero, the number is really a */
@@ -1145,7 +1214,7 @@
case cff_op_endchar:
/* If there is a width specified for endchar, we either have */
/* 1 argument or 5 arguments. We like to argue. */
- set_width_ok = ( ( num_args == 5 ) || ( num_args == 1 ) );
+ set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
break;
default:
@@ -1158,9 +1227,14 @@
decoder->glyph_width = decoder->nominal_width +
( stack[0] >> 16 );
+ if ( decoder->width_only )
+ {
+ /* we only want the advance width; stop here */
+ break;
+ }
+
/* Consumed an argument. */
num_args--;
- args++;
}
}
@@ -1168,12 +1242,20 @@
req_args = 0;
}
- req_args &= 15;
+ req_args &= 0x000F;
if ( num_args < req_args )
goto Stack_Underflow;
args -= req_args;
num_args -= req_args;
+ /* At this point, `args' points to the first argument of the */
+ /* operand in case `req_args' isn't zero. Otherwise, we have */
+ /* to adjust `args' manually. */
+
+ /* Note that we only pop arguments from the stack which we */
+ /* really need and can digest so that we can continue in case */
+ /* of superfluous stack elements. */
+
switch ( op )
{
case cff_op_hstem:
@@ -1181,15 +1263,16 @@
case cff_op_hstemhm:
case cff_op_vstemhm:
/* the number of arguments is always even here */
- FT_TRACE4(( op == cff_op_hstem ? " hstem" :
- ( op == cff_op_vstem ? " vstem" :
- ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
+ FT_TRACE4((
+ op == cff_op_hstem ? " hstem\n" :
+ ( op == cff_op_vstem ? " vstem\n" :
+ ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
if ( hinter )
hinter->stems( hinter->hints,
( op == cff_op_hstem || op == cff_op_hstemhm ),
num_args / 2,
- args );
+ args - ( num_args & ~1 ) );
decoder->num_hints += num_args / 2;
args = stack;
@@ -1209,7 +1292,7 @@
hinter->stems( hinter->hints,
0,
num_args / 2,
- args );
+ args - ( num_args & ~1 ) );
decoder->num_hints += num_args / 2;
}
@@ -1232,12 +1315,14 @@
FT_UInt maskbyte;
- FT_TRACE4(( " " ));
+ FT_TRACE4(( " (maskbytes: " ));
for ( maskbyte = 0;
maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3);
maskbyte++, ip++ )
FT_TRACE4(( "0x%02X", *ip ));
+
+ FT_TRACE4(( ")\n" ));
}
#else
ip += ( decoder->num_hints + 7 ) >> 3;
@@ -1248,44 +1333,44 @@
break;
case cff_op_rmoveto:
- FT_TRACE4(( " rmoveto" ));
+ FT_TRACE4(( " rmoveto\n" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
- x += args[0];
- y += args[1];
+ x += args[-2];
+ y += args[-1];
args = stack;
break;
case cff_op_vmoveto:
- FT_TRACE4(( " vmoveto" ));
+ FT_TRACE4(( " vmoveto\n" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
- y += args[0];
+ y += args[-1];
args = stack;
break;
case cff_op_hmoveto:
- FT_TRACE4(( " hmoveto" ));
+ FT_TRACE4(( " hmoveto\n" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
- x += args[0];
+ x += args[-1];
args = stack;
break;
case cff_op_rlineto:
- FT_TRACE4(( " rlineto" ));
+ FT_TRACE4(( " rlineto\n" ));
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args / 2 ) )
goto Fail;
- if ( num_args < 2 || num_args & 1 )
+ if ( num_args < 2 )
goto Stack_Underflow;
- args = stack;
+ args -= num_args & ~1;
while ( args < decoder->top )
{
x += args[0];
@@ -1302,8 +1387,11 @@
FT_Int phase = ( op == cff_op_hlineto );
- FT_TRACE4(( op == cff_op_hlineto ? " hlineto"
- : " vlineto" ));
+ FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
+ : " vlineto\n" ));
+
+ if ( num_args < 1 )
+ goto Stack_Underflow;
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args ) )
@@ -1328,125 +1416,164 @@
break;
case cff_op_rrcurveto:
- FT_TRACE4(( " rrcurveto" ));
+ {
+ FT_Int nargs;
- /* check number of arguments; must be a multiple of 6 */
- if ( num_args % 6 != 0 )
- goto Stack_Underflow;
- if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_args / 2 ) )
- goto Fail;
+ FT_TRACE4(( " rrcurveto\n" ));
- args = stack;
- while ( args < decoder->top )
- {
- x += args[0];
- y += args[1];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[2];
- y += args[3];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[4];
- y += args[5];
- cff_builder_add_point( builder, x, y, 1 );
- args += 6;
+ if ( num_args < 6 )
+ goto Stack_Underflow;
+
+ nargs = num_args - num_args % 6;
+
+ if ( cff_builder_start_point ( builder, x, y ) ||
+ check_points( builder, nargs / 2 ) )
+ goto Fail;
+
+ args -= nargs;
+ while ( args < decoder->top )
+ {
+ x += args[0];
+ y += args[1];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[2];
+ y += args[3];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[4];
+ y += args[5];
+ cff_builder_add_point( builder, x, y, 1 );
+ args += 6;
+ }
+ args = stack;
}
- args = stack;
break;
case cff_op_vvcurveto:
- FT_TRACE4(( " vvcurveto" ));
+ {
+ FT_Int nargs;
- if ( cff_builder_start_point( builder, x, y ) )
- goto Fail;
- args = stack;
- if ( num_args & 1 )
- {
- x += args[0];
- args++;
- num_args--;
- }
+ FT_TRACE4(( " vvcurveto\n" ));
- if ( num_args % 4 != 0 )
- goto Stack_Underflow;
+ if ( num_args < 4 )
+ goto Stack_Underflow;
- if ( check_points( builder, 3 * ( num_args / 4 ) ) )
- goto Fail;
+ /* if num_args isn't of the form 4n or 4n+1, */
+ /* we reduce it to 4n+1 */
- while ( args < decoder->top )
- {
- y += args[0];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[1];
- y += args[2];
- cff_builder_add_point( builder, x, y, 0 );
- y += args[3];
- cff_builder_add_point( builder, x, y, 1 );
- args += 4;
+ nargs = num_args - num_args % 4;
+ if ( num_args - nargs > 0 )
+ nargs += 1;
+
+ if ( cff_builder_start_point( builder, x, y ) )
+ goto Fail;
+
+ args -= nargs;
+
+ if ( nargs & 1 )
+ {
+ x += args[0];
+ args++;
+ nargs--;
+ }
+
+ if ( check_points( builder, 3 * ( nargs / 4 ) ) )
+ goto Fail;
+
+ while ( args < decoder->top )
+ {
+ y += args[0];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[1];
+ y += args[2];
+ cff_builder_add_point( builder, x, y, 0 );
+ y += args[3];
+ cff_builder_add_point( builder, x, y, 1 );
+ args += 4;
+ }
+ args = stack;
}
- args = stack;
break;
case cff_op_hhcurveto:
- FT_TRACE4(( " hhcurveto" ));
+ {
+ FT_Int nargs;
- if ( cff_builder_start_point( builder, x, y ) )
- goto Fail;
- args = stack;
- if ( num_args & 1 )
- {
- y += args[0];
- args++;
- num_args--;
- }
+ FT_TRACE4(( " hhcurveto\n" ));
- if ( num_args % 4 != 0 )
- goto Stack_Underflow;
+ if ( num_args < 4 )
+ goto Stack_Underflow;
- if ( check_points( builder, 3 * ( num_args / 4 ) ) )
- goto Fail;
+ /* if num_args isn't of the form 4n or 4n+1, */
+ /* we reduce it to 4n+1 */
- while ( args < decoder->top )
- {
- x += args[0];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[1];
- y += args[2];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[3];
- cff_builder_add_point( builder, x, y, 1 );
- args += 4;
+ nargs = num_args - num_args % 4;
+ if ( num_args - nargs > 0 )
+ nargs += 1;
+
+ if ( cff_builder_start_point( builder, x, y ) )
+ goto Fail;
+
+ args -= nargs;
+ if ( nargs & 1 )
+ {
+ y += args[0];
+ args++;
+ nargs--;
+ }
+
+ if ( check_points( builder, 3 * ( nargs / 4 ) ) )
+ goto Fail;
+
+ while ( args < decoder->top )
+ {
+ x += args[0];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[1];
+ y += args[2];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[3];
+ cff_builder_add_point( builder, x, y, 1 );
+ args += 4;
+ }
+ args = stack;
}
- args = stack;
break;
case cff_op_vhcurveto:
case cff_op_hvcurveto:
{
FT_Int phase;
+ FT_Int nargs;
- FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto"
- : " hvcurveto" ));
+ FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
+ : " hvcurveto\n" ));
if ( cff_builder_start_point( builder, x, y ) )
goto Fail;
- args = stack;
- if ( num_args < 4 || ( num_args % 4 ) > 1 )
+ if ( num_args < 4 )
goto Stack_Underflow;
- if ( check_points( builder, ( num_args / 4 ) * 3 ) )
+ /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
+ /* we reduce it to the largest one which fits */
+
+ nargs = num_args - num_args % 4;
+ if ( num_args - nargs > 0 )
+ nargs += 1;
+
+ args -= nargs;
+ if ( check_points( builder, ( nargs / 4 ) * 3 ) )
goto Stack_Underflow;
phase = ( op == cff_op_hvcurveto );
- while ( num_args >= 4 )
+ while ( nargs >= 4 )
{
- num_args -= 4;
+ nargs -= 4;
if ( phase )
{
x += args[0];
@@ -1455,7 +1582,7 @@
y += args[2];
cff_builder_add_point( builder, x, y, 0 );
y += args[3];
- if ( num_args == 1 )
+ if ( nargs == 1 )
x += args[4];
cff_builder_add_point( builder, x, y, 1 );
}
@@ -1467,7 +1594,7 @@
y += args[2];
cff_builder_add_point( builder, x, y, 0 );
x += args[3];
- if ( num_args == 1 )
+ if ( nargs == 1 )
y += args[4];
cff_builder_add_point( builder, x, y, 1 );
}
@@ -1480,19 +1607,23 @@
case cff_op_rlinecurve:
{
- FT_Int num_lines = ( num_args - 6 ) / 2;
+ FT_Int num_lines;
+ FT_Int nargs;
- FT_TRACE4(( " rlinecurve" ));
+ FT_TRACE4(( " rlinecurve\n" ));
- if ( num_args < 8 || ( num_args - 6 ) & 1 )
+ if ( num_args < 8 )
goto Stack_Underflow;
+ nargs = num_args & ~1;
+ num_lines = ( nargs - 6 ) / 2;
+
if ( cff_builder_start_point( builder, x, y ) ||
check_points( builder, num_lines + 3 ) )
goto Fail;
- args = stack;
+ args -= nargs;
/* first, add the line segments */
while ( num_lines > 0 )
@@ -1520,19 +1651,24 @@
case cff_op_rcurveline:
{
- FT_Int num_curves = ( num_args - 2 ) / 6;
+ FT_Int num_curves;
+ FT_Int nargs;
- FT_TRACE4(( " rcurveline" ));
+ FT_TRACE4(( " rcurveline\n" ));
- if ( num_args < 8 || ( num_args - 2 ) % 6 )
+ if ( num_args < 8 )
goto Stack_Underflow;
+ nargs = num_args - 2;
+ nargs = nargs - nargs % 6 + 2;
+ num_curves = ( nargs - 2 ) / 6;
+
if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_curves*3 + 2 ) )
+ check_points( builder, num_curves * 3 + 2 ) )
goto Fail;
- args = stack;
+ args -= nargs;
/* first, add the curves */
while ( num_curves > 0 )
@@ -1563,18 +1699,16 @@
FT_Pos start_y;
- FT_TRACE4(( " hflex1" ));
-
- args = stack;
+ FT_TRACE4(( " hflex1\n" ));
- /* adding five more points; 4 control points, 1 on-curve point */
- /* make sure we have enough space for the start point if it */
+ /* adding five more points: 4 control points, 1 on-curve point */
+ /* -- make sure we have enough space for the start point if it */
/* needs to be added */
if ( cff_builder_start_point( builder, x, y ) ||
check_points( builder, 6 ) )
goto Fail;
- /* Record the starting point's y position for later use */
+ /* record the starting point's y position for later use */
start_y = y;
/* first control point */
@@ -1616,9 +1750,7 @@
FT_Pos start_y;
- FT_TRACE4(( " hflex" ));
-
- args = stack;
+ FT_TRACE4(( " hflex\n" ));
/* adding six more points; 4 control points, 2 on-curve points */
if ( cff_builder_start_point( builder, x, y ) ||
@@ -1663,14 +1795,15 @@
case cff_op_flex1:
{
- FT_Pos start_x, start_y; /* record start x, y values for */
- /* alter use */
- FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
- /* algorithm below */
- FT_Int horizontal, count;
+ FT_Pos start_x, start_y; /* record start x, y values for */
+ /* alter use */
+ FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
+ /* algorithm below */
+ FT_Int horizontal, count;
+ FT_Fixed* temp;
- FT_TRACE4(( " flex1" ));
+ FT_TRACE4(( " flex1\n" ));
/* adding six more points; 4 control points, 2 on-curve points */
if ( cff_builder_start_point( builder, x, y ) ||
@@ -1684,21 +1817,20 @@
/* XXX: figure out whether this is supposed to be a horizontal */
/* or vertical flex; the Type 2 specification is vague... */
- args = stack;
+ temp = args;
/* grab up to the last argument */
for ( count = 5; count > 0; count-- )
{
- dx += args[0];
- dy += args[1];
- args += 2;
+ dx += temp[0];
+ dy += temp[1];
+ temp += 2;
}
- /* rewind */
- args = stack;
-
- if ( dx < 0 ) dx = -dx;
- if ( dy < 0 ) dy = -dy;
+ if ( dx < 0 )
+ dx = -dx;
+ if ( dy < 0 )
+ dy = -dy;
/* strange test, but here it is... */
horizontal = ( dx > dy );
@@ -1707,7 +1839,8 @@
{
x += args[0];
y += args[1];
- cff_builder_add_point( builder, x, y, (FT_Bool)( count == 3 ) );
+ cff_builder_add_point( builder, x, y,
+ (FT_Bool)( count == 3 ) );
args += 2;
}
@@ -1734,13 +1867,12 @@
FT_UInt count;
- FT_TRACE4(( " flex" ));
+ FT_TRACE4(( " flex\n" ));
if ( cff_builder_start_point( builder, x, y ) ||
check_points( builder, 6 ) )
goto Fail;
- args = stack;
for ( count = 6; count > 0; count-- )
{
x += args[0];
@@ -1755,21 +1887,20 @@
break;
case cff_op_endchar:
- FT_TRACE4(( " endchar" ));
+ FT_TRACE4(( " endchar\n" ));
/* We are going to emulate the seac operator. */
- if ( num_args == 4 )
+ if ( num_args >= 4 )
{
/* Save glyph width so that the subglyphs don't overwrite it. */
FT_Pos glyph_width = decoder->glyph_width;
error = cff_operator_seac( decoder,
- args[0],
- args[1],
- (FT_Int)( args[2] >> 16 ),
- (FT_Int)( args[3] >> 16 ) );
- args += 4;
+ args[-4],
+ args[-3],
+ (FT_Int)( args[-2] >> 16 ),
+ (FT_Int)( args[-1] >> 16 ) );
decoder->glyph_width = glyph_width;
}
@@ -1799,11 +1930,11 @@
}
/* return now! */
- FT_TRACE4(( "\n\n" ));
+ FT_TRACE4(( "\n" ));
return error;
case cff_op_abs:
- FT_TRACE4(( " abs" ));
+ FT_TRACE4(( " abs\n" ));
if ( args[0] < 0 )
args[0] = -args[0];
@@ -1811,28 +1942,28 @@
break;
case cff_op_add:
- FT_TRACE4(( " add" ));
+ FT_TRACE4(( " add\n" ));
args[0] += args[1];
args++;
break;
case cff_op_sub:
- FT_TRACE4(( " sub" ));
+ FT_TRACE4(( " sub\n" ));
args[0] -= args[1];
args++;
break;
case cff_op_div:
- FT_TRACE4(( " div" ));
+ FT_TRACE4(( " div\n" ));
args[0] = FT_DivFix( args[0], args[1] );
args++;
break;
case cff_op_neg:
- FT_TRACE4(( " neg" ));
+ FT_TRACE4(( " neg\n" ));
args[0] = -args[0];
args++;
@@ -1843,7 +1974,7 @@
FT_Fixed Rand;
- FT_TRACE4(( " rand" ));
+ FT_TRACE4(( " rand\n" ));
Rand = seed;
if ( Rand >= 0x8000L )
@@ -1858,14 +1989,14 @@
break;
case cff_op_mul:
- FT_TRACE4(( " mul" ));
+ FT_TRACE4(( " mul\n" ));
args[0] = FT_MulFix( args[0], args[1] );
args++;
break;
case cff_op_sqrt:
- FT_TRACE4(( " sqrt" ));
+ FT_TRACE4(( " sqrt\n" ));
if ( args[0] > 0 )
{
@@ -1890,7 +2021,7 @@
case cff_op_drop:
/* nothing */
- FT_TRACE4(( " drop" ));
+ FT_TRACE4(( " drop\n" ));
break;
@@ -1899,7 +2030,7 @@
FT_Fixed tmp;
- FT_TRACE4(( " exch" ));
+ FT_TRACE4(( " exch\n" ));
tmp = args[0];
args[0] = args[1];
@@ -1913,7 +2044,7 @@
FT_Int idx = (FT_Int)( args[0] >> 16 );
- FT_TRACE4(( " index" ));
+ FT_TRACE4(( " index\n" ));
if ( idx < 0 )
idx = 0;
@@ -1930,7 +2061,7 @@
FT_Int idx = (FT_Int)( args[1] >> 16 );
- FT_TRACE4(( " roll" ));
+ FT_TRACE4(( " roll\n" ));
if ( count <= 0 )
count = 1;
@@ -1972,7 +2103,7 @@
break;
case cff_op_dup:
- FT_TRACE4(( " dup" ));
+ FT_TRACE4(( " dup\n" ));
args[1] = args[0];
args++;
@@ -1984,7 +2115,7 @@
FT_Int idx = (FT_Int)( args[1] >> 16 );
- FT_TRACE4(( " put" ));
+ FT_TRACE4(( " put\n" ));
if ( idx >= 0 && idx < decoder->len_buildchar )
decoder->buildchar[idx] = val;
@@ -1997,7 +2128,7 @@
FT_Fixed val = 0;
- FT_TRACE4(( " get" ));
+ FT_TRACE4(( " get\n" ));
if ( idx >= 0 && idx < decoder->len_buildchar )
val = decoder->buildchar[idx];
@@ -2008,18 +2139,63 @@
break;
case cff_op_store:
- FT_TRACE4(( " store "));
+ FT_TRACE4(( " store\n"));
goto Unimplemented;
case cff_op_load:
- FT_TRACE4(( " load" ));
+ FT_TRACE4(( " load\n" ));
goto Unimplemented;
case cff_op_dotsection:
/* this operator is deprecated and ignored by the parser */
- FT_TRACE4(( " dotsection" ));
+ FT_TRACE4(( " dotsection\n" ));
+ break;
+
+ case cff_op_closepath:
+ /* this is an invalid Type 2 operator; however, there */
+ /* exist fonts which are incorrectly converted from probably */
+ /* Type 1 to CFF, and some parsers seem to accept it */
+
+ FT_TRACE4(( " closepath (invalid op)\n" ));
+
+ args = stack;
+ break;
+
+ case cff_op_hsbw:
+ /* this is an invalid Type 2 operator; however, there */
+ /* exist fonts which are incorrectly converted from probably */
+ /* Type 1 to CFF, and some parsers seem to accept it */
+
+ FT_TRACE4(( " hsbw (invalid op)\n" ));
+
+ decoder->glyph_width = decoder->nominal_width +
+ (args[1] >> 16);
+ x = args[0];
+ y = 0;
+ args = stack;
+ break;
+
+ case cff_op_callothersubr:
+ /* this is an invalid Type 2 operator; however, there */
+ /* exist fonts which are incorrectly converted from probably */
+ /* Type 1 to CFF, and some parsers seem to accept it */
+
+ FT_TRACE4(( " callothersubr (invalid op)\n" ));
+
+ /* don't modify stack; handle the subr as `unknown' so that */
+ /* following `pop' operands use the arguments on stack */
+ break;
+
+ case cff_op_pop:
+ /* this is an invalid Type 2 operator; however, there */
+ /* exist fonts which are incorrectly converted from probably */
+ /* Type 1 to CFF, and some parsers seem to accept it */
+
+ FT_TRACE4(( " pop (invalid op)\n" ));
+
+ args++;
break;
case cff_op_and:
@@ -2027,7 +2203,7 @@
FT_Fixed cond = args[0] && args[1];
- FT_TRACE4(( " and" ));
+ FT_TRACE4(( " and\n" ));
args[0] = cond ? 0x10000L : 0;
args++;
@@ -2039,7 +2215,7 @@
FT_Fixed cond = args[0] || args[1];
- FT_TRACE4(( " or" ));
+ FT_TRACE4(( " or\n" ));
args[0] = cond ? 0x10000L : 0;
args++;
@@ -2051,7 +2227,7 @@
FT_Fixed cond = !args[0];
- FT_TRACE4(( " eq" ));
+ FT_TRACE4(( " eq\n" ));
args[0] = cond ? 0x10000L : 0;
args++;
@@ -2063,7 +2239,7 @@
FT_Fixed cond = ( args[2] <= args[3] );
- FT_TRACE4(( " ifelse" ));
+ FT_TRACE4(( " ifelse\n" ));
if ( !cond )
args[0] = args[1];
@@ -2077,12 +2253,12 @@
decoder->locals_bias );
- FT_TRACE4(( " callsubr(%d)", idx ));
+ FT_TRACE4(( " callsubr(%d)\n", idx ));
if ( idx >= decoder->num_locals )
{
- FT_ERROR(( "cff_decoder_parse_charstrings:" ));
- FT_ERROR(( " invalid local subr index\n" ));
+ FT_ERROR(( "cff_decoder_parse_charstrings:"
+ " invalid local subr index\n" ));
goto Syntax_Error;
}
@@ -2103,7 +2279,7 @@
if ( !zone->base || zone->limit == zone->base )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
- " invoking empty subrs!\n" ));
+ " invoking empty subrs\n" ));
goto Syntax_Error;
}
@@ -2119,12 +2295,12 @@
decoder->globals_bias );
- FT_TRACE4(( " callgsubr(%d)", idx ));
+ FT_TRACE4(( " callgsubr(%d)\n", idx ));
if ( idx >= decoder->num_globals )
{
- FT_ERROR(( "cff_decoder_parse_charstrings:" ));
- FT_ERROR(( " invalid global subr index\n" ));
+ FT_ERROR(( "cff_decoder_parse_charstrings:"
+ " invalid global subr index\n" ));
goto Syntax_Error;
}
@@ -2145,7 +2321,7 @@
if ( !zone->base || zone->limit == zone->base )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
- " invoking empty subrs!\n" ));
+ " invoking empty subrs\n" ));
goto Syntax_Error;
}
@@ -2156,7 +2332,7 @@
break;
case cff_op_return:
- FT_TRACE4(( " return" ));
+ FT_TRACE4(( " return\n" ));
if ( decoder->zone <= decoder->zones )
{
@@ -2194,15 +2370,15 @@
return error;
Syntax_Error:
- FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" ));
+ FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
return CFF_Err_Invalid_File_Format;
Stack_Underflow:
- FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" ));
+ FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
return CFF_Err_Too_Few_Arguments;
Stack_Overflow:
- FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" ));
+ FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
return CFF_Err_Stack_Overflow;
}
@@ -2260,7 +2436,7 @@
&charstring, &charstring_len );
if ( !error )
{
- error = cff_decoder_prepare( &decoder, glyph_index );
+ error = cff_decoder_prepare( &decoder, size, glyph_index );
if ( !error )
error = cff_decoder_parse_charstrings( &decoder,
charstring,
@@ -2290,23 +2466,30 @@
{
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;
+ TT_Face face = (TT_Face)glyph->root.face;
+ FT_Bool hinting, force_scaling;
+ CFF_Font cff = (CFF_Font)face->extra.data;
FT_Matrix font_matrix;
FT_Vector font_offset;
+ force_scaling = FALSE;
+
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
/* it immediately to the real glyph_index -- if it isn't a */
/* subsetted font, glyph_indices and CIDs are identical, though */
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
- cff->charset.cids )
+ cff->charset.cids )
{
- glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index );
- if ( glyph_index == 0 )
- return CFF_Err_Invalid_Argument;
+ /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
+ if ( glyph_index != 0 )
+ {
+ glyph_index = cff_charset_cid_to_gindex( &cff->charset,
+ glyph_index );
+ if ( glyph_index == 0 )
+ return CFF_Err_Invalid_Argument;
+ }
}
else if ( glyph_index >= cff->num_glyphs )
return CFF_Err_Invalid_Argument;
@@ -2389,6 +2572,36 @@
if ( load_flags & FT_LOAD_SBITS_ONLY )
return CFF_Err_Invalid_Argument;
+ /* if we have a CID subfont, use its matrix (which has already */
+ /* been multiplied with the root matrix) */
+
+ /* this scaling is only relevant if the PS hinter isn't active */
+ if ( cff->num_subfonts )
+ {
+ FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
+ glyph_index );
+
+ FT_ULong top_upm = cff->top_font.font_dict.units_per_em;
+ FT_ULong sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
+
+
+ font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
+ font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
+
+ if ( top_upm != sub_upm )
+ {
+ glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
+ glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
+
+ force_scaling = TRUE;
+ }
+ }
+ else
+ {
+ font_matrix = cff->top_font.font_dict.font_matrix;
+ font_offset = cff->top_font.font_dict.font_offset;
+ }
+
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
@@ -2405,15 +2618,18 @@
cff_decoder_init( &decoder, face, size, glyph, hinting,
FT_LOAD_TARGET_MODE( load_flags ) );
+ if ( load_flags & FT_LOAD_ADVANCE_ONLY )
+ decoder.width_only = TRUE;
+
decoder.builder.no_recurse =
- (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
+ (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
/* now load the unscaled outline */
error = cff_get_glyph_data( face, glyph_index,
&charstring, &charstring_len );
if ( !error )
{
- error = cff_decoder_prepare( &decoder, glyph_index );
+ error = cff_decoder_prepare( &decoder, size, glyph_index );
if ( !error )
{
error = cff_decoder_parse_charstrings( &decoder,
@@ -2481,21 +2697,6 @@
if ( !error )
{
- if ( cff->num_subfonts >= 1 )
- {
- FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
- glyph_index );
-
-
- font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
- font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
- }
- else
- {
- font_matrix = cff->top_font.font_dict.font_matrix;
- font_offset = cff->top_font.font_dict.font_offset;
- }
-
/* Now, set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
/* bearing the yMax. */
@@ -2526,9 +2727,14 @@
glyph->root.linearHoriAdvance = decoder.glyph_width;
glyph->root.internal->glyph_transformed = 0;
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
has_vertical_info = FT_BOOL( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 &&
- face->vertical.long_metrics != 0 );
+ face->vertical.long_metrics );
+#else
+ has_vertical_info = FT_BOOL( face->vertical_info &&
+ face->vertical.number_Of_VMetrics > 0 );
+#endif
/* get the vertical metrics from the vtmx table if we have one */
if ( has_vertical_info )
@@ -2565,7 +2771,6 @@
glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
- /* apply the font matrix */
if ( !( font_matrix.xx == 0x10000L &&
font_matrix.yy == 0x10000L &&
font_matrix.xy == 0 &&
@@ -2587,7 +2792,7 @@
FT_Vector_Transform( &advance, &font_matrix );
metrics->vertAdvance = advance.y + font_offset.y;
- if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
+ if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
{
/* scale the outline and the metrics */
FT_Int n;
@@ -2620,7 +2825,8 @@
metrics->horiBearingY = cbox.yMax;
if ( has_vertical_info )
- metrics->vertBearingX = -metrics->width / 2;
+ metrics->vertBearingX = metrics->horiBearingX -
+ metrics->horiAdvance / 2;
else
ft_synthesize_vertical_metrics( metrics,
metrics->vertAdvance );
diff --git a/src/freetype2/cff/cffgload.h b/src/freetype2/cff/cffgload.h
index f67864a..956817a 100644
--- a/src/freetype2/cff/cffgload.h
+++ b/src/freetype2/cff/cffgload.h
@@ -4,7 +4,7 @@
/* */
/* OpenType Glyph Loader (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -53,12 +53,6 @@ FT_BEGIN_HEADER
/* */
/* current :: The current glyph outline. */
/* */
- /* last :: The last point position. */
- /* */
- /* scale_x :: The horizontal scale (FUnits to sub-pixels). */
- /* */
- /* scale_y :: The vertical scale (FUnits to sub-pixels). */
- /* */
/* pos_x :: The horizontal translation (if composite glyph). */
/* */
/* pos_y :: The vertical translation (if composite glyph). */
@@ -92,11 +86,6 @@ FT_BEGIN_HEADER
FT_Outline* base;
FT_Outline* current;
- FT_Vector last;
-
- FT_Fixed scale_x;
- FT_Fixed scale_y;
-
FT_Pos pos_x;
FT_Pos pos_y;
@@ -146,6 +135,7 @@ FT_BEGIN_HEADER
FT_Pos nominal_width;
FT_Bool read_width;
+ FT_Bool width_only;
FT_Int num_hints;
FT_Fixed* buildchar;
FT_Int len_buildchar;
@@ -164,6 +154,8 @@ FT_BEGIN_HEADER
FT_Render_Mode hint_mode;
+ FT_Bool seac;
+
} CFF_Decoder;
@@ -177,6 +169,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder,
+ CFF_Size size,
FT_UInt glyph_index );
#if 0 /* unused until we support pure CFF fonts */
diff --git a/src/freetype2/cff/cffload.c b/src/freetype2/cff/cffload.c
index dd2f113..64d1395 100644
--- a/src/freetype2/cff/cffload.c
+++ b/src/freetype2/cff/cffload.c
@@ -4,7 +4,7 @@
/* */
/* OpenType and CFF data/program tables loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -31,6 +31,7 @@
#if 1
+
static const FT_UShort cff_isoadobe_charset[229] =
{
0, 1, 2, 3, 4, 5, 6, 7,
@@ -175,13 +176,15 @@
363, 364, 365, 366, 367, 368, 369, 370,
371, 372, 373, 374, 375, 376, 377, 378
};
-#endif
+
+#endif /* 1 */
FT_LOCAL_DEF( FT_UShort )
cff_get_standard_encoding( FT_UInt charcode )
{
- return (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0);
+ return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
+ : 0 );
}
@@ -316,7 +319,7 @@
static FT_Error
cff_index_load_offsets( CFF_Index idx )
{
- FT_Error error = 0;
+ FT_Error error = CFF_Err_Ok;
FT_Stream stream = idx->stream;
FT_Memory memory = stream->memory;
@@ -399,6 +402,7 @@
old_offset = 1;
for ( n = 0; n <= idx->count; n++ )
{
+ /* at this point, `idx->offsets' can't be NULL */
offset = idx->offsets[n];
if ( !offset )
offset = old_offset;
@@ -732,6 +736,7 @@
{
FT_Error error = FT_Err_Ok;
FT_UInt i;
+ FT_Long j;
FT_UShort max_cid = 0;
@@ -746,8 +751,11 @@
if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
goto Exit;
- for ( i = 0; i < num_glyphs; i++ )
- charset->cids[charset->sids[i]] = (FT_UShort)i;
+ /* When multiple GIDs map to the same CID, we choose the lowest */
+ /* GID. This is not described in any spec, but it matches the */
+ /* behaviour of recent Acroread versions. */
+ for ( j = num_glyphs - 1; j >= 0 ; j-- )
+ charset->cids[charset->sids[j]] = (FT_UShort)j;
charset->max_cid = max_cid;
charset->num_glyphs = num_glyphs;
@@ -838,7 +846,20 @@
goto Exit;
for ( j = 1; j < num_glyphs; j++ )
- charset->sids[j] = FT_GET_USHORT();
+ {
+ FT_UShort sid = FT_GET_USHORT();
+
+
+ /* this constant is given in the CFF specification */
+ if ( sid < 65000L )
+ charset->sids[j] = sid;
+ else
+ {
+ FT_TRACE0(( "cff_charset_load:"
+ " invalid SID value %d set to zero\n", sid ));
+ charset->sids[j] = 0;
+ }
+ }
FT_FRAME_EXIT();
}
@@ -871,6 +892,20 @@
goto Exit;
}
+ /* check whether the range contains at least one valid glyph; */
+ /* the constant is given in the CFF specification */
+ if ( glyph_sid >= 65000L ) {
+ FT_ERROR(( "cff_charset_load: invalid SID range\n" ));
+ error = CFF_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ /* try to rescue some of the SIDs if `nleft' is too large */
+ if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) {
+ FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" ));
+ nleft = ( FT_UInt )( 65000L - 1L - glyph_sid );
+ }
+
/* Fill in the range of sids -- `nleft + 1' glyphs. */
for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
charset->sids[j] = glyph_sid;
@@ -879,7 +914,7 @@
break;
default:
- FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
+ FT_ERROR(( "cff_charset_load: invalid table format\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
@@ -902,7 +937,7 @@
if ( num_glyphs > 229 )
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
- "predefined charset (Adobe ISO-Latin)!\n" ));
+ "predefined charset (Adobe ISO-Latin)\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
@@ -920,7 +955,7 @@
if ( num_glyphs > 166 )
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
- "predefined charset (Adobe Expert)!\n" ));
+ "predefined charset (Adobe Expert)\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
@@ -938,7 +973,7 @@
if ( num_glyphs > 87 )
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
- "predefined charset (Adobe Expert Subset)!\n" ));
+ "predefined charset (Adobe Expert Subset)\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
@@ -1123,7 +1158,7 @@
break;
default:
- FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
+ FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
@@ -1218,7 +1253,7 @@
break;
default:
- FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
+ FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
@@ -1236,7 +1271,8 @@
CFF_Index idx,
FT_UInt font_index,
FT_Stream stream,
- FT_ULong base_offset )
+ FT_ULong base_offset,
+ FT_Library library )
{
FT_Error error;
CFF_ParserRec parser;
@@ -1246,7 +1282,7 @@
CFF_Private priv = &font->private_dict;
- cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );
+ cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
/* set defaults */
FT_MEM_ZERO( top, sizeof ( *top ) );
@@ -1272,8 +1308,9 @@
top->cid_ordering = 0xFFFFU;
top->cid_font_name = 0xFFFFU;
- error = cff_index_access_element( idx, font_index, &dict, &dict_len ) ||
- cff_parser_run( &parser, dict, dict + dict_len );
+ error = cff_index_access_element( idx, font_index, &dict, &dict_len );
+ if ( !error )
+ error = cff_parser_run( &parser, dict, dict + dict_len );
cff_index_forget_element( idx, &dict );
@@ -1296,7 +1333,7 @@
priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
- cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
+ cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
FT_FRAME_ENTER( font->font_dict.private_size ) )
@@ -1349,9 +1386,11 @@
FT_LOCAL_DEF( FT_Error )
- cff_font_load( FT_Stream stream,
+ cff_font_load( FT_Library library,
+ FT_Stream stream,
FT_Int face_index,
- CFF_Font font )
+ CFF_Font font,
+ FT_Bool pure_cff )
{
static const FT_Frame_Field cff_header_fields[] =
{
@@ -1388,7 +1427,7 @@
font->header_size < 4 ||
font->absolute_offsize > 4 )
{
- FT_TRACE2(( "[not a CFF font header!]\n" ));
+ FT_TRACE2(( "[not a CFF font header]\n" ));
error = CFF_Err_Unknown_File_Format;
goto Exit;
}
@@ -1426,7 +1465,8 @@
&font->font_dict_index,
face_index,
stream,
- base_offset );
+ base_offset,
+ library );
if ( error )
goto Exit;
@@ -1456,7 +1496,7 @@
if ( fd_index.count > CFF_MAX_CID_FONTS )
{
- FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
+ FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
goto Fail_CID;
}
@@ -1474,7 +1514,7 @@
{
sub = font->subfonts[idx];
error = cff_subfont_load( sub, &fd_index, idx,
- stream, base_offset );
+ stream, base_offset, library );
if ( error )
goto Fail_CID;
}
@@ -1497,7 +1537,7 @@
/* read the charstrings index now */
if ( dict->charstrings_offset == 0 )
{
- FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
+ FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
error = CFF_Err_Unknown_File_Format;
goto Exit;
}
@@ -1515,7 +1555,7 @@
/* read the Charset and Encoding tables if available */
if ( font->num_glyphs > 0 )
{
- FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU );
+ FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
error = cff_charset_load( &font->charset, font->num_glyphs, stream,
@@ -1535,9 +1575,6 @@
if ( error )
goto Exit;
}
- else
- /* CID-keyed fonts only need CIDs */
- FT_FREE( font->charset.sids );
}
/* get the font name (/CIDFontName for CID-keyed fonts, */
@@ -1590,6 +1627,9 @@
FT_FREE( font->font_info );
}
+ FT_FREE( font->registry );
+ FT_FREE( font->ordering );
+
FT_FREE( font->global_subrs );
FT_FREE( font->font_name );
}
diff --git a/src/freetype2/cff/cffload.h b/src/freetype2/cff/cffload.h
index 068cbb5..2b313ac 100644
--- a/src/freetype2/cff/cffload.h
+++ b/src/freetype2/cff/cffload.h
@@ -4,7 +4,7 @@
/* */
/* OpenType & CFF data/program tables loader (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -58,9 +58,11 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
- cff_font_load( FT_Stream stream,
+ cff_font_load( FT_Library library,
+ FT_Stream stream,
FT_Int face_index,
- CFF_Font font );
+ CFF_Font font,
+ FT_Bool pure_cff );
FT_LOCAL( void )
cff_font_done( CFF_Font font );
diff --git a/src/freetype2/cff/cffobjs.c b/src/freetype2/cff/cffobjs.c
index c02cf33..e0966e0 100644
--- a/src/freetype2/cff/cffobjs.c
+++ b/src/freetype2/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, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -30,6 +30,7 @@
#include "cffload.h"
#include "cffcmap.h"
#include "cfferrs.h"
+#include "cffpic.h"
/*************************************************************************/
@@ -56,7 +57,7 @@
cff_size_get_globals_funcs( CFF_Size size )
{
CFF_Face face = (CFF_Face)size->root.face;
- CFF_Font font = (CFF_FontRec *)face->extra.data;
+ CFF_Font font = (CFF_Font)face->extra.data;
PSHinter_Service pshinter = (PSHinter_Service)font->pshinter;
FT_Module module;
@@ -72,23 +73,84 @@
FT_LOCAL_DEF( void )
cff_size_done( FT_Size cffsize ) /* CFF_Size */
{
- CFF_Size size = (CFF_Size)cffsize;
+ CFF_Size size = (CFF_Size)cffsize;
+ CFF_Face face = (CFF_Face)size->root.face;
+ CFF_Font font = (CFF_Font)face->extra.data;
+ CFF_Internal internal = (CFF_Internal)cffsize->internal;
- if ( cffsize->internal )
+ if ( internal )
{
PSH_Globals_Funcs funcs;
funcs = cff_size_get_globals_funcs( size );
if ( funcs )
- funcs->destroy( (PSH_Globals)cffsize->internal );
+ {
+ FT_UInt i;
+
+
+ funcs->destroy( internal->topfont );
+
+ for ( i = font->num_subfonts; i > 0; i-- )
+ funcs->destroy( internal->subfonts[i - 1] );
+ }
- cffsize->internal = 0;
+ /* `internal' is freed by destroy_size (in ftobjs.c) */
}
}
+ /* CFF and Type 1 private dictionaries have slightly different */
+ /* structures; we need to synthesize a Type 1 dictionary on the fly */
+
+ static void
+ cff_make_private_dict( CFF_SubFont subfont,
+ PS_Private priv )
+ {
+ CFF_Private cpriv = &subfont->private_dict;
+ FT_UInt n, count;
+
+
+ FT_MEM_ZERO( priv, sizeof ( *priv ) );
+
+ count = priv->num_blue_values = cpriv->num_blue_values;
+ for ( n = 0; n < count; n++ )
+ priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
+
+ count = priv->num_other_blues = cpriv->num_other_blues;
+ for ( n = 0; n < count; n++ )
+ priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
+
+ count = priv->num_family_blues = cpriv->num_family_blues;
+ for ( n = 0; n < count; n++ )
+ priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
+
+ count = priv->num_family_other_blues = cpriv->num_family_other_blues;
+ for ( n = 0; n < count; n++ )
+ priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
+
+ priv->blue_scale = cpriv->blue_scale;
+ priv->blue_shift = (FT_Int)cpriv->blue_shift;
+ priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz;
+
+ priv->standard_width[0] = (FT_UShort)cpriv->standard_width;
+ priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
+
+ count = priv->num_snap_widths = cpriv->num_snap_widths;
+ for ( n = 0; n < count; n++ )
+ priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
+
+ count = priv->num_snap_heights = cpriv->num_snap_heights;
+ for ( n = 0; n < count; n++ )
+ priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
+
+ priv->force_bold = cpriv->force_bold;
+ priv->language_group = cpriv->language_group;
+ priv->lenIV = cpriv->lenIV;
+ }
+
+
FT_LOCAL_DEF( FT_Error )
cff_size_init( FT_Size cffsize ) /* CFF_Size */
{
@@ -99,68 +161,43 @@
if ( funcs )
{
- PSH_Globals globals;
- CFF_Face face = (CFF_Face)cffsize->face;
- CFF_Font font = (CFF_FontRec *)face->extra.data;
- CFF_SubFont subfont = &font->top_font;
+ CFF_Face face = (CFF_Face)cffsize->face;
+ CFF_Font font = (CFF_Font)face->extra.data;
+ CFF_Internal internal;
- CFF_Private cpriv = &subfont->private_dict;
PS_PrivateRec priv;
+ FT_Memory memory = cffsize->face->memory;
+ FT_UInt i;
- /* IMPORTANT: The CFF and Type1 private dictionaries have */
- /* slightly different structures; we need to */
- /* synthetize a type1 dictionary on the fly here. */
-
- {
- FT_UInt n, count;
-
-
- FT_MEM_ZERO( &priv, sizeof ( priv ) );
-
- count = priv.num_blue_values = cpriv->num_blue_values;
- for ( n = 0; n < count; n++ )
- priv.blue_values[n] = (FT_Short)cpriv->blue_values[n];
-
- count = priv.num_other_blues = cpriv->num_other_blues;
- for ( n = 0; n < count; n++ )
- priv.other_blues[n] = (FT_Short)cpriv->other_blues[n];
- count = priv.num_family_blues = cpriv->num_family_blues;
- for ( n = 0; n < count; n++ )
- priv.family_blues[n] = (FT_Short)cpriv->family_blues[n];
-
- count = priv.num_family_other_blues = cpriv->num_family_other_blues;
- for ( n = 0; n < count; n++ )
- priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
-
- priv.blue_scale = cpriv->blue_scale;
- priv.blue_shift = (FT_Int)cpriv->blue_shift;
- priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz;
+ if ( FT_NEW( internal ) )
+ goto Exit;
- priv.standard_width[0] = (FT_UShort)cpriv->standard_width;
- priv.standard_height[0] = (FT_UShort)cpriv->standard_height;
+ cff_make_private_dict( &font->top_font, &priv );
+ error = funcs->create( cffsize->face->memory, &priv,
+ &internal->topfont );
+ if ( error )
+ goto Exit;
- count = priv.num_snap_widths = cpriv->num_snap_widths;
- for ( n = 0; n < count; n++ )
- priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
+ for ( i = font->num_subfonts; i > 0; i-- )
+ {
+ CFF_SubFont sub = font->subfonts[i - 1];
- count = priv.num_snap_heights = cpriv->num_snap_heights;
- for ( n = 0; n < count; n++ )
- priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
- priv.force_bold = cpriv->force_bold;
- priv.language_group = cpriv->language_group;
- priv.lenIV = cpriv->lenIV;
+ cff_make_private_dict( sub, &priv );
+ error = funcs->create( cffsize->face->memory, &priv,
+ &internal->subfonts[i - 1] );
+ if ( error )
+ goto Exit;
}
- error = funcs->create( cffsize->face->memory, &priv, &globals );
- if ( !error )
- cffsize->internal = (FT_Size_Internal)(void*)globals;
+ cffsize->internal = (FT_Size_Internal)(void*)internal;
}
size->strike_index = 0xFFFFFFFFUL;
+ Exit:
return error;
}
@@ -182,11 +219,42 @@
funcs = cff_size_get_globals_funcs( cffsize );
if ( funcs )
- funcs->set_scale( (PSH_Globals)size->internal,
- size->metrics.x_scale,
- size->metrics.y_scale,
+ {
+ CFF_Face face = (CFF_Face)size->face;
+ CFF_Font font = (CFF_Font)face->extra.data;
+ CFF_Internal internal = (CFF_Internal)size->internal;
+
+ FT_ULong top_upm = font->top_font.font_dict.units_per_em;
+ FT_UInt i;
+
+
+ funcs->set_scale( internal->topfont,
+ size->metrics.x_scale, size->metrics.y_scale,
0, 0 );
+ for ( i = font->num_subfonts; i > 0; i-- )
+ {
+ CFF_SubFont sub = font->subfonts[i - 1];
+ FT_ULong sub_upm = sub->font_dict.units_per_em;
+ FT_Pos x_scale, y_scale;
+
+
+ if ( top_upm != sub_upm )
+ {
+ x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
+ y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
+ }
+ else
+ {
+ x_scale = size->metrics.x_scale;
+ y_scale = size->metrics.y_scale;
+ }
+
+ funcs->set_scale( internal->subfonts[i - 1],
+ x_scale, y_scale, 0, 0 );
+ }
+ }
+
return CFF_Err_Ok;
}
@@ -223,11 +291,42 @@
funcs = cff_size_get_globals_funcs( cffsize );
if ( funcs )
- funcs->set_scale( (PSH_Globals)size->internal,
- size->metrics.x_scale,
- size->metrics.y_scale,
+ {
+ CFF_Face cffface = (CFF_Face)size->face;
+ CFF_Font font = (CFF_Font)cffface->extra.data;
+ CFF_Internal internal = (CFF_Internal)size->internal;
+
+ FT_ULong top_upm = font->top_font.font_dict.units_per_em;
+ FT_UInt i;
+
+
+ funcs->set_scale( internal->topfont,
+ size->metrics.x_scale, size->metrics.y_scale,
0, 0 );
+ for ( i = font->num_subfonts; i > 0; i-- )
+ {
+ CFF_SubFont sub = font->subfonts[i - 1];
+ FT_ULong sub_upm = sub->font_dict.units_per_em;
+ FT_Pos x_scale, y_scale;
+
+
+ if ( top_upm != sub_upm )
+ {
+ x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
+ y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
+ }
+ else
+ {
+ x_scale = size->metrics.x_scale;
+ y_scale = size->metrics.y_scale;
+ }
+
+ funcs->set_scale( internal->subfonts[i - 1],
+ x_scale, y_scale, 0, 0 );
+ }
+ }
+
return CFF_Err_Ok;
}
@@ -249,7 +348,7 @@
cff_slot_init( FT_GlyphSlot slot )
{
CFF_Face face = (CFF_Face)slot->face;
- CFF_Font font = (CFF_FontRec *)face->extra.data;
+ CFF_Font font = (CFF_Font)face->extra.data;
PSHinter_Service pshinter = (PSHinter_Service)font->pshinter;
@@ -270,7 +369,7 @@
}
}
- return 0;
+ return CFF_Err_Ok;
}
@@ -288,7 +387,9 @@
FT_String* result;
- result = ft_mem_strdup( memory, source, &error );
+ (void)FT_STRDUP( result, source );
+
+ FT_UNUSED( error );
return result;
}
@@ -308,6 +409,7 @@
PSHinter_Service pshinter;
FT_Bool pure_cff = 1;
FT_Bool sfnt_format = 0;
+ FT_Library library = cffface->driver->root.library;
#if 0
@@ -319,14 +421,14 @@
goto Bad_Format;
#else
sfnt = (SFNT_Service)FT_Get_Module_Interface(
- cffface->driver->root.library, "sfnt" );
+ library, "sfnt" );
if ( !sfnt )
goto Bad_Format;
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
pshinter = (PSHinter_Service)FT_Get_Module_Interface(
- cffface->driver->root.library, "pshinter" );
+ library, "pshinter" );
#endif
/* create input stream from resource */
@@ -337,7 +439,7 @@
error = sfnt->init_face( stream, face, face_index, num_params, params );
if ( !error )
{
- if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */
+ if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */
{
FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
goto Bad_Format;
@@ -365,8 +467,7 @@
pure_cff = 0;
/* load font directory */
- error = sfnt->load_face( stream, face,
- face_index, num_params, params );
+ error = sfnt->load_face( stream, face, 0, num_params, params );
if ( error )
goto Exit;
}
@@ -408,13 +509,15 @@
goto Exit;
face->extra.data = cff;
- error = cff_font_load( stream, face_index, cff );
+ error = cff_font_load( library, stream, face_index, cff, pure_cff );
if ( error )
goto Exit;
cff->pshinter = pshinter;
cff->psnames = (void*)psnames;
+ cffface->face_index = face_index;
+
/* Complement the root flags with some interesting information. */
/* Note that this is only necessary for pure CFF and CEF fonts; */
/* SFNT based fonts use the `name' table instead. */
@@ -427,13 +530,118 @@
/* which aren't CID-keyed */
if ( dict->cid_registry == 0xFFFFU && !psnames )
{
- FT_ERROR(( "cff_face_init:" ));
- FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
- FT_ERROR(( " " ));
- FT_ERROR(( " without the `PSNames' module\n" ));
+ FT_ERROR(( "cff_face_init:"
+ " cannot open CFF & CEF fonts\n"
+ " "
+ " without the `PSNames' module\n" ));
goto Bad_Format;
}
+ if ( !dict->units_per_em )
+ dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
+
+ /* Normalize the font matrix so that `matrix->xx' is 1; the */
+ /* scaling is done with `units_per_em' then (at this point, */
+ /* it already contains the scaling factor, but without */
+ /* normalization of the matrix). */
+ /* */
+ /* Note that the offsets must be expressed in integer font */
+ /* units. */
+
+ {
+ FT_Matrix* matrix = &dict->font_matrix;
+ FT_Vector* offset = &dict->font_offset;
+ FT_ULong* upm = &dict->units_per_em;
+ FT_Fixed temp = FT_ABS( matrix->yy );
+
+
+ if ( temp != 0x10000L )
+ {
+ *upm = FT_DivFix( *upm, temp );
+
+ matrix->xx = FT_DivFix( matrix->xx, temp );
+ matrix->yx = FT_DivFix( matrix->yx, temp );
+ matrix->xy = FT_DivFix( matrix->xy, temp );
+ matrix->yy = FT_DivFix( matrix->yy, temp );
+ offset->x = FT_DivFix( offset->x, temp );
+ offset->y = FT_DivFix( offset->y, temp );
+ }
+
+ offset->x >>= 16;
+ offset->y >>= 16;
+ }
+
+ for ( i = cff->num_subfonts; i > 0; i-- )
+ {
+ CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
+ CFF_FontRecDict top = &cff->top_font.font_dict;
+
+ FT_Matrix* matrix;
+ FT_Vector* offset;
+ FT_ULong* upm;
+ FT_Fixed temp;
+
+
+ if ( sub->units_per_em )
+ {
+ FT_Long scaling;
+
+
+ if ( top->units_per_em > 1 && sub->units_per_em > 1 )
+ scaling = FT_MIN( top->units_per_em, sub->units_per_em );
+ else
+ scaling = 1;
+
+ FT_Matrix_Multiply_Scaled( &top->font_matrix,
+ &sub->font_matrix,
+ scaling );
+ FT_Vector_Transform_Scaled( &sub->font_offset,
+ &top->font_matrix,
+ scaling );
+
+ sub->units_per_em = FT_MulDiv( sub->units_per_em,
+ top->units_per_em,
+ scaling );
+ }
+ else
+ {
+ sub->font_matrix = top->font_matrix;
+ sub->font_offset = top->font_offset;
+
+ sub->units_per_em = top->units_per_em;
+ }
+
+ matrix = &sub->font_matrix;
+ offset = &sub->font_offset;
+ upm = &sub->units_per_em;
+ temp = FT_ABS( matrix->yy );
+
+ if ( temp != 0x10000L )
+ {
+ *upm = FT_DivFix( *upm, temp );
+
+ /* if *upm is larger than 100*1000 we divide by 1000 -- */
+ /* this can happen if e.g. there is no top-font FontMatrix */
+ /* and the subfont FontMatrix already contains the complete */
+ /* scaling for the subfont (see section 5.11 of the PLRM) */
+
+ /* 100 is a heuristic value */
+
+ if ( *upm > 100L * 1000L )
+ *upm = ( *upm + 500 ) / 1000;
+
+ matrix->xx = FT_DivFix( matrix->xx, temp );
+ matrix->yx = FT_DivFix( matrix->yx, temp );
+ matrix->xy = FT_DivFix( matrix->xy, temp );
+ matrix->yy = FT_DivFix( matrix->yy, temp );
+ offset->x = FT_DivFix( offset->x, temp );
+ offset->y = FT_DivFix( offset->y, temp );
+ }
+
+ offset->x >>= 16;
+ offset->y >>= 16;
+ }
+
if ( pure_cff )
{
char* style_name = NULL;
@@ -444,7 +652,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;
@@ -454,10 +662,7 @@
cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
- if ( !dict->units_per_em )
- dict->units_per_em = 1000;
-
- cffface->units_per_EM = dict->units_per_em;
+ cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
cffface->ascender = (FT_Short)( cffface->bbox.yMax );
cffface->descender = (FT_Short)( cffface->bbox.yMin );
@@ -561,22 +766,22 @@
/* */
/* Compute face flags. */
/* */
- flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
- FT_FACE_FLAG_HORIZONTAL | /* horizontal data */
- FT_FACE_FLAG_HINTER; /* has native hinter */
+ flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */
+ FT_FACE_FLAG_HORIZONTAL | /* horizontal data */
+ FT_FACE_FLAG_HINTER ); /* has native hinter */
if ( sfnt_format )
- flags |= FT_FACE_FLAG_SFNT;
+ flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;
/* fixed width font? */
if ( dict->is_fixed_pitch )
- flags |= FT_FACE_FLAG_FIXED_WIDTH;
+ flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;
/* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
#if 0
/* kerning available? */
if ( face->kern_pairs )
- flags |= FT_FACE_FLAG_KERNING;
+ flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;
#endif
cffface->face_flags = flags;
@@ -611,51 +816,25 @@
cffface->style_flags = flags;
}
- else
- {
- if ( !dict->units_per_em )
- dict->units_per_em = face->root.units_per_EM;
- }
-
- /* handle font matrix settings in subfonts (if any) */
- for ( i = cff->num_subfonts; i > 0; i-- )
- {
- CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
- CFF_FontRecDict top = &cff->top_font.font_dict;
- if ( sub->units_per_em )
- {
- FT_Matrix scale;
-
-
- scale.xx = scale.yy = (FT_Fixed)FT_DivFix( top->units_per_em,
- sub->units_per_em );
- scale.xy = scale.yx = 0;
-
- FT_Matrix_Multiply( &scale, &sub->font_matrix );
- FT_Vector_Transform( &sub->font_offset, &scale );
- }
- else
- {
- sub->font_matrix = top->font_matrix;
- sub->font_offset = top->font_offset;
- }
- }
-
#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 && pure_cff )
+ cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
+
+
/*******************************************************************/
/* */
/* Compute char maps. */
/* */
- /* Try to synthetize a Unicode charmap if there is none available */
+ /* Try to synthesize a Unicode charmap if there is none available */
/* already. If an OpenType font contains a Unicode "cmap", we */
/* will use it, whatever be in the CFF part of the file. */
{
@@ -683,7 +862,7 @@
if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
goto Exit;
- /* we didn't find a Unicode charmap -- synthetize one */
+ /* we didn't find a Unicode charmap -- synthesize one */
cmaprec.face = cffface;
cmaprec.platform_id = 3;
cmaprec.encoding_id = 1;
@@ -691,7 +870,7 @@
nn = (FT_UInt)cffface->num_charmaps;
- FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL );
+ FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL );
/* if no Unicode charmap was previously selected, select this one */
if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
@@ -710,19 +889,19 @@
{
cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD;
- clazz = &cff_cmap_encoding_class_rec;
+ clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
}
else if ( encoding->offset == 1 )
{
cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT;
- clazz = &cff_cmap_encoding_class_rec;
+ clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
}
else
{
cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM;
- clazz = &cff_cmap_encoding_class_rec;
+ clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
}
FT_CMap_New( clazz, NULL, &cmaprec, NULL );
@@ -742,10 +921,16 @@
FT_LOCAL_DEF( void )
cff_face_done( FT_Face cffface ) /* CFF_Face */
{
- CFF_Face face = (CFF_Face)cffface;
- FT_Memory memory = cffface->memory;
- SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+ CFF_Face face = (CFF_Face)cffface;
+ FT_Memory memory;
+ SFNT_Service sfnt;
+
+
+ if ( !face )
+ return;
+ memory = cffface->memory;
+ sfnt = (SFNT_Service)face->sfnt;
if ( sfnt )
sfnt->done_face( face );
diff --git a/src/freetype2/cff/cffobjs.h b/src/freetype2/cff/cffobjs.h
index f18b5d9..3c81cee 100644
--- a/src/freetype2/cff/cffobjs.h
+++ b/src/freetype2/cff/cffobjs.h
@@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -25,6 +25,7 @@
#include "cfftypes.h"
#include FT_INTERNAL_TRUETYPE_TYPES_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+#include FT_INTERNAL_POSTSCRIPT_HINTS_H
FT_BEGIN_HEADER
@@ -53,8 +54,8 @@ FT_BEGIN_HEADER
/* */
typedef struct CFF_SizeRec_
{
- FT_SizeRec root;
- FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */
+ FT_SizeRec root;
+ FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */
} CFF_SizeRec, *CFF_Size;
@@ -80,6 +81,21 @@ FT_BEGIN_HEADER
} CFF_GlyphSlotRec, *CFF_GlyphSlot;
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* CFF_Internal */
+ /* */
+ /* <Description> */
+ /* The interface to the `internal' field of `FT_Size'. */
+ /* */
+ typedef struct CFF_InternalRec_
+ {
+ PSH_Globals topfont;
+ PSH_Globals subfonts[CFF_MAX_CID_FONTS];
+
+ } CFF_InternalRec, *CFF_Internal;
+
/*************************************************************************/
/* */
diff --git a/src/freetype2/cff/cffparse.c b/src/freetype2/cff/cffparse.c
index 41af6a3..947ec9d 100644
--- a/src/freetype2/cff/cffparse.c
+++ b/src/freetype2/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, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -19,8 +19,10 @@
#include <ft2build.h>
#include "cffparse.h"
#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_DEBUG_H
#include "cfferrs.h"
+#include "cffpic.h"
/*************************************************************************/
@@ -33,47 +35,20 @@
#define FT_COMPONENT trace_cffparse
- enum
- {
- cff_kind_none = 0,
- cff_kind_num,
- cff_kind_fixed,
- cff_kind_fixed_thousand,
- cff_kind_string,
- cff_kind_bool,
- cff_kind_delta,
- cff_kind_callback,
-
- cff_kind_max /* do not remove */
- };
-
-
- /* now generate handlers for the most simple fields */
- typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser );
-
- typedef struct CFF_Field_Handler_
- {
- int kind;
- int code;
- FT_UInt offset;
- FT_Byte size;
- CFF_Field_Reader reader;
- FT_UInt array_max;
- FT_UInt count_offset;
-
- } CFF_Field_Handler;
FT_LOCAL_DEF( void )
cff_parser_init( CFF_Parser parser,
FT_UInt code,
- void* object )
+ void* object,
+ FT_Library library)
{
FT_MEM_ZERO( parser, sizeof ( *parser ) );
parser->top = parser->stack;
parser->object_code = code;
parser->object = object;
+ parser->library = library;
}
@@ -136,24 +111,53 @@
}
+ static const FT_Long power_tens[] =
+ {
+ 1L,
+ 10L,
+ 100L,
+ 1000L,
+ 10000L,
+ 100000L,
+ 1000000L,
+ 10000000L,
+ 100000000L,
+ 1000000000L
+ };
+
+
/* read a real */
static FT_Fixed
cff_parse_real( FT_Byte* start,
FT_Byte* limit,
- FT_Int power_ten )
+ FT_Long power_ten,
+ FT_Long* scaling )
{
- FT_Byte* p = start;
- FT_Long num, divider, result, exponent;
- FT_Int sign = 0, exponent_sign = 0;
+ FT_Byte* p = start;
FT_UInt nib;
FT_UInt phase;
+ FT_Long result, number, rest, exponent;
+ FT_Int sign = 0, exponent_sign = 0;
+ FT_Long exponent_add, integer_length, fraction_length;
+
+
+ if ( scaling )
+ *scaling = 0;
+
+ result = 0;
+
+ number = 0;
+ rest = 0;
+ exponent = 0;
- result = 0;
- num = 0;
- divider = 1;
+ exponent_add = 0;
+ integer_length = 0;
+ fraction_length = 0;
- /* first of all, read the integer part */
+ FT_UNUSED( rest );
+
+ /* First of all, read the integer part. */
phase = 4;
for (;;)
@@ -166,7 +170,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Bad;
+ goto Exit;
}
/* Get the nibble. */
@@ -178,10 +182,20 @@
else if ( nib > 9 )
break;
else
- result = result * 10 + nib;
+ {
+ /* Increase exponent if we can't add the digit. */
+ if ( number >= 0xCCCCCCCL )
+ exponent_add++;
+ /* Skip leading zeros. */
+ else if ( nib || number )
+ {
+ integer_length++;
+ number = number * 10 + nib;
+ }
+ }
}
- /* read decimal part, if any */
+ /* Read fraction part, if any. */
if ( nib == 0xa )
for (;;)
{
@@ -193,7 +207,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Bad;
+ goto Exit;
}
/* Get the nibble. */
@@ -202,14 +216,18 @@
if ( nib >= 10 )
break;
- if ( divider < 10000000L )
+ /* Skip leading zeros if possible. */
+ if ( !nib && !number )
+ exponent_add--;
+ /* Only add digit if we don't overflow. */
+ else if ( number < 0xCCCCCCCL && fraction_length < 9 )
{
- num = num * 10 + nib;
- divider *= 10;
+ fraction_length++;
+ number = number * 10 + nib;
}
}
- /* read exponent, if any */
+ /* Read exponent, if any. */
if ( nib == 12 )
{
exponent_sign = 1;
@@ -218,19 +236,17 @@
if ( nib == 11 )
{
- exponent = 0;
-
for (;;)
{
- /* If we entered this iteration with phase == 4, we need */
- /* to read a new byte. */
+ /* If we entered this iteration with phase == 4, */
+ /* we need to read a new byte. */
if ( phase )
{
p++;
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Bad;
+ goto Exit;
}
/* Get the nibble. */
@@ -240,47 +256,111 @@
break;
exponent = exponent * 10 + nib;
+
+ /* Arbitrarily limit exponent. */
+ if ( exponent > 1000 )
+ goto Exit;
}
if ( exponent_sign )
exponent = -exponent;
-
- power_ten += (FT_Int)exponent;
}
- /* raise to power of ten if needed */
- while ( power_ten > 0 )
+ /* We don't check `power_ten' and `exponent_add'. */
+ exponent += power_ten + exponent_add;
+
+ if ( scaling )
{
- result = result * 10;
- num = num * 10;
+ /* Only use `fraction_length'. */
+ fraction_length += integer_length;
+ exponent += integer_length;
- power_ten--;
- }
+ if ( fraction_length <= 5 )
+ {
+ if ( number > 0x7FFFL )
+ {
+ result = FT_DivFix( number, 10 );
+ *scaling = exponent - fraction_length + 1;
+ }
+ else
+ {
+ if ( exponent > 0 )
+ {
+ FT_Long new_fraction_length, shift;
- while ( power_ten < 0 )
- {
- result = result / 10;
- divider = divider * 10;
- power_ten++;
+ /* Make `scaling' as small as possible. */
+ new_fraction_length = FT_MIN( exponent, 5 );
+ exponent -= new_fraction_length;
+ shift = new_fraction_length - fraction_length;
+
+ number *= power_tens[shift];
+ if ( number > 0x7FFFL )
+ {
+ number /= 10;
+ exponent += 1;
+ }
+ }
+ else
+ exponent -= fraction_length;
+
+ result = number << 16;
+ *scaling = exponent;
+ }
+ }
+ else
+ {
+ if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
+ {
+ result = FT_DivFix( number, power_tens[fraction_length - 4] );
+ *scaling = exponent - 4;
+ }
+ else
+ {
+ result = FT_DivFix( number, power_tens[fraction_length - 5] );
+ *scaling = exponent - 5;
+ }
+ }
}
+ else
+ {
+ integer_length += exponent;
+ fraction_length -= exponent;
+
+ /* Check for overflow and underflow. */
+ if ( FT_ABS( integer_length ) > 5 )
+ goto Exit;
+
+ /* Remove non-significant digits. */
+ if ( integer_length < 0 ) {
+ number /= power_tens[-integer_length];
+ fraction_length += integer_length;
+ }
+
+ /* Convert into 16.16 format. */
+ if ( fraction_length > 0 )
+ {
+ if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
+ goto Exit;
+
+ result = FT_DivFix( number, power_tens[fraction_length] );
+ }
+ else
+ {
+ number *= power_tens[-fraction_length];
- /* Move the integer part into the high 16 bits. */
- result <<= 16;
+ if ( number > 0x7FFFL )
+ goto Exit;
- /* Place the decimal part into the low 16 bits. */
- if ( num )
- result |= FT_DivFix( num, divider );
+ result = number << 16;
+ }
+ }
if ( sign )
result = -result;
Exit:
return result;
-
- Bad:
- result = 0;
- goto Exit;
}
@@ -288,8 +368,8 @@
static FT_Long
cff_parse_num( FT_Byte** d )
{
- return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 )
- : cff_parse_integer( d[0], d[1] ) );
+ return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
+ : cff_parse_integer( d[0], d[1] );
}
@@ -297,64 +377,120 @@
static FT_Fixed
cff_parse_fixed( FT_Byte** d )
{
- return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 )
- : cff_parse_integer( d[0], d[1] ) << 16 );
+ return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
+ : cff_parse_integer( d[0], d[1] ) << 16;
}
+
/* read a floating point number, either integer or real, */
- /* but return 1000 times the number read in. */
+ /* but return `10^scaling' times the number read in */
+ static FT_Fixed
+ cff_parse_fixed_scaled( FT_Byte** d,
+ FT_Long scaling )
+ {
+ return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
+ : ( cff_parse_integer( d[0], d[1] ) *
+ power_tens[scaling] ) << 16;
+ }
+
+
+ /* read a floating point number, either integer or real, */
+ /* and return it as precise as possible -- `scaling' returns */
+ /* the scaling factor (as a power of 10) */
static FT_Fixed
- cff_parse_fixed_thousand( FT_Byte** d )
+ cff_parse_fixed_dynamic( FT_Byte** d,
+ FT_Long* scaling )
{
- return **d ==
- 30 ? cff_parse_real ( d[0], d[1], 3 )
- : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 );
+ FT_ASSERT( scaling );
+
+ if ( **d == 30 )
+ return cff_parse_real( d[0], d[1], 0, scaling );
+ else
+ {
+ FT_Long number;
+ FT_Int integer_length;
+
+
+ number = cff_parse_integer( d[0], d[1] );
+
+ if ( number > 0x7FFFL )
+ {
+ for ( integer_length = 5; integer_length < 10; integer_length++ )
+ if ( number < power_tens[integer_length] )
+ break;
+
+ if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
+ {
+ *scaling = integer_length - 4;
+ return FT_DivFix( number, power_tens[integer_length - 4] );
+ }
+ else
+ {
+ *scaling = integer_length - 5;
+ return FT_DivFix( number, power_tens[integer_length - 5] );
+ }
+ }
+ else
+ {
+ *scaling = 0;
+ return number << 16;
+ }
+ }
}
+
static FT_Error
cff_parse_font_matrix( CFF_Parser parser )
{
CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
FT_Matrix* matrix = &dict->font_matrix;
FT_Vector* offset = &dict->font_offset;
- FT_UShort* upm = &dict->units_per_em;
+ FT_ULong* upm = &dict->units_per_em;
FT_Byte** data = parser->stack;
- FT_Error error;
- FT_Fixed temp;
+ FT_Error error = CFF_Err_Stack_Underflow;
- error = CFF_Err_Stack_Underflow;
-
if ( parser->top >= parser->stack + 6 )
{
- matrix->xx = cff_parse_fixed_thousand( data++ );
- matrix->yx = cff_parse_fixed_thousand( data++ );
- matrix->xy = cff_parse_fixed_thousand( data++ );
- matrix->yy = cff_parse_fixed_thousand( data++ );
- offset->x = cff_parse_fixed_thousand( data++ );
- offset->y = cff_parse_fixed_thousand( data );
+ FT_Long scaling;
- temp = FT_ABS( matrix->yy );
- *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
+ error = CFF_Err_Ok;
+
+ /* We expect a well-formed font matrix, this is, the matrix elements */
+ /* `xx' and `yy' are of approximately the same magnitude. To avoid */
+ /* loss of precision, we use the magnitude of element `xx' to scale */
+ /* all other elements. The scaling factor is then contained in the */
+ /* `units_per_em' value. */
- if ( temp != 0x10000L )
+ matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
+
+ scaling = -scaling;
+
+ if ( scaling < 0 || scaling > 9 )
{
- matrix->xx = FT_DivFix( matrix->xx, temp );
- matrix->yx = FT_DivFix( matrix->yx, temp );
- matrix->xy = FT_DivFix( matrix->xy, temp );
- matrix->yy = FT_DivFix( matrix->yy, temp );
- offset->x = FT_DivFix( offset->x, temp );
- offset->y = FT_DivFix( offset->y, temp );
+ /* Return default matrix in case of unlikely values. */
+ matrix->xx = 0x10000L;
+ matrix->yx = 0;
+ matrix->yx = 0;
+ matrix->yy = 0x10000L;
+ offset->x = 0;
+ offset->y = 0;
+ *upm = 1;
+
+ goto Exit;
}
- /* note that the offsets must be expressed in integer font units */
- offset->x >>= 16;
- offset->y >>= 16;
+ matrix->yx = cff_parse_fixed_scaled( data++, scaling );
+ matrix->xy = cff_parse_fixed_scaled( data++, scaling );
+ matrix->yy = cff_parse_fixed_scaled( data++, scaling );
+ offset->x = cff_parse_fixed_scaled( data++, scaling );
+ offset->y = cff_parse_fixed_scaled( data, scaling );
- error = CFF_Err_Ok;
+ *upm = power_tens[scaling];
}
+ Exit:
return error;
}
@@ -418,7 +554,12 @@
{
dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
- dict->cid_supplement = (FT_ULong)cff_parse_num( data );
+ if ( **data == 30 )
+ FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
+ dict->cid_supplement = cff_parse_num( data );
+ if ( dict->cid_supplement < 0 )
+ FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
+ dict->cid_supplement ));
error = CFF_Err_Ok;
}
@@ -439,6 +580,11 @@
#define CFF_FIELD_DELTA( code, name, max ) \
CFF_FIELD( code, name, cff_kind_delta )
+#define CFFCODE_TOPDICT 0x1000
+#define CFFCODE_PRIVATE 0x2000
+
+#ifndef FT_CONFIG_OPTION_PIC
+
#define CFF_FIELD_CALLBACK( code, name ) \
{ \
cff_kind_callback, \
@@ -470,9 +616,6 @@
FT_FIELD_OFFSET( num_ ## name ) \
},
-#define CFFCODE_TOPDICT 0x1000
-#define CFFCODE_PRIVATE 0x2000
-
static const CFF_Field_Handler cff_field_handlers[] =
{
@@ -482,13 +625,99 @@
};
+#else /* FT_CONFIG_OPTION_PIC */
+
+ void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
+ {
+ FT_Memory memory = library->memory;
+ if ( clazz )
+ FT_FREE( clazz );
+ }
+
+ FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
+ {
+ CFF_Field_Handler* clazz;
+ FT_Error error;
+ FT_Memory memory = library->memory;
+ int i=0;
+
+#undef CFF_FIELD
+#undef CFF_FIELD_DELTA
+#undef CFF_FIELD_CALLBACK
+#define CFF_FIELD_CALLBACK( code, name ) i++;
+#define CFF_FIELD( code, name, kind ) i++;
+#define CFF_FIELD_DELTA( code, name, max ) i++;
+
+#include "cfftoken.h"
+ i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
+
+ if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
+ return error;
+
+ i=0;
+#undef CFF_FIELD
+#undef CFF_FIELD_DELTA
+#undef CFF_FIELD_CALLBACK
+
+#define CFF_FIELD_CALLBACK( code_, name_ ) \
+ clazz[i].kind = cff_kind_callback; \
+ clazz[i].code = code_ | CFFCODE; \
+ clazz[i].offset = 0; \
+ clazz[i].size = 0; \
+ clazz[i].reader = cff_parse_ ## name_; \
+ clazz[i].array_max = 0; \
+ clazz[i].count_offset = 0; \
+ i++;
+
+#undef CFF_FIELD
+#define CFF_FIELD( code_, name_, kind_ ) \
+ clazz[i].kind = kind_; \
+ clazz[i].code = code_ | CFFCODE; \
+ clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
+ clazz[i].size = FT_FIELD_SIZE( name_ ); \
+ clazz[i].reader = 0; \
+ clazz[i].array_max = 0; \
+ clazz[i].count_offset = 0; \
+ i++; \
+
+#undef CFF_FIELD_DELTA
+#define CFF_FIELD_DELTA( code_, name_, max_ ) \
+ clazz[i].kind = cff_kind_delta; \
+ clazz[i].code = code_ | CFFCODE; \
+ clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
+ clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
+ clazz[i].reader = 0; \
+ clazz[i].array_max = max_; \
+ clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
+ i++;
+
+#include "cfftoken.h"
+
+ clazz[i].kind = 0;
+ clazz[i].code = 0;
+ clazz[i].offset = 0;
+ clazz[i].size = 0;
+ clazz[i].reader = 0;
+ clazz[i].array_max = 0;
+ clazz[i].count_offset = 0;
+
+ *output_class = clazz;
+ return FT_Err_Ok;
+ }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
FT_LOCAL_DEF( FT_Error )
cff_parser_run( CFF_Parser parser,
FT_Byte* start,
FT_Byte* limit )
{
- FT_Byte* p = start;
- FT_Error error = CFF_Err_Ok;
+ FT_Byte* p = start;
+ FT_Error error = CFF_Err_Ok;
+ FT_Library library = parser->library;
+ FT_UNUSED(library);
parser->top = parser->stack;
@@ -558,7 +787,7 @@
}
code = code | parser->object_code;
- for ( field = cff_field_handlers; field->kind; field++ )
+ for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
{
if ( field->code == (FT_Int)code )
{
@@ -585,7 +814,7 @@
goto Store_Number;
case cff_kind_fixed_thousand:
- val = cff_parse_fixed_thousand( parser->stack );
+ val = cff_parse_fixed_scaled( parser->stack, 3 );
Store_Number:
switch ( field->size )
diff --git a/src/freetype2/cff/cffparse.h b/src/freetype2/cff/cffparse.h
index 8f3fa58..7e2c00a 100644
--- a/src/freetype2/cff/cffparse.h
+++ b/src/freetype2/cff/cffparse.h
@@ -36,6 +36,7 @@ FT_BEGIN_HEADER
typedef struct CFF_ParserRec_
{
+ FT_Library library;
FT_Byte* start;
FT_Byte* limit;
FT_Byte* cursor;
@@ -52,7 +53,8 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
cff_parser_init( CFF_Parser parser,
FT_UInt code,
- void* object );
+ void* object,
+ FT_Library library);
FT_LOCAL( FT_Error )
cff_parser_run( CFF_Parser parser,
@@ -60,6 +62,37 @@ FT_BEGIN_HEADER
FT_Byte* limit );
+ enum
+ {
+ cff_kind_none = 0,
+ cff_kind_num,
+ cff_kind_fixed,
+ cff_kind_fixed_thousand,
+ cff_kind_string,
+ cff_kind_bool,
+ cff_kind_delta,
+ cff_kind_callback,
+
+ cff_kind_max /* do not remove */
+ };
+
+
+ /* now generate handlers for the most simple fields */
+ typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser );
+
+ typedef struct CFF_Field_Handler_
+ {
+ int kind;
+ int code;
+ FT_UInt offset;
+ FT_Byte size;
+ CFF_Field_Reader reader;
+ FT_UInt array_max;
+ FT_UInt count_offset;
+
+ } CFF_Field_Handler;
+
+
FT_END_HEADER
diff --git a/src/freetype2/cff/cffpic.c b/src/freetype2/cff/cffpic.c
new file mode 100644
index 0000000..568956d
--- /dev/null
+++ b/src/freetype2/cff/cffpic.c
@@ -0,0 +1,99 @@
+/***************************************************************************/
+/* */
+/* cffpic.c */
+/* */
+/* The FreeType position independent code services for cff module. */
+/* */
+/* Copyright 2009 by */
+/* Oran Agra and Mickey Gabel. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "cffpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+ /* forward declaration of PIC init functions from cffdrivr.c */
+ FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**);
+ void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*);
+ void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*);
+ void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*);
+ void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*);
+ void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*);
+ void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*);
+
+ /* forward declaration of PIC init functions from cffparse.c */
+ FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**);
+ void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*);
+
+ /* forward declaration of PIC init functions from cffcmap.c */
+ void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*);
+ void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*);
+
+ void
+ cff_driver_class_pic_free( FT_Library library )
+ {
+ FT_PIC_Container* pic_container = &library->pic_container;
+ FT_Memory memory = library->memory;
+ if ( pic_container->cff )
+ {
+ CffModulePIC* container = (CffModulePIC*)pic_container->cff;
+ if(container->cff_services)
+ FT_Destroy_Class_cff_services(library, container->cff_services);
+ container->cff_services = NULL;
+ if(container->cff_field_handlers)
+ FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers);
+ container->cff_field_handlers = NULL;
+ FT_FREE( container );
+ pic_container->cff = NULL;
+ }
+ }
+
+ FT_Error
+ cff_driver_class_pic_init( FT_Library library )
+ {
+ FT_PIC_Container* pic_container = &library->pic_container;
+ FT_Error error = FT_Err_Ok;
+ CffModulePIC* container;
+ FT_Memory memory = library->memory;
+
+ /* allocate pointer, clear and set global container pointer */
+ if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ return error;
+ FT_MEM_SET( container, 0, sizeof(*container) );
+ pic_container->cff = container;
+
+ /* initialize pointer table - this is how the module usually expects this data */
+ error = FT_Create_Class_cff_services(library, &container->cff_services);
+ if(error)
+ goto Exit;
+ error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers);
+ if(error)
+ goto Exit;
+ FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info);
+ FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict);
+ FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name);
+ FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info);
+ FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info);
+ FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec);
+ FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec);
+Exit:
+ if(error)
+ cff_driver_class_pic_free(library);
+ return error;
+ }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/freetype2/cff/cffpic.h b/src/freetype2/cff/cffpic.h
new file mode 100644
index 0000000..e29d068
--- /dev/null
+++ b/src/freetype2/cff/cffpic.h
@@ -0,0 +1,80 @@
+/***************************************************************************/
+/* */
+/* cffpic.h */
+/* */
+/* The FreeType position independent code services for cff module. */
+/* */
+/* Copyright 2009 by */
+/* Oran Agra and Mickey Gabel. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CFFPIC_H__
+#define __CFFPIC_H__
+
+
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+#define FT_CFF_SERVICE_PS_INFO_GET cff_service_ps_info
+#define FT_CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict
+#define FT_CFF_SERVICE_PS_NAME_GET cff_service_ps_name
+#define FT_CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info
+#define FT_CFF_SERVICE_CID_INFO_GET cff_service_cid_info
+#define FT_CFF_SERVICES_GET cff_services
+#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec
+#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec
+#define FT_CFF_FIELD_HANDLERS_GET cff_field_handlers
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include FT_SERVICE_GLYPH_DICT_H
+#include "cffparse.h"
+#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
+#include FT_SERVICE_TT_CMAP_H
+#include FT_SERVICE_CID_H
+
+ typedef struct CffModulePIC_
+ {
+ FT_ServiceDescRec* cff_services;
+ CFF_Field_Handler* cff_field_handlers;
+ FT_Service_PsInfoRec cff_service_ps_info;
+ FT_Service_GlyphDictRec cff_service_glyph_dict;
+ FT_Service_PsFontNameRec cff_service_ps_name;
+ FT_Service_TTCMapsRec cff_service_get_cmap_info;
+ FT_Service_CIDRec cff_service_cid_info;
+ FT_CMap_ClassRec cff_cmap_encoding_class_rec;
+ FT_CMap_ClassRec cff_cmap_unicode_class_rec;
+ } CffModulePIC;
+
+#define GET_PIC(lib) ((CffModulePIC*)((lib)->pic_container.cff))
+#define FT_CFF_SERVICE_PS_INFO_GET (GET_PIC(library)->cff_service_ps_info)
+#define FT_CFF_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->cff_service_glyph_dict)
+#define FT_CFF_SERVICE_PS_NAME_GET (GET_PIC(library)->cff_service_ps_name)
+#define FT_CFF_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->cff_service_get_cmap_info)
+#define FT_CFF_SERVICE_CID_INFO_GET (GET_PIC(library)->cff_service_cid_info)
+#define FT_CFF_SERVICES_GET (GET_PIC(library)->cff_services)
+#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec)
+#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET (GET_PIC(library)->cff_cmap_unicode_class_rec)
+#define FT_CFF_FIELD_HANDLERS_GET (GET_PIC(library)->cff_field_handlers)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __CFFPIC_H__ */
+
+
+/* END */
diff --git a/src/freetype2/cff/cfftypes.h b/src/freetype2/cff/cfftypes.h
index 306e5aa..df92e9a 100644
--- a/src/freetype2/cff/cfftypes.h
+++ b/src/freetype2/cff/cfftypes.h
@@ -5,7 +5,7 @@
/* Basic OpenType/CFF type definitions and interface (specification */
/* only). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -114,7 +114,7 @@ FT_BEGIN_HEADER
FT_Int paint_type;
FT_Int charstring_type;
FT_Matrix font_matrix;
- FT_UShort units_per_em;
+ FT_ULong units_per_em; /* temporarily used as scaling value also */
FT_Vector font_offset;
FT_ULong unique_id;
FT_BBox font_bbox;
@@ -130,7 +130,7 @@ FT_BEGIN_HEADER
/* these should only be used for the top-level font dictionary */
FT_UInt cid_registry;
FT_UInt cid_ordering;
- FT_ULong cid_supplement;
+ FT_Long cid_supplement;
FT_Long cid_font_version;
FT_Long cid_font_revision;
@@ -259,6 +259,10 @@ FT_BEGIN_HEADER
/* since version 2.3.0 */
PS_FontInfoRec* font_info; /* font info dictionary */
+ /* since version 2.3.6 */
+ FT_String* registry;
+ FT_String* ordering;
+
} CFF_FontRec, *CFF_Font;