1
/* $Header: /home/cvsroot/dvipdfmx/src/tt_table.c,v 1.7 2004/09/11 14:50:29 hirata Exp $
3
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5
Copyright (C) 2002 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.
36
tables contains information refered by other tables
37
maxp->numGlyphs, etc --> loca, etc
38
hhea->numberOfHMetrics --> hmtx
39
head->indexToLocFormat --> loca
40
head->glyphDataFormat --> glyf
43
char *tt_pack_head_table (struct tt_head_table *table)
49
TT_ERROR("passed NULL pointer\n");
51
p = data = NEW(TT_HEAD_TABLE_SIZE, char);
52
p += sfnt_put_ulong(p, table->version);
53
p += sfnt_put_ulong(p, table->fontRevision);
54
p += sfnt_put_ulong(p, table->checkSumAdjustment);
55
p += sfnt_put_ulong(p, table->magicNumber);
56
p += sfnt_put_ushort(p, table->flags);
57
p += sfnt_put_ushort(p, table->unitsPerEm);
59
*(p++) = (table->created)[i];
62
*(p++) = (table->modified)[i];
64
p += sfnt_put_short(p, table->xMin);
65
p += sfnt_put_short(p, table->yMin);
66
p += sfnt_put_short(p, table->xMax);
67
p += sfnt_put_short(p, table->yMax);
68
p += sfnt_put_ushort(p, table->macStyle);
69
p += sfnt_put_ushort(p, table->lowestRecPPEM);
70
p += sfnt_put_short(p, table->fontDirectionHint);
71
p += sfnt_put_short(p, table->indexToLocFormat);
72
p += sfnt_put_short(p, table->glyphDataFormat);
77
struct tt_head_table *tt_read_head_table (sfnt *sfont)
80
struct tt_head_table *table = NULL;
82
table = NEW(1, struct tt_head_table);
84
sfnt_locate_table(sfont, "head");
86
table->version = sfnt_get_ulong(sfont);
87
table->fontRevision = sfnt_get_ulong(sfont);
88
table->checkSumAdjustment = sfnt_get_ulong(sfont);
89
table->magicNumber = sfnt_get_ulong(sfont);
90
table->flags = sfnt_get_ushort(sfont);
91
table->unitsPerEm = sfnt_get_ushort(sfont);
93
(table->created)[i] = sfnt_get_byte (sfont);
96
(table->modified)[i] = sfnt_get_byte (sfont);
98
table->xMin = sfnt_get_short(sfont);
99
table->yMin = sfnt_get_short(sfont);
100
table->xMax = sfnt_get_short(sfont);
101
table->yMax = sfnt_get_short(sfont);
102
table->macStyle = sfnt_get_short(sfont);
103
table->lowestRecPPEM = sfnt_get_short(sfont);
104
table->fontDirectionHint = sfnt_get_short(sfont);
105
table->indexToLocFormat = sfnt_get_short(sfont);
106
table->glyphDataFormat = sfnt_get_short(sfont);
111
char *tt_pack_maxp_table (struct tt_maxp_table *table)
115
p = data = NEW(TT_MAXP_TABLE_SIZE, char);
116
p += sfnt_put_ulong(p, table->version);
117
p += sfnt_put_ushort(p, table->numGlyphs);
118
p += sfnt_put_ushort(p, table->maxPoints);
119
p += sfnt_put_ushort(p, table->maxContours);
120
p += sfnt_put_ushort(p, table->maxComponentPoints);
121
p += sfnt_put_ushort(p, table->maxComponentContours);
122
p += sfnt_put_ushort(p, table->maxZones);
123
p += sfnt_put_ushort(p, table->maxTwilightPoints);
124
p += sfnt_put_ushort(p, table->maxStorage);
125
p += sfnt_put_ushort(p, table->maxFunctionDefs);
126
p += sfnt_put_ushort(p, table->maxInstructionDefs);
127
p += sfnt_put_ushort(p, table->maxStackElements);
128
p += sfnt_put_ushort(p, table->maxSizeOfInstructions);
129
p += sfnt_put_ushort(p, table->maxComponentElements);
130
p += sfnt_put_ushort(p, table->maxComponentDepth);
135
struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont)
137
struct tt_maxp_table *table = NULL;
139
table = NEW(1, struct tt_maxp_table);
141
sfnt_locate_table(sfont, "maxp");
142
table->version = sfnt_get_ulong(sfont);
143
table->numGlyphs = sfnt_get_ushort(sfont);
144
table->maxPoints = sfnt_get_ushort(sfont);
145
table->maxContours = sfnt_get_ushort(sfont);
146
table->maxComponentPoints = sfnt_get_ushort(sfont);
147
table->maxComponentContours = sfnt_get_ushort(sfont);
148
table->maxZones = sfnt_get_ushort(sfont);
149
table->maxTwilightPoints = sfnt_get_ushort(sfont);
150
table->maxStorage = sfnt_get_ushort(sfont);
151
table->maxFunctionDefs = sfnt_get_ushort(sfont);
152
table->maxInstructionDefs = sfnt_get_ushort(sfont);
153
table->maxStackElements = sfnt_get_ushort(sfont);
154
table->maxSizeOfInstructions = sfnt_get_ushort(sfont);
155
table->maxComponentElements = sfnt_get_ushort(sfont);
156
table->maxComponentDepth = sfnt_get_ushort(sfont);
161
char *tt_pack_hhea_table (struct tt_hhea_table *table)
166
p = data = NEW(TT_HHEA_TABLE_SIZE, char);
167
p += sfnt_put_ulong(p, table->version);
168
p += sfnt_put_short(p, table->Ascender);
169
p += sfnt_put_short(p, table->Descender);
170
p += sfnt_put_short(p, table->LineGap);
171
p += sfnt_put_ushort(p, table->advanceWidthMax);
172
p += sfnt_put_short(p, table->minLeftSideBearing);
173
p += sfnt_put_short(p, table->minRightSideBearing);
174
p += sfnt_put_short(p, table->xMaxExtent);
175
p += sfnt_put_short(p, table->caretSlopeRise);
176
p += sfnt_put_short(p, table->caretSlopeRun);
177
for (i = 0; i < 5; i++) {
178
p += sfnt_put_short(p, table->reserved[i]);
180
p += sfnt_put_short(p, table->metricDataFormat);
181
p += sfnt_put_ushort(p, table->numberOfHMetrics);
186
struct tt_hhea_table *
187
tt_read_hhea_table (sfnt *sfont)
190
struct tt_hhea_table *table = NULL;
192
table = NEW(1, struct tt_hhea_table);
194
sfnt_locate_table(sfont, "hhea");
195
table->version = sfnt_get_ulong(sfont);
196
table->Ascender = sfnt_get_short (sfont);
197
table->Descender = sfnt_get_short(sfont);
198
table->LineGap = sfnt_get_short(sfont);
199
table->advanceWidthMax = sfnt_get_ushort(sfont);
200
table->minLeftSideBearing = sfnt_get_short(sfont);
201
table->minRightSideBearing = sfnt_get_short(sfont);
202
table->xMaxExtent = sfnt_get_short(sfont);
203
table->caretSlopeRise = sfnt_get_short(sfont);
204
table->caretSlopeRun = sfnt_get_short(sfont);
205
for(i = 0; i < 5; i++) {
206
table->reserved[i] = sfnt_get_short(sfont);
208
table->metricDataFormat = sfnt_get_short(sfont);
209
if (table->metricDataFormat != 0)
210
TT_ERROR("unknown metricDaraFormat");
211
table->numberOfHMetrics = sfnt_get_ushort(sfont);
218
tt_pack_vhea_table (struct tt_vhea_table *table)
223
p = data = NEW(TT_VHEA_TABLE_SIZE, char);
224
p += sfnt_put_ulong(p, table->version);
225
p += sfnt_put_short(p, table->vertTypoAscender);
226
p += sfnt_put_short(p, table->vertTypoDescender);
227
p += sfnt_put_short(p, table->vertTypoLineGap);
228
p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */
229
p += sfnt_put_short(p, table->minTopSideBearing);
230
p += sfnt_put_short(p, table->minBottomSideBearing);
231
p += sfnt_put_short(p, table->yMaxExtent);
232
p += sfnt_put_short(p, table->caretSlopeRise);
233
p += sfnt_put_short(p, table->caretSlopeRun);
234
p += sfnt_put_short(p, table->caretOffset);
235
for(i = 0; i < 5; i++) {
236
p += sfnt_put_short(p, table->reserved[i]);
238
p += sfnt_put_ushort(p, table->numOfLongVerMetrics);
243
struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont)
246
struct tt_vhea_table *table = NULL;
248
table = NEW(1, struct tt_vhea_table);
250
sfnt_locate_table(sfont, "vhea");
251
table->version = sfnt_get_ulong(sfont);
252
table->vertTypoAscender = sfnt_get_short (sfont);
253
table->vertTypoDescender = sfnt_get_short(sfont);
254
table->vertTypoLineGap = sfnt_get_short(sfont);
255
table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */
256
table->minTopSideBearing = sfnt_get_short(sfont);
257
table->minBottomSideBearing = sfnt_get_short(sfont);
258
table->yMaxExtent = sfnt_get_short(sfont);
259
table->caretSlopeRise = sfnt_get_short(sfont);
260
table->caretSlopeRun = sfnt_get_short(sfont);
261
table->caretOffset = sfnt_get_short(sfont);
263
(table->reserved)[i] = sfnt_get_short(sfont);
265
table->numOfLongVerMetrics = sfnt_get_ushort(sfont);
271
struct tt_VORG_table *
272
tt_read_VORG_table (sfnt *sfont)
274
struct tt_VORG_table *vorg;
278
offset = sfnt_find_table_pos(sfont, "VORG");
281
vorg = NEW(1, struct tt_VORG_table);
283
sfnt_locate_table(sfont, "VORG");
284
if (sfnt_get_ushort(sfont) != 1 ||
285
sfnt_get_ushort(sfont) != 0)
286
TT_ERROR("Unsupported VORG version.");
288
vorg->defaultVertOriginY = sfnt_get_short(sfont);
289
vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont);
290
vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics,
291
struct tt_vertOriginYMetrics);
293
* The vertOriginYMetrics array must be sorted in increasing
297
i < vorg->numVertOriginYMetrics; i++) {
298
vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont);
299
vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont);
311
* Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea.
314
struct tt_longMetrics *
315
tt_read_longMetrics (sfnt *sfont, USHORT numGlyphs, USHORT numLongMetrics)
317
struct tt_longMetrics *m;
318
USHORT gid, last_adv = 0;
320
m = NEW(numGlyphs, struct tt_longMetrics);
321
for (gid = 0; gid < numGlyphs; gid++) {
322
if (gid < numLongMetrics)
323
last_adv = sfnt_get_ushort(sfont);
324
m[gid].sideBearing = sfnt_get_short(sfont);
325
m[gid].advance = last_adv;
332
/* this table may not exist */
333
struct tt_os2__table *
334
tt_read_os2__table (sfnt *sfont)
336
struct tt_os2__table *table = NULL;
339
if (sfnt_find_table_pos(sfont, "OS/2") == 0)
342
sfnt_locate_table(sfont, "OS/2");
344
table = NEW(1, struct tt_os2__table);
346
table->version = sfnt_get_ushort(sfont);
347
table->xAvgCharWidth = sfnt_get_short(sfont);
348
table->usWeightClass = sfnt_get_ushort(sfont);
349
table->usWidthClass = sfnt_get_ushort(sfont);
350
table->fsType = sfnt_get_short(sfont);
351
table->ySubscriptXSize = sfnt_get_short(sfont);
352
table->ySubscriptYSize = sfnt_get_short(sfont);
353
table->ySubscriptXOffset = sfnt_get_short(sfont);
354
table->ySubscriptYOffset = sfnt_get_short(sfont);
355
table->ySuperscriptXSize = sfnt_get_short(sfont);
356
table->ySuperscriptYSize = sfnt_get_short(sfont);
357
table->ySuperscriptXOffset = sfnt_get_short(sfont);
358
table->ySuperscriptYOffset = sfnt_get_short(sfont);
359
table->yStrikeoutSize = sfnt_get_short(sfont);
360
table->yStrikeoutPosition = sfnt_get_short(sfont);
361
table->sFamilyClass = sfnt_get_short(sfont);
362
for (i = 0; i < 10; i++) {
363
table->panose[i] = sfnt_get_byte(sfont);
365
table->ulUnicodeRange1 = sfnt_get_ulong(sfont);
366
table->ulUnicodeRange2 = sfnt_get_ulong(sfont);
367
table->ulUnicodeRange3 = sfnt_get_ulong(sfont);
368
table->ulUnicodeRange4 = sfnt_get_ulong(sfont);
369
for (i = 0; i < 4; i++) {
370
table->achVendID[i] = sfnt_get_char(sfont);
372
table->fsSelection = sfnt_get_ushort(sfont);
373
table->usFirstCharIndex = sfnt_get_ushort(sfont);
374
table->usLastCharIndex = sfnt_get_ushort(sfont);
375
table->sTypoAscender = sfnt_get_short(sfont);
376
table->sTypoDescender = sfnt_get_short(sfont);
377
table->sTypoLineGap = sfnt_get_short(sfont);
378
table->usWinAscent = sfnt_get_ushort(sfont);
379
table->usWinDescent = sfnt_get_ushort(sfont);
380
table->ulCodePageRange1 = sfnt_get_ulong(sfont);
381
table->ulCodePageRange2 = sfnt_get_ulong(sfont);
382
if (table->version == 0x0002) {
383
table->sxHeight = sfnt_get_short(sfont);
384
table->sCapHeight = sfnt_get_short(sfont);
385
table->usDefaultChar = sfnt_get_ushort(sfont);
386
table->usBreakChar = sfnt_get_ushort(sfont);
387
table->usMaxContext = sfnt_get_ushort(sfont);
394
tt_get_name (sfnt *sfont, char *dest, USHORT destlen,
395
USHORT plat_id, USHORT enco_id,
396
USHORT lang_id, USHORT name_id)
399
USHORT num_names, string_offset;
403
name_offset = sfnt_locate_table (sfont, "name");
405
if (sfnt_get_ushort(sfont))
406
TT_ERROR ("Expecting zero");
408
num_names = sfnt_get_ushort(sfont);
409
string_offset = sfnt_get_ushort(sfont);
410
for (i=0;i<num_names;i++) {
411
USHORT p_id, e_id, n_id, l_id;
414
p_id = sfnt_get_ushort(sfont);
415
e_id = sfnt_get_ushort(sfont);
416
l_id = sfnt_get_ushort(sfont);
417
n_id = sfnt_get_ushort(sfont);
418
length = sfnt_get_ushort(sfont);
419
offset = sfnt_get_ushort(sfont);
420
/* language ID value 0xffffu for `accept any language ID' */
421
if ((p_id == plat_id) && (e_id == enco_id) &&
422
(lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) {
423
if (length > destlen - 1) {
424
fprintf(stderr, "\n** Notice: Name string too long. Truncating **\n");
425
length = destlen - 1;
427
sfnt_seek_set (sfont, name_offset+string_offset+offset);
428
sfnt_read((unsigned char*)dest, length, sfont);
433
if (i == num_names) {
441
tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen)
447
const char* name = FT_Get_Postscript_Name(sfont->ft_face);
448
namelen = strlen(name);
449
if (namelen > destlen - 1) {
450
strncpy(dest, name, destlen - 1);
458
/* First try Mac-Roman PS name and then Win-Unicode PS name */
459
if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 ||
460
(namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 ||
461
(namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0)
464
fprintf(stderr, "\n** Warning: No valid PostScript name available **\n");
466
Wrokaround for some bad TTfonts:
467
Language ID value 0xffffu for `accept any language ID'
469
if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) {
471
Finally falling back to Mac Roman name field.
472
Warning: Some bad Japanese TTfonts using SJIS encoded string in the
473
Mac Roman name field.
475
namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1);