1
/* $Header: /home/cvsroot/dvipdfmx/src/tt_table.c,v 1.11 2009/05/02 12:16:32 chofchof Exp $
3
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5
Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
6
the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
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.
34
tables contains information refered by other tables
35
maxp->numGlyphs, etc --> loca, etc
36
hhea->numOfLongHorMetrics --> hmtx
37
head->indexToLocFormat --> loca
38
head->glyphDataFormat --> glyf
41
char *tt_pack_head_table (struct tt_head_table *table)
47
ERROR("passed NULL pointer\n");
49
p = data = NEW(TT_HEAD_TABLE_SIZE, char);
50
p += sfnt_put_ulong(p, table->version);
51
p += sfnt_put_ulong(p, table->fontRevision);
52
p += sfnt_put_ulong(p, table->checkSumAdjustment);
53
p += sfnt_put_ulong(p, table->magicNumber);
54
p += sfnt_put_ushort(p, table->flags);
55
p += sfnt_put_ushort(p, table->unitsPerEm);
57
*(p++) = (table->created)[i];
60
*(p++) = (table->modified)[i];
62
p += sfnt_put_short(p, table->xMin);
63
p += sfnt_put_short(p, table->yMin);
64
p += sfnt_put_short(p, table->xMax);
65
p += sfnt_put_short(p, table->yMax);
66
p += sfnt_put_ushort(p, table->macStyle);
67
p += sfnt_put_ushort(p, table->lowestRecPPEM);
68
p += sfnt_put_short(p, table->fontDirectionHint);
69
p += sfnt_put_short(p, table->indexToLocFormat);
70
p += sfnt_put_short(p, table->glyphDataFormat);
75
struct tt_head_table *tt_read_head_table (sfnt *sfont)
78
struct tt_head_table *table = NULL;
80
sfnt_locate_table(sfont, "head");
82
table = NEW(1, struct tt_head_table);
83
table->version = sfnt_get_ulong(sfont);
84
table->fontRevision = sfnt_get_ulong(sfont);
85
table->checkSumAdjustment = sfnt_get_ulong(sfont);
86
table->magicNumber = sfnt_get_ulong(sfont);
87
table->flags = sfnt_get_ushort(sfont);
88
table->unitsPerEm = sfnt_get_ushort(sfont);
90
(table->created)[i] = sfnt_get_byte (sfont);
93
(table->modified)[i] = sfnt_get_byte (sfont);
95
table->xMin = sfnt_get_short(sfont);
96
table->yMin = sfnt_get_short(sfont);
97
table->xMax = sfnt_get_short(sfont);
98
table->yMax = sfnt_get_short(sfont);
99
table->macStyle = sfnt_get_short(sfont);
100
table->lowestRecPPEM = sfnt_get_short(sfont);
101
table->fontDirectionHint = sfnt_get_short(sfont);
102
table->indexToLocFormat = sfnt_get_short(sfont);
103
table->glyphDataFormat = sfnt_get_short(sfont);
108
char *tt_pack_maxp_table (struct tt_maxp_table *table)
112
p = data = NEW(TT_MAXP_TABLE_SIZE, char);
113
p += sfnt_put_ulong(p, table->version);
114
p += sfnt_put_ushort(p, table->numGlyphs);
115
p += sfnt_put_ushort(p, table->maxPoints);
116
p += sfnt_put_ushort(p, table->maxContours);
117
p += sfnt_put_ushort(p, table->maxComponentPoints);
118
p += sfnt_put_ushort(p, table->maxComponentContours);
119
p += sfnt_put_ushort(p, table->maxZones);
120
p += sfnt_put_ushort(p, table->maxTwilightPoints);
121
p += sfnt_put_ushort(p, table->maxStorage);
122
p += sfnt_put_ushort(p, table->maxFunctionDefs);
123
p += sfnt_put_ushort(p, table->maxInstructionDefs);
124
p += sfnt_put_ushort(p, table->maxStackElements);
125
p += sfnt_put_ushort(p, table->maxSizeOfInstructions);
126
p += sfnt_put_ushort(p, table->maxComponentElements);
127
p += sfnt_put_ushort(p, table->maxComponentDepth);
132
struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont)
134
struct tt_maxp_table *table = NULL;
136
sfnt_locate_table(sfont, "maxp");
138
table = NEW(1, struct tt_maxp_table);
139
table->version = sfnt_get_ulong(sfont);
140
table->numGlyphs = sfnt_get_ushort(sfont);
141
table->maxPoints = sfnt_get_ushort(sfont);
142
table->maxContours = sfnt_get_ushort(sfont);
143
table->maxComponentPoints = sfnt_get_ushort(sfont);
144
table->maxComponentContours = sfnt_get_ushort(sfont);
145
table->maxZones = sfnt_get_ushort(sfont);
146
table->maxTwilightPoints = sfnt_get_ushort(sfont);
147
table->maxStorage = sfnt_get_ushort(sfont);
148
table->maxFunctionDefs = sfnt_get_ushort(sfont);
149
table->maxInstructionDefs = sfnt_get_ushort(sfont);
150
table->maxStackElements = sfnt_get_ushort(sfont);
151
table->maxSizeOfInstructions = sfnt_get_ushort(sfont);
152
table->maxComponentElements = sfnt_get_ushort(sfont);
153
table->maxComponentDepth = sfnt_get_ushort(sfont);
158
char *tt_pack_hhea_table (struct tt_hhea_table *table)
163
p = data = NEW(TT_HHEA_TABLE_SIZE, char);
164
p += sfnt_put_ulong(p, table->version);
165
p += sfnt_put_short(p, table->ascent);
166
p += sfnt_put_short(p, table->descent);
167
p += sfnt_put_short(p, table->lineGap);
168
p += sfnt_put_ushort(p, table->advanceWidthMax);
169
p += sfnt_put_short(p, table->minLeftSideBearing);
170
p += sfnt_put_short(p, table->minRightSideBearing);
171
p += sfnt_put_short(p, table->xMaxExtent);
172
p += sfnt_put_short(p, table->caretSlopeRise);
173
p += sfnt_put_short(p, table->caretSlopeRun);
174
p += sfnt_put_short(p, table->caretOffset);
175
for (i = 0; i < 4; i++) {
176
p += sfnt_put_short(p, table->reserved[i]);
178
p += sfnt_put_short(p, table->metricDataFormat);
179
p += sfnt_put_ushort(p, table->numOfLongHorMetrics);
184
struct tt_hhea_table *
185
tt_read_hhea_table (sfnt *sfont)
189
struct tt_hhea_table *table = NULL;
191
sfnt_locate_table(sfont, "hhea");
193
table = NEW(1, struct tt_hhea_table);
194
table->version = sfnt_get_ulong(sfont);
195
table->ascent = sfnt_get_short (sfont);
196
table->descent = sfnt_get_short(sfont);
197
table->lineGap = sfnt_get_short(sfont);
198
table->advanceWidthMax = sfnt_get_ushort(sfont);
199
table->minLeftSideBearing = sfnt_get_short(sfont);
200
table->minRightSideBearing = sfnt_get_short(sfont);
201
table->xMaxExtent = sfnt_get_short(sfont);
202
table->caretSlopeRise = sfnt_get_short(sfont);
203
table->caretSlopeRun = sfnt_get_short(sfont);
204
table->caretOffset = sfnt_get_short(sfont);
205
for(i = 0; i < 4; i++) {
206
table->reserved[i] = sfnt_get_short(sfont);
208
table->metricDataFormat = sfnt_get_short(sfont);
209
if (table->metricDataFormat != 0)
210
ERROR("unknown metricDaraFormat");
211
table->numOfLongHorMetrics = sfnt_get_ushort(sfont);
213
len = sfnt_find_table_len(sfont, "hmtx");
214
table->numOfExSideBearings = (USHORT)((len - table->numOfLongHorMetrics * 4) / 2);
222
tt_pack_vhea_table (struct tt_vhea_table *table)
227
p = data = NEW(TT_VHEA_TABLE_SIZE, char);
228
p += sfnt_put_ulong(p, table->version);
229
p += sfnt_put_short(p, table->vertTypoAscender);
230
p += sfnt_put_short(p, table->vertTypoDescender);
231
p += sfnt_put_short(p, table->vertTypoLineGap);
232
p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */
233
p += sfnt_put_short(p, table->minTopSideBearing);
234
p += sfnt_put_short(p, table->minBottomSideBearing);
235
p += sfnt_put_short(p, table->yMaxExtent);
236
p += sfnt_put_short(p, table->caretSlopeRise);
237
p += sfnt_put_short(p, table->caretSlopeRun);
238
p += sfnt_put_short(p, table->caretOffset);
239
for(i = 0; i < 4; i++) {
240
p += sfnt_put_short(p, table->reserved[i]);
242
p += sfnt_put_short(p, table->metricDataFormat);
243
p += sfnt_put_ushort(p, table->numOfLongVerMetrics);
249
struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont)
253
struct tt_vhea_table *table = NULL;
255
sfnt_locate_table(sfont, "vhea");
257
table = NEW(1, struct tt_vhea_table);
258
table->version = sfnt_get_ulong(sfont);
259
table->vertTypoAscender = sfnt_get_short (sfont);
260
table->vertTypoDescender = sfnt_get_short(sfont);
261
table->vertTypoLineGap = sfnt_get_short(sfont);
262
table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */
263
table->minTopSideBearing = sfnt_get_short(sfont);
264
table->minBottomSideBearing = sfnt_get_short(sfont);
265
table->yMaxExtent = sfnt_get_short(sfont);
266
table->caretSlopeRise = sfnt_get_short(sfont);
267
table->caretSlopeRun = sfnt_get_short(sfont);
268
table->caretOffset = sfnt_get_short(sfont);
269
for(i = 0; i < 4; i++) {
270
(table->reserved)[i] = sfnt_get_short(sfont);
272
table->metricDataFormat = sfnt_get_short(sfont);
273
table->numOfLongVerMetrics = sfnt_get_ushort(sfont);
275
len = sfnt_find_table_len(sfont, "vmtx");
276
table->numOfExSideBearings = (USHORT)((len - table->numOfLongVerMetrics * 4) / 2);
282
struct tt_VORG_table *
283
tt_read_VORG_table (sfnt *sfont)
285
struct tt_VORG_table *vorg;
289
offset = sfnt_find_table_pos(sfont, "VORG");
292
vorg = NEW(1, struct tt_VORG_table);
294
sfnt_locate_table(sfont, "VORG");
295
if (sfnt_get_ushort(sfont) != 1 ||
296
sfnt_get_ushort(sfont) != 0)
297
ERROR("Unsupported VORG version.");
299
vorg->defaultVertOriginY = sfnt_get_short(sfont);
300
vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont);
301
vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics,
302
struct tt_vertOriginYMetrics);
304
* The vertOriginYMetrics array must be sorted in increasing
308
i < vorg->numVertOriginYMetrics; i++) {
309
vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont);
310
vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont);
322
* Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea.
325
struct tt_longMetrics *
326
tt_read_longMetrics (sfnt *sfont, USHORT numGlyphs, USHORT numLongMetrics, USHORT numExSideBearings)
328
struct tt_longMetrics *m;
329
USHORT gid, last_adv = 0;
332
m = NEW(numGlyphs, struct tt_longMetrics);
333
for (gid = 0; gid < numGlyphs; gid++) {
334
if (gid < numLongMetrics)
335
last_adv = sfnt_get_ushort(sfont);
336
if (gid < numLongMetrics + numExSideBearings)
337
last_esb = sfnt_get_short(sfont);
338
m[gid].advance = last_adv;
339
m[gid].sideBearing = last_esb;
346
/* this table may not exist */
347
struct tt_os2__table *
348
tt_read_os2__table (sfnt *sfont)
350
struct tt_os2__table *table = NULL;
353
table = NEW(1, struct tt_os2__table);
355
if (sfnt_find_table_pos(sfont, "OS/2") > 0) {
356
sfnt_locate_table(sfont, "OS/2");
357
table->version = sfnt_get_ushort(sfont);
358
table->xAvgCharWidth = sfnt_get_short(sfont);
359
table->usWeightClass = sfnt_get_ushort(sfont);
360
table->usWidthClass = sfnt_get_ushort(sfont);
361
table->fsType = sfnt_get_short(sfont);
362
table->ySubscriptXSize = sfnt_get_short(sfont);
363
table->ySubscriptYSize = sfnt_get_short(sfont);
364
table->ySubscriptXOffset = sfnt_get_short(sfont);
365
table->ySubscriptYOffset = sfnt_get_short(sfont);
366
table->ySuperscriptXSize = sfnt_get_short(sfont);
367
table->ySuperscriptYSize = sfnt_get_short(sfont);
368
table->ySuperscriptXOffset = sfnt_get_short(sfont);
369
table->ySuperscriptYOffset = sfnt_get_short(sfont);
370
table->yStrikeoutSize = sfnt_get_short(sfont);
371
table->yStrikeoutPosition = sfnt_get_short(sfont);
372
table->sFamilyClass = sfnt_get_short(sfont);
373
for (i = 0; i < 10; i++) {
374
table->panose[i] = sfnt_get_byte(sfont);
376
table->ulUnicodeRange1 = sfnt_get_ulong(sfont);
377
table->ulUnicodeRange2 = sfnt_get_ulong(sfont);
378
table->ulUnicodeRange3 = sfnt_get_ulong(sfont);
379
table->ulUnicodeRange4 = sfnt_get_ulong(sfont);
380
for (i = 0; i < 4; i++) {
381
table->achVendID[i] = sfnt_get_char(sfont);
383
table->fsSelection = sfnt_get_ushort(sfont);
384
table->usFirstCharIndex = sfnt_get_ushort(sfont);
385
table->usLastCharIndex = sfnt_get_ushort(sfont);
386
table->sTypoAscender = sfnt_get_short(sfont);
387
table->sTypoDescender = sfnt_get_short(sfont);
388
table->sTypoLineGap = sfnt_get_short(sfont);
389
table->usWinAscent = sfnt_get_ushort(sfont);
390
table->usWinDescent = sfnt_get_ushort(sfont);
391
table->ulCodePageRange1 = sfnt_get_ulong(sfont);
392
table->ulCodePageRange2 = sfnt_get_ulong(sfont);
393
if (table->version == 0x0002) {
394
table->sxHeight = sfnt_get_short(sfont);
395
table->sCapHeight = sfnt_get_short(sfont);
396
table->usDefaultChar = sfnt_get_ushort(sfont);
397
table->usBreakChar = sfnt_get_ushort(sfont);
398
table->usMaxContext = sfnt_get_ushort(sfont);
401
/* used in add_CIDVMetrics() of cidtype0.c */
402
table->sTypoAscender = 880;
403
table->sTypoDescender = -120;
404
/* used in tt_get_fontdesc() of tt_aux.c */
405
table->usWeightClass = 400U; /* Normal(Regular) */
406
table->xAvgCharWidth = 0; /* ignore */
407
table->version = 0; /* TrueType rev 1.5 */
408
table->fsType = 0; /* Installable Embedding */
409
table->fsSelection = 0U; /* All undefined */
410
table->sFamilyClass = 0; /* No Classification */
411
for (i = 0; i < 10; i++) {
412
table->panose[i] = 0; /* All Any */
420
tt_get_name (sfnt *sfont, char *dest, USHORT destlen,
421
USHORT plat_id, USHORT enco_id,
422
USHORT lang_id, USHORT name_id)
425
USHORT num_names, string_offset;
429
name_offset = sfnt_locate_table (sfont, "name");
431
if (sfnt_get_ushort(sfont))
432
ERROR ("Expecting zero");
434
num_names = sfnt_get_ushort(sfont);
435
string_offset = sfnt_get_ushort(sfont);
436
for (i=0;i<num_names;i++) {
437
USHORT p_id, e_id, n_id, l_id;
440
p_id = sfnt_get_ushort(sfont);
441
e_id = sfnt_get_ushort(sfont);
442
l_id = sfnt_get_ushort(sfont);
443
n_id = sfnt_get_ushort(sfont);
444
length = sfnt_get_ushort(sfont);
445
offset = sfnt_get_ushort(sfont);
446
/* language ID value 0xffffu for `accept any language ID' */
447
if ((p_id == plat_id) && (e_id == enco_id) &&
448
(lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) {
449
if (length > destlen - 1) {
450
fprintf(stderr, "\n** Notice: Name string too long. Truncating **\n");
451
length = destlen - 1;
453
sfnt_seek_set (sfont, name_offset+string_offset+offset);
454
sfnt_read(dest, length, sfont);
459
if (i == num_names) {
467
tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen)
471
/* First try Mac-Roman PS name and then Win-Unicode PS name */
472
if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 ||
473
(namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 ||
474
(namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0)
477
fprintf(stderr, "\n** Warning: No valid PostScript name available **\n");
479
Wrokaround for some bad TTfonts:
480
Language ID value 0xffffu for `accept any language ID'
482
if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) {
484
Finally falling back to Mac Roman name field.
485
Warning: Some bad Japanese TTfonts using SJIS encoded string in the
486
Mac Roman name field.
488
namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1);