beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / font / tt_table.w
blob8bd2f3b982d218d6cc99006735488e802ef9bf85
1 % tt_table.w
3 % Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
4 % the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr>
5 % Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
7 % This file is part of LuaTeX.
9 % LuaTeX is free software; you can redistribute it and/or modify it under
10 % the terms of the GNU General Public License as published by the Free
11 % Software Foundation; either version 2 of the License, or (at your
12 % option) any later version.
14 % LuaTeX is distributed in the hope that it will be useful, but WITHOUT
15 % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 % FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 % License for more details.
19 % You should have received a copy of the GNU General Public License along
20 % with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
22 @ @c
25 #include "ptexlib.h"
27 #include <stdio.h>
28 #include "font/sfnt.h"
29 #include "font/tt_table.h"
31 @ tables contains information refered by other tables
33 |maxp->numGlyphs, etc --> loca, etc|
35 |hhea->numberOfHMetrics --> hmtx|
37 |head->indexToLocFormat --> loca|
39 |head->glyphDataFormat --> glyf|
42 char *tt_pack_head_table(struct tt_head_table *table)
44 int i;
45 char *p, *data;
47 if (table == NULL)
48 normal_error("ttf","passed NULL pointer");
50 p = data = NEW(TT_HEAD_TABLE_SIZE, char);
51 p += sfnt_put_ulong(p, (LONG) table->version);
52 p += sfnt_put_ulong(p, (LONG) table->fontRevision);
53 p += sfnt_put_ulong(p, (LONG) table->checkSumAdjustment);
54 p += sfnt_put_ulong(p, (LONG) table->magicNumber);
55 p += sfnt_put_ushort(p, table->flags);
56 p += sfnt_put_ushort(p, table->unitsPerEm);
57 for (i = 0; i < 8; i++) {
58 *(p++) = (char) (table->created)[i];
60 for (i = 0; i < 8; i++) {
61 *(p++) = (char) (table->modified)[i];
63 p += sfnt_put_short(p, table->xMin);
64 p += sfnt_put_short(p, table->yMin);
65 p += sfnt_put_short(p, table->xMax);
66 p += sfnt_put_short(p, table->yMax);
67 p += sfnt_put_ushort(p, table->macStyle);
68 p += sfnt_put_ushort(p, table->lowestRecPPEM);
69 p += sfnt_put_short(p, table->fontDirectionHint);
70 p += sfnt_put_short(p, table->indexToLocFormat);
71 p += sfnt_put_short(p, table->glyphDataFormat);
73 return data;
76 struct tt_head_table *tt_read_head_table(sfnt * sfont)
78 int i;
79 struct tt_head_table *table = NULL;
81 table = NEW(1, struct tt_head_table);
83 sfnt_locate_table(sfont, "head");
85 table->version = sfnt_get_ulong(sfont);
86 table->fontRevision = sfnt_get_ulong(sfont);
87 table->checkSumAdjustment = sfnt_get_ulong(sfont);
88 table->magicNumber = sfnt_get_ulong(sfont);
89 table->flags = sfnt_get_ushort(sfont);
90 table->unitsPerEm = sfnt_get_ushort(sfont);
91 for (i = 0; i < 8; i++) {
92 (table->created)[i] = sfnt_get_byte(sfont);
94 for (i = 0; i < 8; i++) {
95 (table->modified)[i] = sfnt_get_byte(sfont);
97 table->xMin = sfnt_get_short(sfont);
98 table->yMin = sfnt_get_short(sfont);
99 table->xMax = sfnt_get_short(sfont);
100 table->yMax = sfnt_get_short(sfont);
101 table->macStyle = (USHORT) sfnt_get_short(sfont);
102 table->lowestRecPPEM = (USHORT) sfnt_get_short(sfont);
103 table->fontDirectionHint = sfnt_get_short(sfont);
104 table->indexToLocFormat = sfnt_get_short(sfont);
105 table->glyphDataFormat = sfnt_get_short(sfont);
107 return table;
110 char *tt_pack_maxp_table(struct tt_maxp_table *table)
112 char *p, *data;
114 p = data = NEW(TT_MAXP_TABLE_SIZE, char);
115 p += sfnt_put_ulong(p, (LONG) table->version);
116 p += sfnt_put_ushort(p, table->numGlyphs);
117 p += sfnt_put_ushort(p, table->maxPoints);
118 p += sfnt_put_ushort(p, table->maxContours);
119 p += sfnt_put_ushort(p, table->maxComponentPoints);
120 p += sfnt_put_ushort(p, table->maxComponentContours);
121 p += sfnt_put_ushort(p, table->maxZones);
122 p += sfnt_put_ushort(p, table->maxTwilightPoints);
123 p += sfnt_put_ushort(p, table->maxStorage);
124 p += sfnt_put_ushort(p, table->maxFunctionDefs);
125 p += sfnt_put_ushort(p, table->maxInstructionDefs);
126 p += sfnt_put_ushort(p, table->maxStackElements);
127 p += sfnt_put_ushort(p, table->maxSizeOfInstructions);
128 p += sfnt_put_ushort(p, table->maxComponentElements);
129 p += sfnt_put_ushort(p, table->maxComponentDepth);
131 return data;
134 struct tt_maxp_table *tt_read_maxp_table(sfnt * sfont)
136 struct tt_maxp_table *table = NULL;
138 table = NEW(1, struct tt_maxp_table);
140 sfnt_locate_table(sfont, "maxp");
141 table->version = sfnt_get_ulong(sfont);
142 table->numGlyphs = sfnt_get_ushort(sfont);
143 table->maxPoints = sfnt_get_ushort(sfont);
144 table->maxContours = sfnt_get_ushort(sfont);
145 table->maxComponentPoints = sfnt_get_ushort(sfont);
146 table->maxComponentContours = sfnt_get_ushort(sfont);
147 table->maxZones = sfnt_get_ushort(sfont);
148 table->maxTwilightPoints = sfnt_get_ushort(sfont);
149 table->maxStorage = sfnt_get_ushort(sfont);
150 table->maxFunctionDefs = sfnt_get_ushort(sfont);
151 table->maxInstructionDefs = sfnt_get_ushort(sfont);
152 table->maxStackElements = sfnt_get_ushort(sfont);
153 table->maxSizeOfInstructions = sfnt_get_ushort(sfont);
154 table->maxComponentElements = sfnt_get_ushort(sfont);
155 table->maxComponentDepth = sfnt_get_ushort(sfont);
157 return table;
160 char *tt_pack_hhea_table(struct tt_hhea_table *table)
162 int i;
163 char *p, *data;
165 p = data = NEW(TT_HHEA_TABLE_SIZE, char);
166 p += sfnt_put_ulong(p, (LONG) table->version);
167 p += sfnt_put_short(p, table->Ascender);
168 p += sfnt_put_short(p, table->Descender);
169 p += sfnt_put_short(p, table->LineGap);
170 p += sfnt_put_ushort(p, table->advanceWidthMax);
171 p += sfnt_put_short(p, table->minLeftSideBearing);
172 p += sfnt_put_short(p, table->minRightSideBearing);
173 p += sfnt_put_short(p, table->xMaxExtent);
174 p += sfnt_put_short(p, table->caretSlopeRise);
175 p += sfnt_put_short(p, table->caretSlopeRun);
176 for (i = 0; i < 5; i++) {
177 p += sfnt_put_short(p, table->reserved[i]);
179 p += sfnt_put_short(p, table->metricDataFormat);
180 p += sfnt_put_ushort(p, table->numberOfHMetrics);
182 return data;
185 struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont)
187 int i;
188 struct tt_hhea_table *table = NULL;
190 table = NEW(1, struct tt_hhea_table);
192 sfnt_locate_table(sfont, "hhea");
193 table->version = sfnt_get_ulong(sfont);
194 table->Ascender = sfnt_get_short(sfont);
195 table->Descender = sfnt_get_short(sfont);
196 table->LineGap = sfnt_get_short(sfont);
197 table->advanceWidthMax = sfnt_get_ushort(sfont);
198 table->minLeftSideBearing = sfnt_get_short(sfont);
199 table->minRightSideBearing = sfnt_get_short(sfont);
200 table->xMaxExtent = sfnt_get_short(sfont);
201 table->caretSlopeRise = sfnt_get_short(sfont);
202 table->caretSlopeRun = sfnt_get_short(sfont);
203 for (i = 0; i < 5; i++) {
204 table->reserved[i] = sfnt_get_short(sfont);
206 table->metricDataFormat = sfnt_get_short(sfont);
207 if (table->metricDataFormat != 0)
208 normal_error("ttf","unknown metricDaraFormat");
209 table->numberOfHMetrics = sfnt_get_ushort(sfont);
211 return table;
214 @ vhea
216 char *tt_pack_vhea_table(struct tt_vhea_table *table)
218 int i;
219 char *p, *data;
221 p = data = NEW(TT_VHEA_TABLE_SIZE, char);
222 p += sfnt_put_ulong(p, (LONG) table->version);
223 p += sfnt_put_short(p, table->vertTypoAscender);
224 p += sfnt_put_short(p, table->vertTypoDescender);
225 p += sfnt_put_short(p, table->vertTypoLineGap);
226 p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */
227 p += sfnt_put_short(p, table->minTopSideBearing);
228 p += sfnt_put_short(p, table->minBottomSideBearing);
229 p += sfnt_put_short(p, table->yMaxExtent);
230 p += sfnt_put_short(p, table->caretSlopeRise);
231 p += sfnt_put_short(p, table->caretSlopeRun);
232 p += sfnt_put_short(p, table->caretOffset);
233 for (i = 0; i < 5; i++) {
234 p += sfnt_put_short(p, table->reserved[i]);
236 p += sfnt_put_ushort(p, table->numOfLongVerMetrics);
238 return data;
241 struct tt_vhea_table *tt_read_vhea_table(sfnt * sfont)
243 int i;
244 struct tt_vhea_table *table = NULL;
246 table = NEW(1, struct tt_vhea_table);
248 sfnt_locate_table(sfont, "vhea");
249 table->version = sfnt_get_ulong(sfont);
250 table->vertTypoAscender = sfnt_get_short(sfont);
251 table->vertTypoDescender = sfnt_get_short(sfont);
252 table->vertTypoLineGap = sfnt_get_short(sfont);
253 table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */
254 table->minTopSideBearing = sfnt_get_short(sfont);
255 table->minBottomSideBearing = sfnt_get_short(sfont);
256 table->yMaxExtent = sfnt_get_short(sfont);
257 table->caretSlopeRise = sfnt_get_short(sfont);
258 table->caretSlopeRun = sfnt_get_short(sfont);
259 table->caretOffset = sfnt_get_short(sfont);
260 for (i = 0; i < 5; i++) {
261 (table->reserved)[i] = sfnt_get_short(sfont);
263 table->numOfLongVerMetrics = sfnt_get_ushort(sfont);
265 return table;
269 struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont)
271 struct tt_VORG_table *vorg;
272 ULONG offset;
273 USHORT i;
275 offset = sfnt_find_table_pos(sfont, "VORG");
277 if (offset > 0) {
278 vorg = NEW(1, struct tt_VORG_table);
280 sfnt_locate_table(sfont, "VORG");
281 if (sfnt_get_ushort(sfont) != 1 || sfnt_get_ushort(sfont) != 0)
282 normal_error("ttf","unsupported VORG version");
284 vorg->defaultVertOriginY = sfnt_get_short(sfont);
285 vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont);
286 vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics,
287 struct tt_vertOriginYMetrics);
289 * The vertOriginYMetrics array must be sorted in increasing
290 * glyphIndex order.
292 for (i = 0; i < vorg->numVertOriginYMetrics; i++) {
293 vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont);
294 vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont);
296 } else {
297 vorg = NULL;
300 return vorg;
304 @ hmtx and vmtx
306 Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea.
309 struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs,
310 USHORT numLongMetrics)
312 struct tt_longMetrics *m;
313 USHORT gid, last_adv = 0;
315 m = NEW(numGlyphs, struct tt_longMetrics);
316 for (gid = 0; gid < numGlyphs; gid++) {
317 if (gid < numLongMetrics)
318 last_adv = sfnt_get_ushort(sfont);
319 m[gid].sideBearing = sfnt_get_short(sfont);
320 m[gid].advance = last_adv;
323 return m;
326 @ OS/2 table
328 this table may not exist
330 struct tt_os2__table *tt_read_os2__table(sfnt * sfont)
332 struct tt_os2__table *table = NULL;
333 int i;
335 if (sfnt_find_table_pos(sfont, "OS/2") == 0)
336 return NULL;
338 sfnt_locate_table(sfont, "OS/2");
340 table = NEW(1, struct tt_os2__table);
342 table->version = sfnt_get_ushort(sfont);
343 table->xAvgCharWidth = sfnt_get_short(sfont);
344 table->usWeightClass = sfnt_get_ushort(sfont);
345 table->usWidthClass = sfnt_get_ushort(sfont);
346 table->fsType = sfnt_get_short(sfont);
347 table->ySubscriptXSize = sfnt_get_short(sfont);
348 table->ySubscriptYSize = sfnt_get_short(sfont);
349 table->ySubscriptXOffset = sfnt_get_short(sfont);
350 table->ySubscriptYOffset = sfnt_get_short(sfont);
351 table->ySuperscriptXSize = sfnt_get_short(sfont);
352 table->ySuperscriptYSize = sfnt_get_short(sfont);
353 table->ySuperscriptXOffset = sfnt_get_short(sfont);
354 table->ySuperscriptYOffset = sfnt_get_short(sfont);
355 table->yStrikeoutSize = sfnt_get_short(sfont);
356 table->yStrikeoutPosition = sfnt_get_short(sfont);
357 table->sFamilyClass = sfnt_get_short(sfont);
358 for (i = 0; i < 10; i++) {
359 table->panose[i] = sfnt_get_byte(sfont);
361 table->ulUnicodeRange1 = sfnt_get_ulong(sfont);
362 table->ulUnicodeRange2 = sfnt_get_ulong(sfont);
363 table->ulUnicodeRange3 = sfnt_get_ulong(sfont);
364 table->ulUnicodeRange4 = sfnt_get_ulong(sfont);
365 for (i = 0; i < 4; i++) {
366 table->achVendID[i] = sfnt_get_char(sfont);
368 table->fsSelection = sfnt_get_ushort(sfont);
369 table->usFirstCharIndex = sfnt_get_ushort(sfont);
370 table->usLastCharIndex = sfnt_get_ushort(sfont);
371 table->sTypoAscender = sfnt_get_short(sfont);
372 table->sTypoDescender = sfnt_get_short(sfont);
373 table->sTypoLineGap = sfnt_get_short(sfont);
374 table->usWinAscent = sfnt_get_ushort(sfont);
375 table->usWinDescent = sfnt_get_ushort(sfont);
376 table->ulCodePageRange1 = sfnt_get_ulong(sfont);
377 table->ulCodePageRange2 = sfnt_get_ulong(sfont);
378 if (table->version == 0x0002) {
379 table->sxHeight = sfnt_get_short(sfont);
380 table->sCapHeight = sfnt_get_short(sfont);
381 table->usDefaultChar = sfnt_get_ushort(sfont);
382 table->usBreakChar = sfnt_get_ushort(sfont);
383 table->usMaxContext = sfnt_get_ushort(sfont);
386 return table;
389 USHORT
390 tt_get_name(sfnt * sfont, char *dest, USHORT destlen,
391 USHORT plat_id, USHORT enco_id, USHORT lang_id, USHORT name_id)
393 USHORT length = 0;
394 USHORT num_names, string_offset;
395 ULONG name_offset;
396 int i;
398 name_offset = sfnt_locate_table(sfont, "name");
400 if (sfnt_get_ushort(sfont))
401 normal_error("ttf","expecting zero");
403 num_names = sfnt_get_ushort(sfont);
404 string_offset = sfnt_get_ushort(sfont);
405 for (i = 0; i < num_names; i++) {
406 USHORT p_id, e_id, n_id, l_id;
407 USHORT offset;
409 p_id = sfnt_get_ushort(sfont);
410 e_id = sfnt_get_ushort(sfont);
411 l_id = sfnt_get_ushort(sfont);
412 n_id = sfnt_get_ushort(sfont);
413 length = sfnt_get_ushort(sfont);
414 offset = sfnt_get_ushort(sfont);
415 /* language ID value 0xffffu for `accept any language ID' */
416 if ((p_id == plat_id) && (e_id == enco_id) &&
417 (lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) {
418 if (length > destlen - 1) {
419 fprintf(stderr,
420 "\n** Notice: Name string too long. Truncating **\n");
421 length = (USHORT) (destlen - 1);
423 sfnt_seek_set(sfont, (long) (name_offset + string_offset + offset));
424 sfnt_read((unsigned char *) dest, length, sfont);
425 dest[length] = '\0';
426 break;
429 if (i == num_names) {
430 length = 0;
433 return length;
436 USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen)
438 USHORT namelen = 0;
440 /* First try Mac-Roman PS name and then Win-Unicode PS name */
441 if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 ||
442 (namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 ||
443 (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0)
444 return namelen;
446 normal_warning("ttf","no valid PostScript name available");
448 Wrokaround for some bad TTfonts:
449 Language ID value 0xffffu for `accept any language ID'
451 if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) {
453 Finally falling back to Mac Roman name field.
454 Warning: Some bad Japanese TTfonts using SJIS encoded string in the
455 Mac Roman name field.
457 namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1);
460 return namelen;