64 #include FT_INTERNAL_DEBUG_H 65 #include FT_CONFIG_CONFIG_H 66 #include FT_MULTIPLE_MASTERS_H 67 #include FT_INTERNAL_TYPE1_TYPES_H 68 #include FT_INTERNAL_CALC_H 74 #ifdef FT_CONFIG_OPTION_INCREMENTAL 75 #define IS_INCREMENTAL ( face->root.internal->incremental_interface != 0 ) 77 #define IS_INCREMENTAL 0 88 #define FT_COMPONENT trace_t1load 91 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 124 if ( num_designs > 0 )
144 for ( nn = 2; nn <= num_designs; nn++ )
169 if ( num_designs && num_axis && blend->
design_pos[0] == 0 )
177 for ( n = 1; n < num_designs; n++ )
185 error =
FT_THROW( Invalid_File_Format );
236 if ( ncv <= axismap->blend_points[0] )
239 for ( j = 1; j < axismap->num_points; ++j )
241 if ( ncv <= axismap->blend_points[j] )
243 ( axismap->design_points[j] - axismap->design_points[j - 1] ) *
244 FT_DivFix( ncv - axismap->blend_points[j - 1],
245 axismap->blend_points[j] -
246 axismap->blend_points[j - 1] );
249 return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
265 if ( axis_count == 1 )
268 else if ( axis_count == 2 )
271 axiscoords[1] = weights[3] + weights[2];
274 else if ( axis_count == 3 )
277 axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];
278 axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];
285 axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] +
286 weights[7] + weights[6] + weights[3] + weights[2];
287 axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] +
288 weights[7] + weights[6] + weights[5] + weights[4];
289 axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] +
290 weights[11] + weights[10] + weights[9] + weights[8];
377 if ( blend && blend->
num_axis == num_coords )
396 if ( factor > 0x10000L )
399 if ( (
n & ( 1 <<
m ) ) == 0 )
400 factor = 0x10000L - factor;
425 if ( blend && blend->
num_axis == num_coords )
438 FT_Int before = -1, after = -1;
447 if ( design == p_design )
449 the_blend = blends[
p];
453 if ( design < p_design )
464 the_blend = blends[0];
466 else if ( after < 0 )
470 the_blend =
FT_MulDiv( design - designs[before],
471 blends [after] - blends [before],
472 designs[after] - designs[before] );
475 final_blends[
n] = the_blend;
501 if ( num_coords <= 4 && num_coords > 0 )
503 for (
i = 0;
i < num_coords; ++
i )
528 for ( n = 1; n < num_designs; n++ )
536 for ( n = 0; n < num_designs; n++ )
548 for ( n = 0; n < num_axis; n++ )
552 for ( n = 0; n < num_axis; n++ )
587 FT_ERROR((
"parse_blend_axis_types: incorrect number of axes: %d\n",
589 error =
FT_THROW( Invalid_File_Format );
594 error = t1_allocate_blend( face, 0, (
FT_UInt)num_axis );
602 for ( n = 0; n < num_axis; n++ )
610 if ( token->
start[0] ==
'/' )
616 error =
FT_THROW( Invalid_File_Format );
629 loader->parser.root.error =
error;
634 parse_blend_design_positions(
T1_Face face,
649 if ( num_designs < 0 )
656 FT_ERROR((
"parse_blend_design_positions:" 657 " incorrect number of designs: %d\n",
659 error =
FT_THROW( Invalid_File_Format );
664 FT_Byte* old_cursor = parser->root.cursor;
665 FT_Byte* old_limit = parser->root.limit;
672 for ( n = 0; n < num_designs; n++ )
680 token = design_tokens +
n;
681 parser->root.cursor = token->
start;
682 parser->root.limit = token->
limit;
689 FT_ERROR((
"parse_blend_design_positions:" 690 " invalid number of axes: %d\n",
692 error =
FT_THROW( Invalid_File_Format );
697 error = t1_allocate_blend( face, num_designs, num_axis );
702 else if ( n_axis != num_axis )
704 FT_ERROR((
"parse_blend_design_positions: incorrect table\n" ));
705 error =
FT_THROW( Invalid_File_Format );
710 for ( axis = 0; axis < n_axis; axis++ )
712 T1_Token token2 = axis_tokens + axis;
715 parser->root.cursor = token2->
start;
716 parser->root.limit = token2->
limit;
721 loader->parser.root.cursor = old_cursor;
722 loader->parser.root.limit = old_limit;
726 loader->parser.root.error =
error;
731 parse_blend_design_map(
T1_Face face,
753 FT_ERROR((
"parse_blend_design_map: incorrect number of axes: %d\n",
755 error =
FT_THROW( Invalid_File_Format );
759 old_cursor = parser->root.cursor;
760 old_limit = parser->root.limit;
762 error = t1_allocate_blend( face, 0, num_axis );
768 for ( n = 0; n < num_axis; n++ )
776 axis_token = axis_tokens +
n;
778 parser->root.cursor = axis_token->
start;
779 parser->root.limit = axis_token->
limit;
785 FT_ERROR((
"parse_blend_design_map: incorrect table\n" ));
786 error =
FT_THROW( Invalid_File_Format );
796 for ( p = 0; p < num_points; p++ )
801 point_token = point_tokens +
p;
804 parser->root.cursor = point_token->
start + 1;
805 parser->root.limit = point_token->
limit - 1;
812 parser->root.cursor = old_cursor;
813 parser->root.limit = old_limit;
816 parser->root.error =
error;
821 parse_weight_vector(
T1_Face face,
837 if ( num_designs < 0 )
845 " incorrect number of designs: %d\n",
847 error =
FT_THROW( Invalid_File_Format );
853 error = t1_allocate_blend( face, num_designs, 0 );
861 " /BlendDesignPosition and /WeightVector have\n" 863 " different number of elements\n" ));
864 error =
FT_THROW( Invalid_File_Format );
868 old_cursor = parser->root.cursor;
869 old_limit = parser->root.limit;
871 for ( n = 0; n < num_designs; n++ )
873 token = design_tokens +
n;
874 parser->root.cursor = token->
start;
875 parser->root.limit = token->
limit;
881 parser->root.cursor = old_cursor;
882 parser->root.limit = old_limit;
885 parser->root.error =
error;
933 error = loader->parser.root.error;
943 objects = &dummy_object;
955 objects = &dummy_object;
961 objects = &dummy_object;
973 objects = &dummy_object;
978 objects = (
void**)blend->
bboxes;
984 dummy_object = loader;
985 objects = &dummy_object;
991 objects = &dummy_object;
995 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 997 dummy_object = face->
blend;
998 objects = &dummy_object;
1004 dummy_object = &face->
type1;
1005 objects = &dummy_object;
1014 objects, max_objects, 0 );
1017 objects, max_objects, 0 );
1021 FT_TRACE1((
"t1_load_keyword: ignoring keyword `%s'" 1022 " which is not valid at this point\n" 1023 " (probably due to missing keywords)\n",
1061 cur = parser->root.cursor;
1072 *base = parser->root.cursor + 1;
1074 if ( s >= 0 && s < limit - *base )
1076 parser->root.cursor += s + 1;
1078 return !parser->root.error;
1084 FT_ERROR((
"read_binary_data: invalid size field\n" ));
1085 parser->root.error =
FT_THROW( Invalid_File_Format );
1096 t1_parse_font_matrix(
T1_Face face,
1112 parser->root.error =
FT_THROW( Invalid_File_Format );
1116 temp_scale =
FT_ABS( temp[3] );
1118 if ( temp_scale == 0 )
1120 FT_ERROR((
"t1_parse_font_matrix: invalid font matrix\n" ));
1121 parser->root.error =
FT_THROW( Invalid_File_Format );
1132 if ( temp_scale != 0x10000L )
1134 temp[0] =
FT_DivFix( temp[0], temp_scale );
1135 temp[1] =
FT_DivFix( temp[1], temp_scale );
1136 temp[2] =
FT_DivFix( temp[2], temp_scale );
1137 temp[4] =
FT_DivFix( temp[4], temp_scale );
1138 temp[5] =
FT_DivFix( temp[5], temp_scale );
1139 temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
1142 matrix->
xx = temp[0];
1143 matrix->
yx = temp[1];
1144 matrix->
xy = temp[2];
1145 matrix->
yy = temp[3];
1148 offset->
x = temp[4] >> 16;
1149 offset->
y = temp[5] >> 16;
1165 cur = parser->root.cursor;
1168 FT_ERROR((
"parse_encoding: out of bounds\n" ));
1169 parser->root.error =
FT_THROW( Invalid_File_Format );
1179 PS_Table char_table = &loader->encoding_table;
1189 only_immediates = 1;
1190 parser->root.cursor++;
1196 if ( parser->root.cursor >= limit )
1200 loader->num_chars = encode->num_chars =
count;
1204 char_table, count, memory ) ) )
1206 parser->root.error =
error;
1211 for ( n = 0; n <
count; n++ )
1213 char* notdef = (
char *)
".notdef";
1242 while ( parser->root.cursor < limit )
1244 cur = parser->root.cursor;
1247 if ( *cur ==
'd' && cur + 3 < limit )
1249 if ( cur[1] ==
'e' &&
1271 if ( only_immediates )
1279 cur = parser->root.cursor;
1281 if ( cur + 2 < limit && *cur ==
'/' && n < count )
1288 parser->root.cursor = cur;
1290 if ( parser->root.cursor >= limit )
1292 if ( parser->root.error )
1295 len = parser->root.cursor - cur;
1297 parser->root.error =
T1_Add_Table( char_table, charcode,
1299 if ( parser->root.error )
1301 char_table->elements[charcode][
len] =
'\0';
1305 else if ( only_immediates )
1315 parser->root.error =
FT_THROW( Unknown_File_Format );
1322 if ( parser->root.error )
1330 parser->root.cursor = cur;
1337 if ( cur + 17 < limit &&
1338 ft_strncmp( (
const char*)cur,
"StandardEncoding", 16 ) == 0 )
1341 else if ( cur + 15 < limit &&
1342 ft_strncmp( (
const char*)cur,
"ExpertEncoding", 14 ) == 0 )
1345 else if ( cur + 18 < limit &&
1346 ft_strncmp( (
const char*)cur,
"ISOLatin1Encoding", 17 ) == 0 )
1350 parser->root.error =
FT_ERR( Ignore );
1371 if ( parser->root.cursor < parser->root.limit &&
1372 *parser->root.cursor ==
'[' )
1376 if ( parser->root.cursor >= parser->root.limit ||
1377 *parser->root.cursor !=
']' )
1378 parser->root.error =
FT_THROW( Invalid_File_Format );
1386 if ( parser->root.error )
1392 if ( !loader->num_subrs )
1411 if ( parser->root.cursor + 4 >= parser->root.limit ||
1412 ft_strncmp( (
char*)parser->root.cursor,
"dup", 3 ) != 0 )
1427 if ( parser->root.error )
1431 if ( parser->root.cursor + 4 < parser->root.limit &&
1432 ft_strncmp( (
char*)parser->root.cursor,
"put", 3 ) == 0 )
1439 if ( loader->num_subrs )
1457 error =
FT_THROW( Invalid_File_Format );
1477 if ( !loader->num_subrs )
1478 loader->num_subrs = num_subrs;
1483 parser->root.error =
error;
1487 #define TABLE_EXTEND 5 1491 parse_charstrings(
T1_Face face,
1495 PS_Table code_table = &loader->charstrings;
1496 PS_Table name_table = &loader->glyph_names;
1497 PS_Table swap_table = &loader->swap_table;
1511 if ( num_glyphs < 0 )
1513 error =
FT_THROW( Invalid_File_Format );
1519 if ( num_glyphs == 0 || parser->root.error )
1529 if ( !loader->num_glyphs )
1562 cur = parser->root.cursor;
1569 if ( cur[0] ==
'd' &&
1587 if ( cur[0] ==
'e' &&
1594 if ( parser->root.error )
1602 if ( cur + 1 >=
limit )
1604 error =
FT_THROW( Invalid_File_Format );
1609 len = parser->root.cursor - cur;
1617 if ( loader->num_glyphs )
1625 name_table->elements[
n][
len] =
'\0';
1630 (
const char*)(name_table->elements[n]) ) == 0 )
1644 error =
FT_THROW( Invalid_File_Format );
1667 loader->num_glyphs =
n;
1670 if ( notdef_found &&
1671 ft_strcmp(
".notdef", (
const char*)name_table->elements[0] ) )
1681 name_table->elements[0],
1682 name_table->lengths [0] );
1688 code_table->elements[0],
1689 code_table->lengths [0] );
1695 name_table->elements[notdef_index],
1696 name_table->lengths [notdef_index] );
1702 code_table->elements[notdef_index],
1703 code_table->lengths [notdef_index] );
1708 swap_table->elements[0],
1709 swap_table->lengths [0] );
1714 swap_table->elements[1],
1715 swap_table->lengths [1] );
1720 swap_table->elements[2],
1721 swap_table->lengths [2] );
1726 swap_table->elements[3],
1727 swap_table->lengths [3] );
1732 else if ( !notdef_found )
1740 FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
1741 char* notdef_name = (
char *)
".notdef";
1745 name_table->elements[0],
1746 name_table->lengths [0] );
1751 code_table->elements[0],
1752 code_table->lengths [0] );
1760 error =
T1_Add_Table( code_table, 0, notdef_glyph, 5 );
1766 swap_table->elements[0],
1767 swap_table->lengths [0] );
1772 swap_table->elements[1],
1773 swap_table->lengths [1] );
1778 loader->num_glyphs += 1;
1784 parser->root.error =
error;
1814 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 1831 #define T1_FIELD_COUNT \ 1832 ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) 1846 parser->root.cursor = base;
1847 parser->root.limit = base +
size;
1850 limit = parser->root.limit;
1854 while ( parser->root.cursor < limit )
1859 cur = parser->root.cursor;
1866 else if (
IS_PS_TOKEN( cur, limit,
"closefile" ) )
1871 else if (
IS_PS_TOKEN( cur, limit,
"FontDirectory" ) )
1873 if ( loader->keywords_encountered &
T1_PRIVATE )
1874 loader->keywords_encountered |=
1876 parser->root.cursor += 13;
1884 if ( parser->root.error )
1892 else if ( *cur ==
'R' && cur + 6 < limit && *(cur + 1) ==
'D' &&
1899 parser->root.cursor = start_binary;
1901 return FT_THROW( Invalid_File_Format );
1905 else if ( *cur ==
'-' && cur + 6 < limit && *(cur + 1) ==
'|' &&
1912 parser->root.cursor = start_binary;
1914 return FT_THROW( Invalid_File_Format );
1919 else if ( *cur ==
'/' && cur + 2 < limit )
1926 parser->root.cursor = cur;
1928 if ( parser->root.error )
1931 len = parser->root.cursor - cur;
1948 if ( cur[0] == name[0] &&
1980 ( loader->keywords_encountered &
T1_PRIVATE )
1984 if ( !( dict & keyword->
dict ) )
1986 FT_TRACE1((
"parse_dict: found `%s' but ignoring it" 1987 " since it is in the wrong dictionary\n",
1992 if ( !( loader->keywords_encountered &
1994 ft_strcmp( (
const char*)name,
"CharStrings" ) == 0 )
1996 parser->root.error = t1_load_keyword( face,
2001 if (
FT_ERR_EQ( parser->root.error, Ignore ) )
2004 return parser->root.error;
2019 if ( parser->root.error )
2028 return parser->root.error;
2039 loader->num_glyphs = 0;
2040 loader->num_chars = 0;
2043 loader->encoding_table.init = 0;
2044 loader->charstrings.init = 0;
2045 loader->glyph_names.init = 0;
2046 loader->subrs.init = 0;
2047 loader->swap_table.init = 0;
2048 loader->fontdata = 0;
2049 loader->keywords_encountered = 0;
2083 t1_init_loader( &loader, face );
2096 parser = &loader.parser;
2104 error = parse_dict( face, &loader,
2105 parser->base_dict, parser->base_len );
2113 error = parse_dict( face, &loader,
2114 parser->private_dict, parser->private_len );
2121 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 2128 FT_ERROR((
"T1_Open_Face(): /DesignVector contains %u entries " 2129 "while there are %u axes.\n",
2165 FT_ERROR((
"T1_Open_Face: cannot allocate BuildCharArray\n" ));
2180 if ( loader.subrs.init )
2182 loader.subrs.init = 0;
2185 type1->
subrs = loader.subrs.elements;
2186 type1->
subrs_len = loader.subrs.lengths;
2190 if ( !loader.charstrings.init )
2192 FT_ERROR((
"T1_Open_Face: no `/CharStrings' array in face\n" ));
2196 loader.charstrings.init = 0;
2205 loader.glyph_names.block = 0;
2206 loader.glyph_names.elements = 0;
2211 FT_Int charcode,
idx, min_char, max_char;
2225 for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
2227 type1->
encoding.char_index[charcode] = 0;
2228 type1->
encoding.char_name [charcode] = (
char *)
".notdef";
2230 char_name = loader.encoding_table.elements[charcode];
2232 for ( idx = 0; idx < type1->
num_glyphs; idx++ )
2236 (
const char*)glyph_name ) == 0 )
2239 type1->
encoding.char_name [charcode] = (
char*)glyph_name;
2244 (
const char*)glyph_name ) != 0 )
2246 if ( charcode < min_char )
2247 min_char = charcode;
2248 if ( charcode >= max_char )
2249 max_char = charcode + 1;
2256 type1->
encoding.code_first = min_char;
2257 type1->
encoding.code_last = max_char;
2258 type1->
encoding.num_chars = loader.num_chars;
2262 t1_done_loader( &loader );
#define FT_ALLOC(ptr, size)
T1_Finalize_Parser(T1_Parser parser)
FT_DivFix(FT_Long a, FT_Long b)
#define T1_Add_Table(p, i, o, l)
#define T1_MAX_MM_MAP_POINTS
PS_PrivateRec private_dict
FT_MM_Axis axis[T1_MAX_MM_AXIS]
#define FT_MEM_ZERO(dest, count)
PS_FontExtraRec font_extra
T1_New_Parser(T1_Parser parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux)
#define T1_Skip_Spaces(p)
PS_DesignMapRec design_map[T1_MAX_MM_AXIS]
T1_Set_MM_Blend(T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
#define T1_Release_Table(p)
return FT_THROW(Missing_Property)
FT_String * axis_names[T1_MAX_MM_AXIS]
FT_BEGIN_HEADER struct T1_EncodingRecRec_ * T1_Encoding
FT_BEGIN_HEADER struct FT_MM_Axis_ FT_MM_Axis
const PS_Table_FuncsRec * ps_table_funcs
T1_Set_Var_Design(T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
GLboolean GLboolean GLboolean b
FT_Fixed expansion_factor
#define T1_ToTokenArray(p, t, m, c)
FT_BEGIN_HEADER typedef unsigned char FT_Bool
#define FT_TRACE1(varformat)
GLenum GLuint GLint GLenum face
#define FT_ERROR(varformat)
#define FT_ASSERT(condition)
FT_UInt num_default_design_vector
T1_Set_MM_Design(T1_Face face, FT_UInt num_coords, FT_Long *coords)
#define T1_MAX_MM_DESIGNS
#define T1_ToFixedArray(p, m, f, t)
PS_Private privates[T1_MAX_MM_DESIGNS+1]
mm_weights_unmap(FT_Fixed *weights, FT_Fixed *axiscoords, FT_UInt axis_count)
FT_Byte * charstrings_block
#define T1_Load_Field_Table(p, f, o, m, pf)
struct T1_FieldRec_ * T1_Field
void(* t1_decrypt)(FT_Byte *buffer, FT_Offset length, FT_UShort seed)
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
FT_Fixed * default_weight_vector
#define IS_PS_TOKEN(cur, limit, token)
FT_BBox * bboxes[T1_MAX_MM_DESIGNS+1]
#define T1_Skip_PS_Token(p)
FT_BEGIN_HEADER struct T1_Loader_ * T1_Loader
#define T1_FIELD_CALLBACK(_ident, _name, _dict)
struct PSAux_ServiceRec_ * PSAux_Service
FT_PtrDist * charstrings_len
FT_BEGIN_HEADER struct T1_Loader_ T1_LoaderRec
struct FT_FaceRec_ * FT_Face
mm_axis_unmap(PS_DesignMap axismap, FT_Fixed ncv)
FT_Fixed * design_pos[T1_MAX_MM_DESIGNS]
PS_FontInfo font_infos[T1_MAX_MM_DESIGNS+1]
FT_Byte * glyph_names_block
T1_Done_Blend(T1_Face face)
T1_Get_Private_Dict(T1_Parser parser, PSAux_Service psaux)
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
T1_EncodingType encoding_type
#define FT_NEW_ARRAY(ptr, count)
GLuint const GLchar * name
FT_MulFix(FT_Long a, FT_Long b)
if(!abbox) return FT_THROW(Invalid_Argument)
typedefFT_BEGIN_HEADER struct PS_TableRec_ * PS_Table
#define FT_TRACE6(varformat)
#define T1_Load_Field(p, f, o, m, pf)
#define FT_SET_ERROR(expression)
T1_Field_ParseFunc reader
T1_Get_MM_Var(T1_Face face, FT_MM_Var **master)
T1_Open_Face(T1_Face face)
T1_FieldLocation location
GLuint GLuint GLsizei count
#define FT_MAKE_TAG(_x1, _x2, _x3, _x4)
FT_BEGIN_HEADER struct T1_ParserRec_ * T1_Parser
FT_Error(* init)(PS_Table table, FT_Int count, FT_Memory memory)
#define FT_MEM_COPY(dest, source, count)
T1_Get_Multi_Master(T1_Face face, FT_Multi_Master *master)
FT_Var_Named_Style * namedstyle
#define T1_FONTDIR_AFTER_PRIVATE
GLenum GLsizei GLenum GLenum const GLvoid * table
#define T1_FIELD_DICT_PRIVATE
#define T1_FIELD_DICT_FONTDICT