diff options
Diffstat (limited to 'src/freetype2/type1')
-rw-r--r-- | src/freetype2/type1/t1afm.c | 15 | ||||
-rw-r--r-- | src/freetype2/type1/t1driver.c | 58 | ||||
-rw-r--r-- | src/freetype2/type1/t1driver.h | 4 | ||||
-rw-r--r-- | src/freetype2/type1/t1gload.c | 129 | ||||
-rw-r--r-- | src/freetype2/type1/t1gload.h | 9 | ||||
-rw-r--r-- | src/freetype2/type1/t1load.c | 134 | ||||
-rw-r--r-- | src/freetype2/type1/t1objs.c | 137 | ||||
-rw-r--r-- | src/freetype2/type1/t1parse.c | 50 | ||||
-rw-r--r-- | src/freetype2/type1/t1parse.h | 6 | ||||
-rw-r--r-- | src/freetype2/type1/t1tokens.h | 13 |
10 files changed, 359 insertions, 196 deletions
diff --git a/src/freetype2/type1/t1afm.c b/src/freetype2/type1/t1afm.c index b81a8df..16dc471 100644 --- a/src/freetype2/type1/t1afm.c +++ b/src/freetype2/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (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, */ @@ -50,13 +50,17 @@ /* read a glyph name and return the equivalent glyph index */ static FT_Int t1_get_index( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ) { T1_Font type1 = (T1_Font)user_data; FT_Int n; + /* PS string/name length must be < 16-bit */ + if ( ( len - 0xFFFFU ) > 0 ) + return 0; + for ( n = 0; n < type1->num_glyphs; n++ ) { char* gname = (char*)type1->glyph_names[n]; @@ -88,7 +92,12 @@ FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 ); - return (int)( index1 - index2 ); + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; } diff --git a/src/freetype2/type1/t1driver.c b/src/freetype2/type1/t1driver.c index 3ca21dc..8c398ee 100644 --- a/src/freetype2/type1/t1driver.c +++ b/src/freetype2/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,6 +84,7 @@ return 0; } + static const FT_Service_GlyphDictRec t1_service_glyph_dict = { (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, @@ -91,10 +92,10 @@ }; - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* t1_get_ps_name( T1_Face face ) @@ -102,16 +103,17 @@ return (const char*) face->type1.font_name; } + static const FT_Service_PsFontNameRec t1_service_ps_name = { (FT_PsName_GetFunc)t1_get_ps_name }; - /* - * MULTIPLE MASTERS SERVICE - * - */ + /* + * MULTIPLE MASTERS SERVICE + * + */ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = @@ -125,17 +127,28 @@ #endif - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error t1_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((T1_Face)face)->type1.font_info; - return 0; + + return T1_Err_Ok; + } + + + static FT_Error + t1_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T1_Face)face)->type1.font_extra; + + return T1_Err_Ok; } @@ -143,6 +156,7 @@ t1_ps_has_glyph_names( FT_Face face ) { FT_UNUSED( face ); + return 1; } @@ -152,17 +166,20 @@ PS_PrivateRec* afont_private ) { *afont_private = ((T1_Face)face)->type1.private_dict; - return 0; + + return T1_Err_Ok; } static const FT_Service_PsInfoRec t1_service_ps_info = { (PS_GetFontInfoFunc) t1_ps_get_font_info, + (PS_GetFontExtraFunc) t1_ps_get_font_extra, (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, (PS_GetFontPrivateFunc)t1_ps_get_font_private, }; + #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { @@ -170,10 +187,11 @@ }; #endif - /* - * SERVICE LIST - * - */ + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec t1_services[] = { @@ -304,7 +322,7 @@ (FT_Face_GetKerningFunc) Get_Kerning, (FT_Face_AttachFunc) T1_Read_Metrics, #endif - (FT_Face_GetAdvancesFunc) 0, + (FT_Face_GetAdvancesFunc) T1_Get_Advances, (FT_Size_RequestFunc) T1_Size_Request, (FT_Size_SelectFunc) 0 }; diff --git a/src/freetype2/type1/t1driver.h b/src/freetype2/type1/t1driver.h index ad42944..9fecbeb 100644 --- a/src/freetype2/type1/t1driver.h +++ b/src/freetype2/type1/t1driver.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; diff --git a/src/freetype2/type1/t1gload.c b/src/freetype2/type1/t1gload.c index e08a428..1658615 100644 --- a/src/freetype2/type1/t1gload.c +++ b/src/freetype2/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,6 +18,7 @@ #include <ft2build.h> #include "t1gload.h" +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H @@ -62,6 +63,11 @@ T1_Font type1 = &face->type1; FT_Error error = T1_Err_Ok; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + decoder->font_matrix = type1->font_matrix; decoder->font_offset = type1->font_offset; @@ -70,10 +76,9 @@ /* For incremental fonts get the character data using the */ /* callback function. */ - if ( face->root.internal->incremental_interface ) - error = face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, char_string ); + if ( inc ) + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, char_string ); else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -92,21 +97,21 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + if ( !error && inc && inc->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; - metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - decoder->builder.left_bearing.x = metrics.bearing_x; - decoder->builder.left_bearing.y = metrics.bearing_y; - decoder->builder.advance.x = metrics.advance; + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); decoder->builder.advance.y = 0; } @@ -203,6 +208,63 @@ FT_LOCAL_DEF( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ) + { + T1_DecoderRec decoder; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_UInt nn; + FT_Error error; + + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + advances[nn] = 0; + + return T1_Err_Ok; + } + + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + for ( nn = 0; nn < count; nn++ ) + { + error = T1_Parse_Glyph( &decoder, first + nn ); + if ( !error ) + advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); + else + advances[nn] = 0; + } + + return T1_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, FT_UInt glyph_index, @@ -236,8 +298,16 @@ if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; + if ( size ) + { + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + else + { + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + } glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -303,11 +373,14 @@ FT_Slot_Internal internal = glyph->root.internal; - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - internal->glyph_matrix = font_matrix; - internal->glyph_delta = font_offset; - internal->glyph_transformed = 1; + glyph->root.metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + glyph->root.metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; } else { @@ -317,8 +390,10 @@ /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - glyph->root.linearHoriAdvance = decoder.builder.advance.x; + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + glyph->root.linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); glyph->root.internal->glyph_transformed = 0; /* make up vertical ones */ @@ -371,8 +446,8 @@ } /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); } /* compute the other metrics */ diff --git a/src/freetype2/type1/t1gload.h b/src/freetype2/type1/t1gload.h index de87896..100df06 100644 --- a/src/freetype2/type1/t1gload.h +++ b/src/freetype2/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,6 +32,13 @@ FT_BEGIN_HEADER FT_Pos* max_advance ); FT_LOCAL( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ); + + FT_LOCAL( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, FT_UInt glyph_index, diff --git a/src/freetype2/type1/t1load.c b/src/freetype2/type1/t1load.c index 55177ee..d867e94 100644 --- a/src/freetype2/type1/t1load.c +++ b/src/freetype2/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font 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, */ @@ -65,6 +65,7 @@ #include FT_CONFIG_CONFIG_H #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_CALC_H #include "t1load.h" #include "t1errors.h" @@ -213,10 +214,6 @@ } -#define FT_INT_TO_FIXED( a ) ( (a) << 16 ) -#define FT_FIXED_TO_INT( a ) ( FT_RoundFix( a ) >> 16 ) - - /*************************************************************************/ /* */ /* Given a normalized (blend) coordinate, figure out the design */ @@ -230,7 +227,7 @@ if ( ncv <= axismap->blend_points[0] ) - return axismap->design_points[0]; + return INT_TO_FIXED( axismap->design_points[0] ); for ( j = 1; j < axismap->num_points; ++j ) { @@ -241,8 +238,7 @@ axismap->blend_points[j] - axismap->blend_points[j - 1] ); - - return axismap->design_points[j - 1] + + return INT_TO_FIXED( axismap->design_points[j - 1] ) + FT_MulDiv( t, axismap->design_points[j] - axismap->design_points[j - 1], @@ -250,7 +246,7 @@ } } - return axismap->design_points[axismap->num_points - 1]; + return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); } @@ -332,13 +328,13 @@ for ( i = 0 ; i < mmaster.num_axis; ++i ) { mmvar->axis[i].name = mmaster.axis[i].name; - mmvar->axis[i].minimum = FT_INT_TO_FIXED( mmaster.axis[i].minimum); - mmvar->axis[i].maximum = FT_INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].maximum ) / 2; /* Does not apply. But this value is in range */ - mmvar->axis[i].strid = 0xFFFFFFFFUL; /* Does not apply */ - mmvar->axis[i].tag = 0xFFFFFFFFUL; /* Does not apply */ + mmvar->axis[i].strid = (FT_UInt)-1; /* Does not apply */ + mmvar->axis[i].tag = (FT_ULong)-1; /* Does not apply */ if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); @@ -348,16 +344,15 @@ mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); } - if ( blend->num_designs == 1U << blend->num_axis ) + if ( blend->num_designs == ( 1U << blend->num_axis ) ) { mm_weights_unmap( blend->default_weight_vector, axiscoords, blend->num_axis ); for ( i = 0; i < mmaster.num_axis; ++i ) - mmvar->axis[i].def = - FT_INT_TO_FIXED( mm_axis_unmap( &blend->design_map[i], - axiscoords[i] ) ); + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); } *master = mmvar; @@ -504,7 +499,7 @@ if ( num_coords <= 4 && num_coords > 0 ) { for ( i = 0; i < num_coords; ++i ) - lcoords[i] = FT_FIXED_TO_INT( coords[i] ); + lcoords[i] = FIXED_TO_INT( coords[i] ); error = T1_Set_MM_Design( face, num_coords, lcoords ); } @@ -656,8 +651,8 @@ } if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { - FT_ERROR(( "parse_blend_design_positions:" )); - FT_ERROR(( " incorrect number of designs: %d\n", + FT_ERROR(( "parse_blend_design_positions:" + " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; @@ -674,7 +669,7 @@ for ( n = 0; n < num_designs; n++ ) { - T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; T1_Token token; FT_Int axis, n_axis; @@ -687,6 +682,15 @@ if ( n == 0 ) { + if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " invalid number of axes: %d\n", + n_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + num_axis = n_axis; error = t1_allocate_blend( face, num_designs, num_axis ); if ( error ) @@ -835,8 +839,8 @@ } if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { - FT_ERROR(( "parse_weight_vector:" )); - FT_ERROR(( " incorrect number of designs: %d\n", + FT_ERROR(( "parse_weight_vector:" + " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; @@ -852,9 +856,9 @@ else if ( blend->num_designs != (FT_UInt)num_designs ) { FT_ERROR(( "parse_weight_vector:" - " /BlendDesignPosition and /WeightVector have\n" )); - FT_ERROR(( " " - " different number of elements!\n" )); + " /BlendDesignPosition and /WeightVector have\n" + " " + " different number of elements\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -941,6 +945,12 @@ } break; + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + objects = &dummy_object; + max_objects = 0; + break; + case T1_FIELD_LOCATION_PRIVATE: dummy_object = &face->type1.private_dict; objects = &dummy_object; @@ -1130,7 +1140,7 @@ cur = parser->root.cursor; if ( cur >= limit ) { - FT_ERROR(( "parse_encoding: out of bounds!\n" )); + FT_ERROR(( "parse_encoding: out of bounds\n" )); parser->root.error = T1_Err_Invalid_File_Format; return; } @@ -1265,6 +1275,19 @@ n++; } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the type1 */ + /* specification (it might be an encoding for a CID type1 */ + /* font, however), so we conclude that this font is NOT a */ + /* type1 font. */ + parser->root.error = FT_Err_Unknown_File_Format; + return; + } } else { @@ -1310,9 +1333,9 @@ PS_Table table = &loader->subrs; FT_Memory memory = parser->root.memory; FT_Error error; - FT_Int n, num_subrs; + FT_Int num_subrs; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)face->psaux; T1_Skip_Spaces( parser ); @@ -1346,18 +1369,17 @@ goto Fail; } - /* the format is simple: */ - /* */ - /* `index' + binary data */ - /* */ - for ( n = 0; n < num_subrs; n++ ) + /* the format is simple: */ + /* */ + /* `index' + binary data */ + /* */ + for (;;) { FT_Long idx, size; FT_Byte* base; - /* If the next token isn't `dup', we are also done. This */ - /* happens when there are `holes' in the Subrs array. */ + /* If the next token isn't `dup' we are done. */ if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) break; @@ -1397,7 +1419,10 @@ FT_Byte* temp; - if ( size <= face->type1.private_dict.lenIV ) + /* some fonts define empty subr records -- this is not totally */ + /* compliant to the specification (which says they should at */ + /* least contain a `return'), but we support them anyway */ + if ( size < face->type1.private_dict.lenIV ) { error = T1_Err_Invalid_File_Format; goto Fail; @@ -1603,15 +1628,11 @@ } } - if ( loader->num_glyphs ) - return; - else - loader->num_glyphs = n; + loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)name_table->elements[0] ) && - notdef_found ) + if ( notdef_found && + ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) { /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ /* name and code entries to swap_table. Then place notdef_index */ @@ -1680,7 +1701,7 @@ /* and add our own /.notdef glyph to index 0. */ /* 0 333 hsbw endchar */ - FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; + FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; char* notdef_name = (char *)".notdef"; @@ -1718,7 +1739,7 @@ goto Fail; /* we added a glyph. */ - loader->num_glyphs = n + 1; + loader->num_glyphs += 1; } return; @@ -2132,7 +2153,7 @@ #endif if ( !loader.charstrings.init ) { - FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" )); + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); error = T1_Err_Invalid_File_Format; } @@ -2161,8 +2182,8 @@ /* the index is then stored in type1.encoding.char_index, and */ /* a the name to type1.encoding.char_name */ - min_char = +32000; - max_char = -32000; + min_char = 0; + max_char = 0; charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) @@ -2188,25 +2209,14 @@ { if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) - max_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; } break; } } } - /* - * Yes, this happens: Certain PDF-embedded fonts have only a - * `.notdef' glyph defined! - */ - - if ( min_char > max_char ) - { - min_char = 0; - max_char = loader.encoding_table.max_elems; - } - type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; diff --git a/src/freetype2/type1/t1objs.c b/src/freetype2/type1/t1objs.c index 3d08336..e9357e6 100644 --- a/src/freetype2/type1/t1objs.c +++ b/src/freetype2/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 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, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_IDS_H @@ -90,7 +91,7 @@ FT_LOCAL_DEF( FT_Error ) T1_Size_Init( T1_Size size ) { - FT_Error error = 0; + FT_Error error = T1_Err_Ok; PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); @@ -191,72 +192,75 @@ FT_LOCAL_DEF( void ) T1_Face_Done( T1_Face face ) { - if ( face ) - { - FT_Memory memory = face->root.memory; - T1_Font type1 = &face->type1; + FT_Memory memory; + T1_Font type1; + + + if ( !face ) + return; + memory = face->root.memory; + type1 = &face->type1; #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - /* release multiple masters information */ - FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + /* release multiple masters information */ + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); - if ( face->buildchar ) - { - FT_FREE( face->buildchar ); + if ( face->buildchar ) + { + FT_FREE( face->buildchar ); - face->buildchar = NULL; - face->len_buildchar = 0; - } + face->buildchar = NULL; + face->len_buildchar = 0; + } - T1_Done_Blend( face ); - face->blend = 0; + T1_Done_Blend( face ); + face->blend = 0; #endif - /* release font info strings */ - { - PS_FontInfo info = &type1->font_info; + /* release font info strings */ + { + PS_FontInfo info = &type1->font_info; - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - } + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + } - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); - FT_FREE( type1->subrs ); - FT_FREE( type1->subrs_len ); + FT_FREE( type1->subrs ); + FT_FREE( type1->subrs_len ); - FT_FREE( type1->subrs_block ); - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); + FT_FREE( type1->subrs_block ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); #ifndef T1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); #endif - /* release unicode map, if any */ + /* release unicode map, if any */ #if 0 - FT_FREE( face->unicode_map_rec.maps ); - face->unicode_map_rec.num_maps = 0; - face->unicode_map = NULL; + FT_FREE( face->unicode_map_rec.maps ); + face->unicode_map_rec.num_maps = 0; + face->unicode_map = NULL; #endif - face->root.family_name = 0; - face->root.style_name = 0; - } + face->root.family_name = NULL; + face->root.style_name = NULL; } @@ -298,7 +302,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -324,7 +327,7 @@ goto Exit; /* check the face index */ - if ( face_index != 0 ) + if ( face_index > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = T1_Err_Invalid_Argument; @@ -341,7 +344,7 @@ root->num_glyphs = type1->num_glyphs; - root->face_index = face_index; + root->face_index = 0; root->face_flags = FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | @@ -356,11 +359,18 @@ /* XXX: TODO -- add kerning with .afm support */ + + /* The following code to extract the family and the style is very */ + /* simplistic and might get some things wrong. For a full-featured */ + /* algorithm you might have a look at the whitepaper given at */ + /* */ + /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ + /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = info->family_name; - /* assume "Regular" style if we don't know better */ - root->style_name = (char *)"Regular"; + root->style_name = NULL; + if ( root->family_name ) { char* full = info->full_name; @@ -369,6 +379,9 @@ if ( full ) { + FT_Bool the_same = TRUE; + + while ( *full ) { if ( *full == *family ) @@ -384,12 +397,17 @@ family++; else { + the_same = FALSE; + if ( !*family ) root->style_name = full; break; } } } + + if ( the_same ) + root->style_name = (char *)"Regular"; } } else @@ -399,6 +417,15 @@ root->family_name = type1->font_name; } + if ( !root->style_name ) + { + if ( info->weight ) + root->style_name = info->weight; + else + /* assume `Regular' style because we don't know better */ + root->style_name = (char *)"Regular"; + } + /* compute style flags */ root->style_flags = 0; if ( info->italic_angle ) @@ -441,9 +468,9 @@ /* in case of error, keep the standard width */ if ( !error ) - root->max_advance_width = (FT_Short)max_advance; + root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); else - error = 0; /* clear error */ + error = T1_Err_Ok; /* clear error */ } root->max_advance_height = root->height; @@ -465,7 +492,7 @@ charmap.face = root; - /* first of all, try to synthetize a Unicode charmap */ + /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; diff --git a/src/freetype2/type1/t1parse.c b/src/freetype2/type1/t1parse.c index 1b252c7..1bef56b 100644 --- a/src/freetype2/type1/t1parse.c +++ b/src/freetype2/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,6 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_POSTSCRIPT_AUX_H @@ -65,14 +64,16 @@ /*************************************************************************/ + /* see Adobe Technical Note 5040.Download_Fonts.pdf */ + static FT_Error read_pfb_tag( FT_Stream stream, FT_UShort *atag, - FT_Long *asize ) + FT_ULong *asize ) { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; *atag = 0; @@ -82,7 +83,7 @@ { if ( tag == 0x8001U || tag == 0x8002U ) { - if ( !FT_READ_LONG_LE( size ) ) + if ( !FT_READ_ULONG_LE( size ) ) *asize = size; } @@ -100,22 +101,25 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong dummy; if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - error = read_pfb_tag( stream, &tag, &size ); + error = read_pfb_tag( stream, &tag, &dummy ); if ( error ) goto Exit; + /* We assume that the first segment in a PFB is always encoded as */ + /* text. This might be wrong (and the specification doesn't insist */ + /* on that), but we have never seen a counterexample. */ if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) goto Exit; if ( !FT_FRAME_ENTER( header_length ) ) { - error = 0; + error = T1_Err_Ok; if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) error = T1_Err_Unknown_File_Format; @@ -136,7 +140,7 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); @@ -170,19 +174,19 @@ /* Here a short summary of what is going on: */ /* */ /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e. for PFB */ + /* the base dictionary if this is possible (i.e., for PFB */ /* files). Otherwise, we load the whole font into memory. */ /* */ /* When `loading' the base dictionary, we only setup pointers */ /* in the case of a memory-based stream. Otherwise, we */ /* allocate and load the base dictionary in it. */ /* */ - /* parser->in_pfb is set if we are in a binary (".pfb") font. */ + /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ /* parser->in_memory is set if we have a memory stream. */ /* */ - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e 0x8001 */ + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e., 0x8001 */ if ( FT_STREAM_SEEK( 0L ) ) goto Exit; @@ -217,7 +221,7 @@ } else { - /* read segment in memory - this is clumsy, but so does the format */ + /* read segment in memory -- this is clumsy, but so does the format */ if ( FT_ALLOC( parser->base_dict, size ) || FT_STREAM_READ( parser->base_dict, size ) ) goto Exit; @@ -260,7 +264,7 @@ FT_Stream stream = parser->stream; FT_Memory memory = parser->root.memory; FT_Error error = T1_Err_Ok; - FT_Long size; + FT_ULong size; if ( parser->in_pfb ) @@ -293,13 +297,13 @@ /* and allocate private dictionary buffer */ if ( parser->private_len == 0 ) { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); error = T1_Err_Invalid_File_Format; goto Fail; } - if ( FT_STREAM_SEEK( start_pos ) || + if ( FT_STREAM_SEEK( start_pos ) || FT_ALLOC( parser->private_dict, parser->private_len ) ) goto Fail; @@ -349,8 +353,8 @@ cur++; if ( cur >= limit ) { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " could not find `eexec' keyword\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " could not find `eexec' keyword\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -403,13 +407,13 @@ cur++; else { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " `eexec' not properly terminated\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " `eexec' not properly terminated\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } - size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); + size = parser->base_len - ( cur - parser->base_dict ); if ( parser->in_memory ) { diff --git a/src/freetype2/type1/t1parse.h b/src/freetype2/type1/t1parse.h index 6fa4ca6..fb1c8a8 100644 --- a/src/freetype2/type1/t1parse.h +++ b/src/freetype2/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,10 +64,10 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* base_dict; - FT_Long base_len; + FT_ULong base_len; FT_Byte* private_dict; - FT_Long private_len; + FT_ULong private_len; FT_Bool in_pfb; FT_Bool in_memory; diff --git a/src/freetype2/type1/t1tokens.h b/src/freetype2/type1/t1tokens.h index 788c811..2d692f0 100644 --- a/src/freetype2/type1/t1tokens.h +++ b/src/freetype2/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,13 @@ T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, T1_FIELD_DICT_FONTDICT ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, + T1_FIELD_DICT_FONTDICT ) #undef FT_STRUCTURE #define FT_STRUCTURE PS_PrivateRec @@ -87,7 +94,9 @@ T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, T1_FIELD_DICT_PRIVATE ) - + T1_FIELD_BOOL ( "ForceBold", force_bold, + T1_FIELD_DICT_PRIVATE ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec |