3 This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5 Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6 the dvipdfmx project team.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
33 static const char *macglyphorder[258];
35 /* offset from begenning of the post table */
36 #define NAME_STR_OFFSET 32
39 read_v2_post_names (struct tt_post_table *post, sfnt *sfont)
41 USHORT i, idx, *indices, maxidx;
44 post->numberOfGlyphs = sfnt_get_ushort(sfont);
46 indices = NEW(post->numberOfGlyphs, USHORT);
49 i < post->numberOfGlyphs; i++) {
50 idx = sfnt_get_ushort(sfont);
55 /* Although this is strictly speaking out of spec, it seems to work
56 and there are real-life fonts that use it.
57 We show a warning only once, instead of thousands of times */
58 static char warning_issued = 0;
59 if (!warning_issued) {
60 WARN("TrueType post table name index %u > 32767", idx);
63 /* In a real-life large font, (x)dvipdfmx crashes if we use
64 nonvanishing idx in the case of idx > 32767.
65 If we set idx = 0, (x)dvipdfmx works fine for the font and
66 created pdf seems fine. The post table may not be important
74 post->count = maxidx - 257;
75 if (post->count < 1) {
78 post->names = NEW(post->count, char *);
79 for (i = 0; i < post->count; i++) { /* read Pascal strings */
80 len = sfnt_get_byte(sfont);
82 post->names[i] = NEW(len + 1, char);
83 sfnt_read(post->names[i], len, sfont);
84 post->names[i][len] = 0;
86 post->names[i] = NULL;
91 post->glyphNamePtr = NEW(post->numberOfGlyphs, const char *);
92 for (i = 0; i < post->numberOfGlyphs; i++) {
95 post->glyphNamePtr[i] = macglyphorder[idx];
96 } else if (idx - 258 < post->count) {
97 post->glyphNamePtr[i] = post->names[idx - 258];
99 WARN("Invalid glyph name index number: %u (>= %u)",
100 idx, post->count + 258);
110 struct tt_post_table *
111 tt_read_post_table (sfnt *sfont)
113 struct tt_post_table *post;
115 /* offset = */ sfnt_locate_table(sfont, "post");
117 post = NEW(1, struct tt_post_table);
119 post->Version = sfnt_get_ulong(sfont); /* Fixed */
120 post->italicAngle = sfnt_get_ulong(sfont); /* Fixed */
121 post->underlinePosition = sfnt_get_short(sfont); /* FWord */
122 post->underlineThickness = sfnt_get_short(sfont); /* FWord */
123 post->isFixedPitch = sfnt_get_ulong(sfont);
124 post->minMemType42 = sfnt_get_ulong(sfont);
125 post->maxMemType42 = sfnt_get_ulong(sfont);
126 post->minMemType1 = sfnt_get_ulong(sfont);
127 post->maxMemType1 = sfnt_get_ulong(sfont);
129 post->numberOfGlyphs = 0;
130 post->glyphNamePtr = NULL;
134 if (post->Version == 0x00010000UL) {
135 post->numberOfGlyphs = 258; /* wrong */
136 post->glyphNamePtr = macglyphorder;
139 } else if (post->Version == 0x00025000UL) {
140 WARN("TrueType 'post' version 2.5 found (deprecated)");
141 post->numberOfGlyphs = 0; /* wrong */
142 post->glyphNamePtr = NULL;
145 } else if (post->Version == 0x00020000UL) {
146 if (read_v2_post_names(post, sfont) < 0) {
147 WARN("Invalid TrueType 'post' table...");
148 tt_release_post_table(post);
151 } else if (post->Version == 0x00030000UL) {
152 post->numberOfGlyphs = 0; /* wrong */
153 post->glyphNamePtr = NULL;
157 WARN("Unknown 'post' version: %08X", post->Version);
158 tt_release_post_table(post);
166 tt_lookup_post_table (struct tt_post_table *post, const char *glyphname)
170 ASSERT(post && glyphname);
172 for (gid = 0; gid < post->count; gid++) {
173 if (post->glyphNamePtr[gid] &&
174 !strcmp(glyphname, post->glyphNamePtr[gid])) {
183 tt_release_post_table (struct tt_post_table *post)
189 if (post->glyphNamePtr && post->Version != 0x00010000UL)
190 RELEASE((void *)post->glyphNamePtr);
192 for (i = 0; i < post->count; i++) {
194 RELEASE(post->names[i]);
196 RELEASE(post->names);
199 post->glyphNamePtr = NULL;
207 /* Macintosh glyph order - from apple's TTRefMan */
209 macglyphorder[258] = {
211 ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl",
212 "numbersign", "dollar", "percent", "ampersand", "quotesingle",
213 "parenleft", "parenright", "asterisk", "plus", "comma",
215 "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
216 "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
218 "equal", "greater", "question", "at", "A", "B", "C", "D",
219 "E", "F", "G", "H", "I", "J", "K", "L",
221 "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
222 "Y", "Z", "bracketleft", "backslash",
224 "bracketright", "asciicircum", "underscore", "grave",
225 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
227 "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
228 "y", "z", "braceleft", "bar",
230 "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla",
231 "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave",
232 "acircumflex", "adieresis", "atilde", "aring", "ccedilla",
234 "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave",
235 "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex",
236 "odieresis", "otilde", "uacute", "ugrave",
238 "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
239 "section", "bullet", "paragraph", "germandbls", "registered",
240 "copyright", "trademark", "acute", "dieresis", "notequal",
242 "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
243 "yen", "mu", "partialdiff", "summation", "product", "pi", "integral",
244 "ordfeminine", "ordmasculine", "Omega",
246 "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical",
247 "florin", "approxequal", "Delta", "guillemotleft", "guillemotright",
248 "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde",
250 "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright",
251 "quoteleft", "quoteright", "divide", "lozenge", "ydieresis",
252 "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright",
254 "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase",
255 "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute",
256 "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave",
258 "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex",
259 "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve",
260 "dotaccent", "ring", "cedilla", "hungarumlaut",
262 "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron",
263 "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn",
266 "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
267 "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent",
268 "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron",