summaryrefslogtreecommitdiff
path: root/Build/source/libs/libttf/extend/ftxpost.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-16 00:09:26 +0000
committerKarl Berry <karl@freefriends.org>2006-01-16 00:09:26 +0000
commit6c0eafbb1395d426a72a74538e0b2a95e8344ca6 (patch)
tree2a5f80b80fc76086a2602b812c2a182d00f961b7 /Build/source/libs/libttf/extend/ftxpost.c
parent70f7efeb5c9965a63a4143ad1c1f473585dc364c (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.c523
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 */