summaryrefslogtreecommitdiffstats
path: root/src/cff
diff options
context:
space:
mode:
Diffstat (limited to 'src/cff')
-rw-r--r--src/cff/Jamfile29
-rw-r--r--src/cff/cffcmap.c10
-rw-r--r--src/cff/cffdrivr.c153
-rw-r--r--src/cff/cffgload.c161
-rw-r--r--src/cff/cffgload.h14
-rw-r--r--src/cff/cffload.c13
-rw-r--r--src/cff/cffobjs.c326
-rw-r--r--src/cff/cffobjs.h22
-rw-r--r--src/cff/cffparse.c309
-rw-r--r--src/cff/cfftypes.h8
-rw-r--r--src/cff/module.mk23
-rw-r--r--src/cff/rules.mk72
12 files changed, 784 insertions, 356 deletions
diff --git a/src/cff/Jamfile b/src/cff/Jamfile
deleted file mode 100644
index 6d0bb1b..0000000
--- a/src/cff/Jamfile
+++ /dev/null
@@ -1,29 +0,0 @@
-# FreeType 2 src/cff Jamfile
-#
-# Copyright 2001, 2002 by
-# David Turner, Robert Wilhelm, and Werner Lemberg.
-#
-# 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.
-
-SubDir FT2_TOP $(FT2_SRC_DIR) cff ;
-
-{
- local _sources ;
-
- if $(FT2_MULTI)
- {
- _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap ;
- }
- else
- {
- _sources = cff ;
- }
-
- Library $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/cff Jamfile
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index fffc5fc..578d048 100644
--- a/src/cff/cffcmap.c
+++ b/src/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, */
@@ -107,7 +107,9 @@
(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
};
@@ -213,7 +215,9 @@
(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
};
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 952e88e..68de8dc 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -22,8 +22,10 @@
#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"
@@ -151,7 +153,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 +165,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,6 +186,32 @@
}
+ FT_CALLBACK_DEF(FT_Error)
+ cff_get_advances( FT_Face ftface,
+ FT_UInt start,
+ FT_UInt count,
+ FT_UInt flags,
+ FT_Fixed* advances )
+ {
+ CFF_Face face = (CFF_Face) ftface;
+ FT_UInt nn;
+ FT_Error error = 0;
+ FT_GlyphSlot slot = face->root.glyph;
+
+ flags |= FT_LOAD_ADVANCE_ONLY;
+
+ for (nn = 0; nn < count; nn++)
+ {
+ error = Load_Glyph( slot, face->root.size, start+nn, flags );
+ if (error) break;
+
+ advances[nn] = (flags & FT_LOAD_VERTICAL_LAYOUT)
+ ? slot->advance.y
+ : slot->advance.x;
+ }
+ return error;
+ }
+
/*
* GLYPH DICT SERVICE
*
@@ -226,8 +254,8 @@
FT_FREE( gname );
error = CFF_Err_Ok;
- Exit:
- return error;
+ Exit:
+ return error;
}
@@ -284,10 +312,10 @@
};
- /*
- * POSTSCRIPT INFO SERVICE
- *
- */
+ /*
+ * POSTSCRIPT INFO SERVICE
+ *
+ */
static FT_Int
cff_ps_has_glyph_names( FT_Face face )
@@ -306,9 +334,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 +345,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;
@@ -353,6 +382,27 @@
/*
+ * 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;
+ }
+
+
+ static const FT_Service_PsFontNameRec cff_service_ps_name =
+ {
+ (FT_PsName_GetFunc)cff_get_ps_name
+ };
+
+
+ /*
* TT CMAP INFO
*
* If the charmap is a synthetic Unicode encoding cmap or
@@ -397,6 +447,65 @@
};
+ /*
+ * 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;
+ }
+
+ if ( supplement )
+ *supplement = dict->cid_supplement;
+ }
+
+ Fail:
+ return error;
+ }
+
+
+ static const FT_Service_CIDRec cff_service_cid_info =
+ {
+ (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros
+ };
+
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -411,12 +520,14 @@
static const FT_ServiceDescRec cff_services[] =
{
- { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF },
- { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info },
+ { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF },
+ { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info },
+ { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name },
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
- { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict },
+ { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict },
#endif
- { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info },
+ { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info },
+ { FT_SERVICE_ID_CID, &cff_service_cid_info },
{ NULL, NULL }
};
@@ -484,7 +595,7 @@
cff_get_kerning,
0, /* FT_Face_AttachFunc */
- 0, /* FT_Face_GetAdvancesFunc */
+ cff_get_advances, /* FT_Face_GetAdvancesFunc */
cff_size_request,
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 0e2a179..3296d12 100644
--- a/src/cff/cffgload.c
+++ b/src/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 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -110,6 +110,9 @@
cff_op_callgsubr,
cff_op_return,
+ cff_op_hsbw, /* Type 1 opcode: invalid but seen in real life */
+ cff_op_closepath, /* ditto */
+
/* do not remove */
cff_op_max
@@ -187,6 +190,9 @@
1, /* callsubr */
1,
+ 0,
+
+ 2, /* hsbw */
0
};
@@ -222,6 +228,8 @@
/* */
/* glyph :: The current glyph object. */
/* */
+ /* hinting :: Whether hinting is active. */
+ /* */
static void
cff_builder_init( CFF_Builder* builder,
TT_Face face,
@@ -251,17 +259,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 +344,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,
@@ -370,19 +379,27 @@
decoder->hint_mode = hint_mode;
}
+ FT_LOCAL_DEF( void )
+ cff_decoder_set_width_only( CFF_Decoder* decoder )
+ {
+ decoder->width_only = 1;
+ }
- /* 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,8 +410,16 @@
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
-
+
sub = cff->subfonts[fd_index];
+ if ( builder->hints_funcs )
+ {
+ 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];
+ }
}
decoder->num_locals = sub->num_local_subrs;
@@ -954,6 +979,9 @@
case 8:
op = cff_op_rrcurveto;
break;
+ case 9:
+ op = cff_op_closepath;
+ break;
case 10:
op = cff_op_callsubr;
break;
@@ -1055,6 +1083,9 @@
}
}
break;
+ case 13:
+ op = cff_op_hsbw;
+ break;
case 14:
op = cff_op_endchar;
break;
@@ -1158,6 +1189,12 @@
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,7 +1205,7 @@
req_args = 0;
}
- req_args &= 15;
+ req_args &= 0x000F;
if ( num_args < req_args )
goto Stack_Underflow;
args -= req_args;
@@ -2022,6 +2059,30 @@
FT_TRACE4(( " dotsection" ));
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)" ));
+
+ 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)" ));
+
+ decoder->glyph_width = decoder->nominal_width +
+ (args[1] >> 16);
+ x = args[0];
+ y = 0;
+ args = stack;
+ break;
+
case cff_op_and:
{
FT_Fixed cond = args[0] && args[1];
@@ -2260,7 +2321,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,
@@ -2291,18 +2352,19 @@
FT_Error error;
CFF_Decoder decoder;
TT_Face face = (TT_Face)glyph->root.face;
- FT_Bool hinting;
+ 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 )
@@ -2389,6 +2451,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_Int top_upm = cff->top_font.font_dict.units_per_em;
+ FT_Int 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,6 +2497,9 @@
cff_decoder_init( &decoder, face, size, glyph, hinting,
FT_LOAD_TARGET_MODE( load_flags ) );
+ if ((load_flags & FT_LOAD_ADVANCE_ONLY) != 0)
+ cff_decoder_set_width_only( &decoder );
+
decoder.builder.no_recurse =
(FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
@@ -2413,7 +2508,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,
@@ -2481,21 +2576,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. */
@@ -2565,9 +2645,8 @@
glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
- /* apply the font matrix */
- if ( !( font_matrix.xx == 0x10000L &&
- font_matrix.yy == 0x10000L &&
+ /* apply the font matrix -- `xx' has already been normalized */
+ if ( !( font_matrix.yy == 0x10000L &&
font_matrix.xy == 0 &&
font_matrix.yx == 0 ) )
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
@@ -2587,7 +2666,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;
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index f67864a..bf21654 100644
--- a/src/cff/cffgload.h
+++ b/src/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 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -55,10 +55,6 @@ FT_BEGIN_HEADER
/* */
/* 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). */
@@ -94,9 +90,6 @@ FT_BEGIN_HEADER
FT_Vector last;
- FT_Fixed scale_x;
- FT_Fixed scale_y;
-
FT_Pos pos_x;
FT_Pos pos_y;
@@ -146,6 +139,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;
@@ -175,8 +169,12 @@ FT_BEGIN_HEADER
FT_Bool hinting,
FT_Render_Mode hint_mode );
+ FT_LOCAL( void )
+ cff_decoder_set_width_only( CFF_Decoder* decoder );
+
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/cff/cffload.c b/src/cff/cffload.c
index dd2f113..9c030cf 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -175,13 +175,14 @@
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 );
}
@@ -1272,8 +1273,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 );
@@ -1590,6 +1592,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/cff/cffobjs.c b/src/cff/cffobjs.c
index c02cf33..12997a9 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -56,7 +56,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 +72,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 );
- cffsize->internal = 0;
+ for ( i = font->num_subfonts; i > 0; i-- )
+ funcs->destroy( internal->subfonts[i - 1] );
+ }
+
+ /* `internal' is freed by destroy_size (in ftobjs.c) */
}
}
+ /* CFF and Type 1 private dictionaries have slightly different */
+ /* structures; we need to synthetize 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 +160,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 +218,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_Int 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_Int 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 +290,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_Int 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_Int 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 +347,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 +368,7 @@
}
}
- return 0;
+ return CFF_Err_Ok;
}
@@ -288,7 +386,9 @@
FT_String* result;
- result = ft_mem_strdup( memory, source, &error );
+ (void)FT_STRDUP( result, source );
+
+ FT_UNUSED( error );
return result;
}
@@ -444,7 +544,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;
@@ -617,39 +717,119 @@
dict->units_per_em = face->root.units_per_EM;
}
- /* handle font matrix settings in subfonts (if any) */
+ /* 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_Matrix scale;
+ FT_Int scaling;
- 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 );
+ 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;
}
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
/* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
- /* has unset this flag because of the 3.0 `post' table */
+ /* has unset this flag because of the 3.0 `post' table. */
if ( dict->cid_registry == 0xFFFFU )
cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif
+ if ( dict->cid_registry != 0xFFFFU )
+ cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
+
+
/*******************************************************************/
/* */
/* Compute char maps. */
@@ -683,7 +863,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;
diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
index f18b5d9..3c81cee 100644
--- a/src/cff/cffobjs.h
+++ b/src/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/cff/cffparse.c b/src/cff/cffparse.c
index 41af6a3..d6d77dd 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
/* */
/* CFF token stream parser (body) */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -19,6 +19,7 @@
#include <ft2build.h>
#include "cffparse.h"
#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_DEBUG_H
#include "cfferrs.h"
@@ -136,24 +137,51 @@
}
+ 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_Int power_ten,
+ FT_Int* 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_Int 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 */
+ /* First of all, read the integer part. */
phase = 4;
for (;;)
@@ -166,7 +194,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Bad;
+ goto Exit;
}
/* Get the nibble. */
@@ -178,10 +206,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 +231,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Bad;
+ goto Exit;
}
/* Get the nibble. */
@@ -202,14 +240,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 )
{
- 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 +260,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 +280,105 @@
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_Int 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;
- /* Move the integer part into the high 16 bits. */
- result <<= 16;
+ /* 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];
+
+ 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 +386,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 +395,121 @@
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_thousand( FT_Byte** d )
+ cff_parse_fixed_scaled( FT_Byte** d,
+ FT_Int 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 );
+ 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
+ : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16,
+ power_tens[scaling] );
}
+
+ /* 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_dynamic( FT_Byte** d,
+ FT_Int* scaling )
+ {
+ 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_Int scaling;
- temp = FT_ABS( matrix->yy );
- *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
+ error = CFF_Err_Ok;
- if ( temp != 0x10000L )
+ /* 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. */
+
+ 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;
}
@@ -585,7 +740,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/cff/cfftypes.h b/src/cff/cfftypes.h
index 306e5aa..546ea3b 100644
--- a/src/cff/cfftypes.h
+++ b/src/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;
@@ -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;
diff --git a/src/cff/module.mk b/src/cff/module.mk
deleted file mode 100644
index 0474e37..0000000
--- a/src/cff/module.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# FreeType 2 CFF module definition
-#
-
-
-# Copyright 1996-2000, 2006 by
-# David Turner, Robert Wilhelm, and Werner Lemberg.
-#
-# 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.
-
-
-FTMODULE_H_COMMANDS += CFF_DRIVER
-
-define CFF_DRIVER
-$(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER)
-$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE)
-endef
-
-# EOF
diff --git a/src/cff/rules.mk b/src/cff/rules.mk
deleted file mode 100644
index 4100c80..0000000
--- a/src/cff/rules.mk
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# FreeType 2 OpenType/CFF driver configuration rules
-#
-
-
-# Copyright 1996-2000, 2001, 2003 by
-# David Turner, Robert Wilhelm, and Werner Lemberg.
-#
-# 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.
-
-
-# OpenType driver directory
-#
-CFF_DIR := $(SRC_DIR)/cff
-
-
-CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR))
-
-
-# CFF driver sources (i.e., C files)
-#
-CFF_DRV_SRC := $(CFF_DIR)/cffobjs.c \
- $(CFF_DIR)/cffload.c \
- $(CFF_DIR)/cffgload.c \
- $(CFF_DIR)/cffparse.c \
- $(CFF_DIR)/cffcmap.c \
- $(CFF_DIR)/cffdrivr.c
-
-# CFF driver headers
-#
-CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
- $(CFF_DIR)/cfftoken.h \
- $(CFF_DIR)/cfftypes.h \
- $(CFF_DIR)/cfferrs.h
-
-
-# CFF driver object(s)
-#
-# CFF_DRV_OBJ_M is used during `multi' builds
-# CFF_DRV_OBJ_S is used during `single' builds
-#
-CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR)/%.c=$(OBJ_DIR)/%.$O)
-CFF_DRV_OBJ_S := $(OBJ_DIR)/cff.$O
-
-# CFF driver source file for single build
-#
-CFF_DRV_SRC_S := $(CFF_DIR)/cff.c
-
-
-# CFF driver - single object
-#
-$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H)
- $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CFF_DRV_SRC_S))
-
-
-# CFF driver - multiple objects
-#
-$(OBJ_DIR)/%.$O: $(CFF_DIR)/%.c $(FREETYPE_H) $(CFF_DRV_H)
- $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
-
-
-# update main driver object lists
-#
-DRV_OBJS_S += $(CFF_DRV_OBJ_S)
-DRV_OBJS_M += $(CFF_DRV_OBJ_M)
-
-
-# EOF