33#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
47#define FT_COMPONENT ttpost
53#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
58#define MAC_NAME( x ) (FT_String*)psnames->macintosh_name( (FT_UInt)(x) )
68#define MAC_NAME( x ) (FT_String*)tt_post_default_names[x]
72 static const FT_String*
const tt_post_default_names[258] =
75 ".notdef",
".null",
"nonmarkingreturn",
"space",
"exclam",
76 "quotedbl",
"numbersign",
"dollar",
"percent",
"ampersand",
78 "quotesingle",
"parenleft",
"parenright",
"asterisk",
"plus",
79 "comma",
"hyphen",
"period",
"slash",
"zero",
81 "one",
"two",
"three",
"four",
"five",
82 "six",
"seven",
"eight",
"nine",
"colon",
84 "semicolon",
"less",
"equal",
"greater",
"question",
85 "at",
"A",
"B",
"C",
"D",
87 "E",
"F",
"G",
"H",
"I",
88 "J",
"K",
"L",
"M",
"N",
90 "O",
"P",
"Q",
"R",
"S",
91 "T",
"U",
"V",
"W",
"X",
93 "Y",
"Z",
"bracketleft",
"backslash",
"bracketright",
94 "asciicircum",
"underscore",
"grave",
"a",
"b",
96 "c",
"d",
"e",
"f",
"g",
97 "h",
"i",
"j",
"k",
"l",
99 "m",
"n",
"o",
"p",
"q",
100 "r",
"s",
"t",
"u",
"v",
102 "w",
"x",
"y",
"z",
"braceleft",
103 "bar",
"braceright",
"asciitilde",
"Adieresis",
"Aring",
105 "Ccedilla",
"Eacute",
"Ntilde",
"Odieresis",
"Udieresis",
106 "aacute",
"agrave",
"acircumflex",
"adieresis",
"atilde",
108 "aring",
"ccedilla",
"eacute",
"egrave",
"ecircumflex",
109 "edieresis",
"iacute",
"igrave",
"icircumflex",
"idieresis",
111 "ntilde",
"oacute",
"ograve",
"ocircumflex",
"odieresis",
112 "otilde",
"uacute",
"ugrave",
"ucircumflex",
"udieresis",
114 "dagger",
"degree",
"cent",
"sterling",
"section",
115 "bullet",
"paragraph",
"germandbls",
"registered",
"copyright",
117 "trademark",
"acute",
"dieresis",
"notequal",
"AE",
118 "Oslash",
"infinity",
"plusminus",
"lessequal",
"greaterequal",
120 "yen",
"mu",
"partialdiff",
"summation",
"product",
121 "pi",
"integral",
"ordfeminine",
"ordmasculine",
"Omega",
123 "ae",
"oslash",
"questiondown",
"exclamdown",
"logicalnot",
124 "radical",
"florin",
"approxequal",
"Delta",
"guillemotleft",
126 "guillemotright",
"ellipsis",
"nonbreakingspace",
"Agrave",
"Atilde",
127 "Otilde",
"OE",
"oe",
"endash",
"emdash",
129 "quotedblleft",
"quotedblright",
"quoteleft",
"quoteright",
"divide",
130 "lozenge",
"ydieresis",
"Ydieresis",
"fraction",
"currency",
132 "guilsinglleft",
"guilsinglright",
"fi",
"fl",
"daggerdbl",
133 "periodcentered",
"quotesinglbase",
"quotedblbase",
"perthousand",
"Acircumflex",
135 "Ecircumflex",
"Aacute",
"Edieresis",
"Egrave",
"Iacute",
136 "Icircumflex",
"Idieresis",
"Igrave",
"Oacute",
"Ocircumflex",
138 "apple",
"Ograve",
"Uacute",
"Ucircumflex",
"Ugrave",
139 "dotlessi",
"circumflex",
"tilde",
"macron",
"breve",
141 "dotaccent",
"ring",
"cedilla",
"hungarumlaut",
"ogonek",
142 "caron",
"Lslash",
"lslash",
"Scaron",
"scaron",
144 "Zcaron",
"zcaron",
"brokenbar",
"Eth",
"eth",
145 "Yacute",
"yacute",
"Thorn",
"thorn",
"minus",
147 "multiply",
"onesuperior",
"twosuperior",
"threesuperior",
"onehalf",
148 "onequarter",
"threequarters",
"franc",
"Gbreve",
"gbreve",
150 "Idotaccent",
"Scedilla",
"scedilla",
"Cacute",
"cacute",
151 "Ccaron",
"ccaron",
"dcroat",
159 load_format_20( TT_Post_Names names,
161 FT_UShort num_glyphs,
164 FT_Memory memory = stream->memory;
168 FT_UShort num_names = 0;
170 FT_UShort* glyph_indices = NULL;
171 FT_Byte** name_strings = NULL;
175 if ( (FT_ULong)num_glyphs * 2 > post_len )
177 error = FT_THROW( Invalid_File_Format );
182 if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
183 FT_FRAME_ENTER( num_glyphs * 2 ) )
186 q = (FT_Byte*)stream->cursor;
188 for ( n = 0; n < num_glyphs; n++ )
190 FT_UShort idx = FT_NEXT_USHORT( q );
193 if ( idx > num_names )
196 glyph_indices[n] = idx;
202 num_names = num_names > 257 ? num_names - 257 : 0;
211 post_len -= (FT_ULong)num_glyphs * 2;
213 if ( FT_QALLOC( name_strings, num_names *
sizeof ( FT_Byte* ) +
217 p = (FT_Byte*)( name_strings + num_names );
218 if ( FT_STREAM_READ( p, post_len ) )
221 p_end = p + post_len;
224 for ( n = 0; p < p_end && n < num_names; n++ )
231 FT_TRACE4((
"load_format_20: unusual %u-char name found\n", len ));
242 FT_TRACE4((
"load_format_20: %hu PostScript names are truncated\n",
243 (FT_UShort)( num_names - n ) ));
245 for ( ; n < num_names; n++ )
246 name_strings[n] = p_end;
251 names->num_glyphs = num_glyphs;
252 names->num_names = num_names;
253 names->glyph_indices = glyph_indices;
254 names->glyph_names = name_strings;
259 FT_FREE( name_strings );
260 FT_FREE( glyph_indices );
268 load_format_25( TT_Post_Names names,
270 FT_UShort num_glyphs,
273 FT_Memory memory = stream->memory;
277 FT_UShort* glyph_indices = NULL;
282 if ( num_glyphs > post_len ||
283 num_glyphs > 258 + 128 )
285 error = FT_THROW( Invalid_File_Format );
290 if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
291 FT_FRAME_ENTER( num_glyphs ) )
294 q = (FT_Byte*)stream->cursor;
296 for ( n = 0; n < num_glyphs; n++ )
298 FT_Int idx = n + FT_NEXT_CHAR( q );
301 if ( idx < 0 || idx > 257 )
304 glyph_indices[n] = (FT_UShort)idx;
310 names->num_glyphs = num_glyphs;
311 names->glyph_indices = glyph_indices;
316 FT_FREE( glyph_indices );
324 load_post_names( TT_Face face )
326 FT_Error error = FT_Err_Ok;
327 FT_Stream stream = face->root.stream;
328 FT_Fixed format = face->postscript.FormatType;
330 FT_UShort num_glyphs;
334 error = face->goto_table( face, TTAG_post, stream, &post_len );
340 if ( post_len < 34 ||
341 FT_STREAM_SKIP( 32 ) ||
342 FT_READ_USHORT( num_glyphs ) ||
343 num_glyphs > face->max_profile.numGlyphs ||
348 if ( format == 0x00020000L )
349 error = load_format_20( &face->postscript_names, stream,
350 num_glyphs, post_len - 34 );
351 else if ( format == 0x00025000L )
352 error = load_format_25( &face->postscript_names, stream,
353 num_glyphs, post_len - 34 );
356 face->postscript_names.loaded = 1;
362 tt_face_free_ps_names( TT_Face face )
364 FT_Memory memory = face->root.memory;
365 TT_Post_Names names = &face->postscript_names;
368 if ( names->num_glyphs )
370 FT_FREE( names->glyph_indices );
371 names->num_glyphs = 0;
374 if ( names->num_names )
376 FT_FREE( names->glyph_names );
377 names->num_names = 0;
409 FT_LOCAL_DEF( FT_Error )
410 tt_face_get_ps_name( TT_Face face,
417#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
418 FT_Service_PsCMaps psnames;
423 return FT_THROW( Invalid_Face_Handle );
425 if ( idx >= (FT_UInt)face->max_profile.numGlyphs )
426 return FT_THROW( Invalid_Glyph_Index );
428#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
429 psnames = (FT_Service_PsCMaps)face->psnames;
431 return FT_THROW( Unimplemented_Feature );
435 *PSname = MAC_NAME( 0 );
437 format = face->postscript.FormatType;
439 if ( format == 0x00020000L ||
440 format == 0x00025000L )
442 TT_Post_Names names = &face->postscript_names;
445 if ( !names->loaded )
447 error = load_post_names( face );
452 if ( idx < (FT_UInt)names->num_glyphs )
454 FT_UShort name_index = names->glyph_indices[idx];
457 if ( name_index < 258 )
458 *PSname = MAC_NAME( name_index );
460 *PSname = (FT_String*)names->glyph_names[name_index - 258];
465 else if ( format == 0x00010000L &&
466 face->max_profile.numGlyphs == 258 )
467 *PSname = MAC_NAME( idx );
479 typedef int tt_post_dummy_;