diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-16 00:09:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-16 00:09:26 +0000 |
commit | 6c0eafbb1395d426a72a74538e0b2a95e8344ca6 (patch) | |
tree | 2a5f80b80fc76086a2602b812c2a182d00f961b7 /Build/source/libs/libttf/extend/ftxpost.c | |
parent | 70f7efeb5c9965a63a4143ad1c1f473585dc364c (diff) |
libs 1
git-svn-id: svn://tug.org/texlive/trunk@1483 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/libttf/extend/ftxpost.c')
-rw-r--r-- | Build/source/libs/libttf/extend/ftxpost.c | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/Build/source/libs/libttf/extend/ftxpost.c b/Build/source/libs/libttf/extend/ftxpost.c new file mode 100644 index 00000000000..8b2ac5940c0 --- /dev/null +++ b/Build/source/libs/libttf/extend/ftxpost.c @@ -0,0 +1,523 @@ +/******************************************************************* + * + * ftxpost.c + * + * post table support API extension body + * + * Copyright 1996-1999 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. + * + * + * The post table is not completely loaded by the core engine. This + * file loads the missing PS glyph names and implements an API to + * access them. + * + ******************************************************************/ + +#include "ttconfig.h" +#include "ftxpost.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" +#include "ttload.h" /* for the macros */ +#include "ttfile.h" +#include "tttags.h" +#include "ttmemory.h" +#include "ttextend.h" + + +#define POST_ID Build_Extension_ID( 'p', 'o', 's', 't' ) + + + /* the 258 default Mac PS glyph names */ + + String* TT_Post_Default_Names[258] = + { + /* 0 */ + ".notdef", ".null", "CR", "space", "exclam", + "quotedbl", "numbersign", "dollar", "percent", "ampersand", + /* 10 */ + "quotesingle", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", + /* 20 */ + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", + /* 30 */ + "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", + /* 40 */ + "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", + /* 50 */ + "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", + /* 60 */ + "Y", "Z", "bracketleft", "backslash", "bracketright", + "asciicircum", "underscore", "grave", "a", "b", + /* 70 */ + "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", + /* 80 */ + "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", + /* 90 */ + "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", "Aring", + /* 100 */ + "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", + "aacute", "agrave", "acircumflex", "adieresis", "atilde", + /* 110 */ + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", "idieresis", + /* 120 */ + "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", + "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", + /* 130 */ + "dagger", "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", "copyright", + /* 140 */ + "trademark", "acute", "dieresis", "notequal", "AE", + "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + /* 150 */ + "yen", "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", "Omega", + /* 160 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + /* 170 */ + "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", "emdash", + /* 180 */ + "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", + "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", + /* 190 */ + "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", + /* 200 */ + "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", + /* 210 */ + "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", "breve", + /* 220 */ + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", + "caron", "Lslash", "lslash", "Scaron", "scaron", + /* 230 */ + "Zcaron", "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", "minus", + /* 240 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", + /* 250 */ + "Idot", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron", + }; + + + + static TT_Error Load_Format_20( TT_Post_20* post20, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort nameindex, n, num; + Byte len; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + num = GET_UShort(); + + FORGET_Frame(); + + /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ + /* than the value in the maxp table (cf. cyberbit.ttf). */ + + /* There already exist fonts which have more than 32768 glyph names */ + /* in this table, so the test for this threshold has been dropped. */ + if ( num > input->numGlyphs ) + return TT_Err_Invalid_Post_Table; + + post20->numGlyphs = num; + + if ( ALLOC_ARRAY( post20->glyphNameIndex, num, TT_UShort ) ) + return error; + + if ( ACCESS_Frame( num * 2L ) ) + goto Fail; + + for ( n = 0; n < num; n++ ) + { + post20->glyphNameIndex[n] = GET_UShort(); + + if ( post20->glyphNameIndex[n] > 258 + num ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Post_Table; + goto Fail; + } + } + + FORGET_Frame(); + + if ( ALLOC_ARRAY( post20->glyphNames, num, Char* ) ) + goto Fail; + + /* We must initialize the glyphNames array for proper */ + /* deallocation. */ + for ( n = 0; n < num; n++ ) + post20->glyphNames[n] = NULL; + + /* Now we can read the glyph names which are stored in */ + /* Pascal string format. */ + for ( n = 0; n < num; n++ ) + { + nameindex = post20->glyphNameIndex[n]; + + if ( nameindex < 258 ) + ; /* default Mac glyph, do nothing */ + else + { + if ( ACCESS_Frame( 1L ) ) + goto Fail1; + + len = GET_Byte(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( post20->glyphNames[nameindex - 258], + len + 1, Char ) || + FILE_Read( post20->glyphNames[nameindex - 258], len ) ) + goto Fail1; + + /* we make a C string */ + post20->glyphNames[nameindex - 258][len] = '\0'; + } + } + + return TT_Err_Ok; + + + Fail1: + for ( n = 0; n < num; n++ ) + if ( post20->glyphNames[n] ) + FREE( post20->glyphNames[n] ); + + FREE( post20->glyphNames ); + + Fail: + FREE( post20->glyphNameIndex ); + return error; + } + + + static TT_Error Load_Format_25( TT_Post_25* post25, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, num; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ + num = GET_UShort(); + + FORGET_Frame(); + + if ( num > input->numGlyphs || num > 258 ) + return TT_Err_Invalid_Post_Table; + + post25->numGlyphs = num; + + if ( ALLOC_ARRAY( post25->offset, num, Char ) ) + return error; + + if ( ACCESS_Frame( num ) ) + goto Fail; + + for ( n = 0; n < num; n++ ) + { + post25->offset[n] = GET_Char(); + + /* We add 128 to the tests to avoid problems with negative */ + /* values for comparison. */ + if ( n + ( post25->offset[n] + 128 ) > num + 128 || + n + ( post25->offset[n] + 128 ) < 128 ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Post_Table; + goto Fail; + } + } + + FORGET_Frame(); + + return TT_Err_Ok; + + + Fail: + FREE( post25->offset ); + return error; + } + + + static TT_Error Post_Create( void* ext, + PFace face ) + { + TT_Post* post = (TT_Post*)ext; + Long table; + + + /* by convention */ + if ( !post ) + return TT_Err_Ok; + + /* we store the start offset and the size of the subtable */ + table = TT_LookUp_Table( face, TTAG_post ); + post->offset = face->dirTables[table].Offset + 32L; + post->length = face->dirTables[table].Length - 32L; + post->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error Post_Destroy( void* ext, + PFace face ) + { + TT_Post* post = (TT_Post*)ext; + UShort n; + + + /* by convention */ + if ( !post ) + return TT_Err_Ok; + + if ( post->loaded ) + { + switch ( face->postscript.FormatType ) + { + case 0x00010000: /* nothing to do */ + break; + + case 0x00020000: + for ( n = 0; n < post->p.post20.numGlyphs; n++ ) + if ( post->p.post20.glyphNames[n] ) + FREE( post->p.post20.glyphNames[n] ); + FREE( post->p.post20.glyphNames ); + FREE( post->p.post20.glyphNameIndex ); + break; + + case 0x00028000: + FREE( post->p.post25.offset ); + break; + + case 0x00030000: /* nothing to do */ + break; + +#if 0 + case 0x00040000: + break; +#endif + + default: + ; /* invalid format, do nothing */ + } + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_Post_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + POST_ID, + sizeof ( TT_Post ), + Post_Create, + Post_Destroy ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Load_PS_Names + * + * Description : Loads the PostScript Glyph Name subtable (if any). + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_PS_Names( TT_Face face, + TT_Post* ppost ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Stream stream; + TT_Post* post; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, POST_ID, (void**)&post ); + if ( error ) + return error; + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + + switch ( faze->postscript.FormatType ) + { + case 0x00010000: + error = TT_Err_Ok; /* nothing to do */ + break; + + case 0x00020000: + if ( FILE_Seek( post->offset ) ) + goto Fail; + + error = Load_Format_20( &post->p.post20, faze ); + break; + + case 0x00028000: /* 2.5 in 16.16 format */ + if ( FILE_Seek( post->offset ) ) + goto Fail; + + error = Load_Format_25( &post->p.post25, faze ); + break; + + case 0x00030000: + error = TT_Err_Ok; /* nothing to do */ + break; + +#if 0 + case 0x00040000: + break; +#endif + + default: + error = TT_Err_Invalid_Post_Table_Format; + break; + } + + if ( !error ) + { + post->loaded = TRUE; + *ppost = *post; + } + + + Fail: + DONE_Stream( stream ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Get_PS_Name + * + * Description : Gets the PostScript Glyph Name of a glyph. + * + * Input : index glyph index + * PSname address of a string pointer. + * Will be NULL in case of error; otherwise it + * contains a pointer to the glyph name. + * + * You must not modify the returned string! + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Post* post; + UShort nameindex; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( index >= faze->numGlyphs ) + return TT_Err_Invalid_Glyph_Index; + + error = TT_Extension_Get( faze, POST_ID, (void**)&post ); + if ( error ) + return error; + + + *PSname = TT_Post_Default_Names[0]; /* default value */ + + switch ( faze->postscript.FormatType ) + { + case 0x00010000: + if ( index < 258 ) /* paranoid checking */ + *PSname = TT_Post_Default_Names[index]; + break; + + case 0x00020000: + if ( index < post->p.post20.numGlyphs ) + nameindex = post->p.post20.glyphNameIndex[index]; + else + break; + + if ( nameindex < 258 ) + *PSname = TT_Post_Default_Names[nameindex]; + else + *PSname = (String*)post->p.post20.glyphNames[nameindex - 258]; + break; + + case 0x00028000: + if ( index < post->p.post25.numGlyphs ) /* paranoid checking */ + *PSname = TT_Post_Default_Names[index + post->p.post25.offset[index]]; + break; + + case 0x00030000: + break; /* nothing to do */ + +#if 0 + case 0x00040000: + break; +#endif + + default: + ; /* should never happen */ + } + + return TT_Err_Ok; + } + + +/* END */ |