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
/>.
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
)
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
);
76 struct tt_head_table
*tt_read_head_table
(sfnt
* sfont
)
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
);
110 char
*tt_pack_maxp_table
(struct tt_maxp_table
*table
)
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
);
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
);
160 char
*tt_pack_hhea_table
(struct tt_hhea_table
*table
)
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
);
185 struct tt_hhea_table
*tt_read_hhea_table
(sfnt
* sfont
)
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
);
216 char
*tt_pack_vhea_table
(struct tt_vhea_table
*table
)
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
);
241 struct tt_vhea_table
*tt_read_vhea_table
(sfnt
* sfont
)
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
);
269 struct tt_VORG_table
*tt_read_VORG_table
(sfnt
* sfont
)
271 struct tt_VORG_table
*vorg
;
275 offset
= sfnt_find_table_pos
(sfont
, "VORG");
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
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
);
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
;
328 this table may not exist
330 struct tt_os2__table
*tt_read_os2__table
(sfnt
* sfont
)
332 struct tt_os2__table
*table
= NULL;
335 if
(sfnt_find_table_pos
(sfont
, "OS/2") == 0)
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
);
390 tt_get_name
(sfnt
* sfont
, char
*dest
, USHORT destlen
,
391 USHORT plat_id
, USHORT enco_id
, USHORT lang_id
, USHORT name_id
)
394 USHORT num_names
, string_offset
;
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
;
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) {
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
);
429 if
(i
== num_names
) {
436 USHORT tt_get_ps_fontname
(sfnt
* sfont
, char
*dest
, USHORT destlen
)
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)
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);