OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2000, 2007 Red Hat, Inc. | |
3 * | |
4 * This is part of HarfBuzz, an OpenType Layout engine library. | |
5 * | |
6 * Permission is hereby granted, without written agreement and without | |
7 * license or royalty fees, to use, copy, modify, and distribute this | |
8 * software and its documentation for any purpose, provided that the | |
9 * above copyright notice and the following two paragraphs appear in | |
10 * all copies of this software. | |
11 * | |
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | |
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | |
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | |
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |
16 * DAMAGE. | |
17 * | |
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | |
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO | |
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
23 * | |
24 * Red Hat Author(s): Owen Taylor, Behdad Esfahbod | |
25 */ | |
26 | |
27 #include "harfbuzz-impl.h" | |
28 #include "harfbuzz-dump.h" | |
29 #include "harfbuzz-gdef-private.h" | |
30 #include "harfbuzz-gsub-private.h" | |
31 #include "harfbuzz-gpos-private.h" | |
32 #include "harfbuzz-open-private.h" | |
33 #include <stdarg.h> | |
34 | |
35 #define DUMP(format) dump (stream, indent, format) | |
36 #define DUMP1(format, arg1) dump (stream, indent, format, arg1) | |
37 #define DUMP2(format, arg1, arg2) dump (stream, indent, format, arg1, arg2) | |
38 #define DUMP3(format, arg1, arg2, arg3) dump (stream, indent, format, arg1, arg2
, arg3) | |
39 | |
40 #define DUMP_FINT(strct,fld) dump (stream, indent, "<" #fld ">%d</" #fld ">\n",
(strct)->fld) | |
41 #define DUMP_FUINT(strct,fld) dump (stream, indent, "<" #fld ">%u</" #fld ">\n",
(strct)->fld) | |
42 #define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">
\n", (strct)->fld) | |
43 #define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">
\n", (strct)->fld) | |
44 #define DUMP_USHORT_ARRAY(strct,fld,cnt) Dump_UShort_Array ((strct)->fld, cnt, #
fld, stream, indent); | |
45 | |
46 #define DEF_DUMP(type) static void Dump_ ## type (HB_ ## type *type, FILE *strea
m, int indent, HB_Type hb_type) | |
47 #define RECURSE(name, type, val) do { DUMP ("<" #name ">\n"); Dump_ ## type (va
l, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0) | |
48 #define RECURSE_NUM(name, i, type, val) do { DUMP1 ("<" #name "> <!-- %d -->\n"
, i); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n");
} while (0) | |
49 #define DUMP_VALUE_RECORD(val, frmt) do { DUMP ("<ValueRecord>\n"); Dump_ValueR
ecord (val, stream, indent + 1, hb_type, frmt); DUMP ("</ValueRecord>\n"); } whi
le (0) | |
50 | |
51 static void | |
52 do_indent (FILE *stream, int indent) | |
53 { | |
54 fprintf (stream, "%*s", indent * 3, ""); | |
55 } | |
56 | |
57 static void | |
58 dump (FILE *stream, int indent, const char *format, ...) | |
59 { | |
60 va_list list; | |
61 | |
62 do_indent (stream, indent); | |
63 | |
64 va_start (list, format); | |
65 vfprintf (stream, format, list); | |
66 va_end (list); | |
67 } | |
68 | |
69 static void | |
70 Dump_UShort_Array (HB_UShort *array, int count, const char *name, FILE *stream,
int indent) | |
71 { | |
72 int i; | |
73 | |
74 do_indent (stream, indent); | |
75 | |
76 fprintf (stream, "<%s>", name); | |
77 for (i = 0; i < count; i++) | |
78 fprintf (stream, "%d%s", array[i], i == 0 ? "" : " "); | |
79 fprintf (stream, "</%s>\n", name); | |
80 } | |
81 | |
82 static void | |
83 Print_Tag (HB_UInt tag, FILE *stream) | |
84 { | |
85 fprintf (stream, "%c%c%c%c", | |
86 (unsigned char)(tag >> 24), | |
87 (unsigned char)((tag >> 16) & 0xff), | |
88 (unsigned char)((tag >> 8) & 0xff), | |
89 (unsigned char)(tag & 0xff)); | |
90 } | |
91 | |
92 DEF_DUMP (LangSys) | |
93 { | |
94 int i; | |
95 | |
96 HB_UNUSED(hb_type); | |
97 | |
98 DUMP_FUINT (LangSys, LookupOrderOffset); | |
99 DUMP_FUINT (LangSys, ReqFeatureIndex); | |
100 DUMP_FUINT (LangSys, FeatureCount); | |
101 | |
102 for (i=0; i < LangSys->FeatureCount; i++) | |
103 DUMP1("<FeatureIndex>%d</FeatureIndex>\n", LangSys->FeatureIndex[i]); | |
104 } | |
105 | |
106 DEF_DUMP (ScriptTable) | |
107 { | |
108 int i; | |
109 | |
110 RECURSE (DefaultLangSys, LangSys, &ScriptTable->DefaultLangSys); | |
111 | |
112 DUMP_FUINT (ScriptTable, LangSysCount); | |
113 | |
114 for (i=0; i < ScriptTable->LangSysCount; i++) | |
115 { | |
116 do_indent (stream, indent); | |
117 fprintf (stream, "<LangSysTag>"); | |
118 Print_Tag (ScriptTable->LangSysRecord[i].LangSysTag, stream); | |
119 fprintf (stream, "</LangSysTag>\n"); | |
120 RECURSE_NUM (LangSys, i, LangSys, &ScriptTable->LangSysRecord[i].LangSys); | |
121 } | |
122 } | |
123 | |
124 DEF_DUMP (ScriptList) | |
125 { | |
126 int i; | |
127 | |
128 DUMP_FUINT (ScriptList, ScriptCount); | |
129 | |
130 for (i=0; i < ScriptList->ScriptCount; i++) | |
131 { | |
132 do_indent (stream, indent); | |
133 fprintf (stream, "<ScriptTag>"); | |
134 Print_Tag (ScriptList->ScriptRecord[i].ScriptTag, stream); | |
135 fprintf (stream, "</ScriptTag>\n"); | |
136 RECURSE_NUM (Script, i, ScriptTable, &ScriptList->ScriptRecord[i].Script); | |
137 } | |
138 } | |
139 | |
140 DEF_DUMP (Feature) | |
141 { | |
142 int i; | |
143 | |
144 HB_UNUSED(hb_type); | |
145 | |
146 DUMP_FUINT (Feature, FeatureParams); | |
147 DUMP_FUINT (Feature, LookupListCount); | |
148 | |
149 for (i=0; i < Feature->LookupListCount; i++) | |
150 DUMP1("<LookupIndex>%d</LookupIndex>\n", Feature->LookupListIndex[i]); | |
151 } | |
152 | |
153 DEF_DUMP (MarkRecord) | |
154 { | |
155 HB_UNUSED(hb_type); | |
156 | |
157 DUMP_FUINT (MarkRecord, Class); | |
158 DUMP1("<Anchor>%d</Anchor>\n", MarkRecord->MarkAnchor.PosFormat ); | |
159 } | |
160 | |
161 DEF_DUMP (MarkArray) | |
162 { | |
163 int i; | |
164 | |
165 DUMP_FUINT (MarkArray, MarkCount); | |
166 | |
167 for (i=0; i < MarkArray->MarkCount; i++) | |
168 RECURSE_NUM (MarkRecord, i, MarkRecord, &MarkArray->MarkRecord[i]); | |
169 } | |
170 | |
171 DEF_DUMP (FeatureList) | |
172 { | |
173 int i; | |
174 | |
175 DUMP_FUINT (FeatureList, FeatureCount); | |
176 | |
177 for (i=0; i < FeatureList->FeatureCount; i++) | |
178 { | |
179 do_indent (stream, indent); | |
180 fprintf (stream, "<FeatureTag>"); | |
181 Print_Tag (FeatureList->FeatureRecord[i].FeatureTag, stream); | |
182 fprintf (stream, "</FeatureTag> <!-- %d -->\n", i); | |
183 RECURSE_NUM (Feature, i, Feature, &FeatureList->FeatureRecord[i].Feature); | |
184 } | |
185 } | |
186 | |
187 DEF_DUMP (Coverage) | |
188 { | |
189 HB_UNUSED(hb_type); | |
190 | |
191 DUMP_FUINT (Coverage, CoverageFormat); | |
192 | |
193 if (Coverage->CoverageFormat == 1) | |
194 { | |
195 int i; | |
196 DUMP_FUINT (&Coverage->cf.cf1, GlyphCount); | |
197 | |
198 for (i = 0; i < Coverage->cf.cf1.GlyphCount; i++) | |
199 DUMP2("<Glyph>%#06x</Glyph> <!-- %d -->\n", | |
200 Coverage->cf.cf1.GlyphArray[i], i); | |
201 } | |
202 else | |
203 { | |
204 int i; | |
205 DUMP_FUINT (&Coverage->cf.cf2, RangeCount); | |
206 | |
207 for ( i = 0; i < Coverage->cf.cf2.RangeCount; i++ ) | |
208 DUMP3("<Glyph>%#06x - %#06x</Glyph> <!-- %d -->\n", | |
209 Coverage->cf.cf2.RangeRecord[i].Start, | |
210 Coverage->cf.cf2.RangeRecord[i].End, i); | |
211 } | |
212 } | |
213 | |
214 DEF_DUMP (ClassRangeRecord) | |
215 { | |
216 HB_UNUSED(hb_type); | |
217 | |
218 DUMP_FGLYPH (ClassRangeRecord, Start); | |
219 DUMP_FGLYPH (ClassRangeRecord, End); | |
220 DUMP_FUINT (ClassRangeRecord, Class); | |
221 } | |
222 | |
223 DEF_DUMP (ClassDefinition) | |
224 { | |
225 HB_UNUSED(hb_type); | |
226 | |
227 DUMP_FUINT( ClassDefinition, ClassFormat); | |
228 DUMP_FUINT( ClassDefinition, loaded); | |
229 | |
230 if (ClassDefinition->ClassFormat == 1) | |
231 { | |
232 int i; | |
233 HB_ClassDefFormat1 *ClassDefFormat1 = &ClassDefinition->cd.cd1; | |
234 DUMP("<ClassDefinition>\n"); | |
235 DUMP_FUINT (ClassDefFormat1, StartGlyph ); | |
236 DUMP_FUINT (ClassDefFormat1, GlyphCount ); | |
237 for (i = 0; i < ClassDefFormat1->GlyphCount; i++) | |
238 DUMP2(" <Class>%d</Class> <!-- %#06x -->", ClassDefFormat1->ClassValueAr
ray[i], | |
239 ClassDefFormat1->StartGlyph+i ); | |
240 } | |
241 else if (ClassDefinition->ClassFormat == 2) | |
242 { | |
243 int i; | |
244 HB_ClassDefFormat2 *ClassDefFormat2 = &ClassDefinition->cd.cd2; | |
245 DUMP_FUINT (ClassDefFormat2, ClassRangeCount); | |
246 | |
247 for (i = 0; i < ClassDefFormat2->ClassRangeCount; i++) | |
248 RECURSE_NUM (ClassRangeRecord, i, ClassRangeRecord, &ClassDefFormat2->Cl
assRangeRecord[i]); | |
249 } | |
250 else | |
251 fprintf(stderr, "invalid class def table!!!\n"); | |
252 } | |
253 | |
254 DEF_DUMP (SubstLookupRecord) | |
255 { | |
256 HB_UNUSED(hb_type); | |
257 | |
258 DUMP_FUINT (SubstLookupRecord, SequenceIndex); | |
259 DUMP_FUINT (SubstLookupRecord, LookupListIndex); | |
260 } | |
261 | |
262 DEF_DUMP (ChainSubClassRule) | |
263 { | |
264 int i; | |
265 | |
266 DUMP_USHORT_ARRAY (ChainSubClassRule, Backtrack, ChainSubClassRule->BacktrackG
lyphCount); | |
267 DUMP_USHORT_ARRAY (ChainSubClassRule, Input, ChainSubClassRule->InputGlyphCoun
t - 1); | |
268 DUMP_USHORT_ARRAY (ChainSubClassRule, Lookahead, ChainSubClassRule->LookaheadG
lyphCount); | |
269 | |
270 for (i = 0; i < ChainSubClassRule->SubstCount; i++) | |
271 RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainSubClassRule->Su
bstLookupRecord[i]); | |
272 | |
273 indent--; | |
274 } | |
275 | |
276 DEF_DUMP (ChainSubClassSet) | |
277 { | |
278 int i; | |
279 | |
280 DUMP_FUINT( ChainSubClassSet, ChainSubClassRuleCount ); | |
281 for (i = 0; i < ChainSubClassSet->ChainSubClassRuleCount; i++) | |
282 RECURSE_NUM (ChainSubClassRule, i, ChainSubClassRule, &ChainSubClassSet->Cha
inSubClassRule[i]); | |
283 } | |
284 | |
285 static void | |
286 Dump_GSUB_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Typ
e hb_type) | |
287 { | |
288 HB_SingleSubst *SingleSubst = &subtable->st.gsub.single; | |
289 | |
290 DUMP_FUINT (SingleSubst, SubstFormat); | |
291 RECURSE (Coverage, Coverage, &SingleSubst->Coverage); | |
292 | |
293 if (SingleSubst->SubstFormat == 1) | |
294 { | |
295 DUMP_FINT (&SingleSubst->ssf.ssf1, DeltaGlyphID); | |
296 } | |
297 else | |
298 { | |
299 int i; | |
300 | |
301 DUMP_FINT (&SingleSubst->ssf.ssf2, GlyphCount); | |
302 for (i=0; i < SingleSubst->ssf.ssf2.GlyphCount; i++) | |
303 DUMP2("<Substitute>%#06x</Substitute> <!-- %d -->\n", SingleSubst->ssf.s
sf2.Substitute[i], i); | |
304 } | |
305 } | |
306 | |
307 DEF_DUMP (Ligature) | |
308 { | |
309 int i; | |
310 | |
311 HB_UNUSED(hb_type); | |
312 | |
313 DUMP_FGLYPH (Ligature, LigGlyph); | |
314 DUMP_FUINT (Ligature, ComponentCount); | |
315 | |
316 for (i=0; i < Ligature->ComponentCount - 1; i++) | |
317 DUMP1("<Component>%#06x</Component>\n", Ligature->Component[i]); | |
318 } | |
319 | |
320 DEF_DUMP (LigatureSet) | |
321 { | |
322 int i; | |
323 | |
324 DUMP_FUINT (LigatureSet, LigatureCount); | |
325 | |
326 for (i=0; i < LigatureSet->LigatureCount; i++) | |
327 RECURSE_NUM (Ligature, i, Ligature, &LigatureSet->Ligature[i]); | |
328 } | |
329 | |
330 static void | |
331 Dump_GSUB_Lookup_Ligature (HB_SubTable *subtable, FILE *stream, int indent, HB_T
ype hb_type) | |
332 { | |
333 int i; | |
334 HB_LigatureSubst *LigatureSubst = &subtable->st.gsub.ligature; | |
335 | |
336 DUMP_FUINT (LigatureSubst, SubstFormat); | |
337 RECURSE (Coverage, Coverage, &LigatureSubst->Coverage); | |
338 | |
339 DUMP_FUINT (LigatureSubst, LigatureSetCount); | |
340 | |
341 for (i=0; i < LigatureSubst->LigatureSetCount; i++) | |
342 RECURSE_NUM (LigatureSet, i, LigatureSet, &LigatureSubst->LigatureSet[i]); | |
343 } | |
344 | |
345 DEF_DUMP (ContextSubstFormat1) | |
346 { | |
347 HB_UNUSED(hb_type); | |
348 HB_UNUSED(ContextSubstFormat1); | |
349 | |
350 | |
351 DUMP("<!-- Not implemented!!! -->\n"); | |
352 } | |
353 | |
354 DEF_DUMP (ContextSubstFormat2) | |
355 { | |
356 DUMP_FUINT (ContextSubstFormat2, MaxContextLength); | |
357 RECURSE (Coverage, Coverage, &ContextSubstFormat2->Coverage); | |
358 RECURSE (ClassDefinition, ClassDefinition, &ContextSubstFormat2->ClassDef); | |
359 } | |
360 | |
361 DEF_DUMP (ContextSubstFormat3) | |
362 { | |
363 HB_UNUSED(hb_type); | |
364 HB_UNUSED(ContextSubstFormat3); | |
365 | |
366 DUMP("<!-- Not implemented!!! -->\n"); | |
367 } | |
368 | |
369 static void | |
370 Dump_GSUB_Lookup_Context (HB_SubTable *subtable, FILE *stream, int indent, HB_Ty
pe hb_type) | |
371 { | |
372 HB_ContextSubst *ContextSubst = &subtable->st.gsub.context; | |
373 | |
374 DUMP_FUINT (ContextSubst, SubstFormat); | |
375 switch( ContextSubst->SubstFormat ) | |
376 { | |
377 case 1: | |
378 Dump_ContextSubstFormat1 (&ContextSubst->csf.csf1, stream, indent+2, hb_ty
pe); | |
379 break; | |
380 case 2: | |
381 Dump_ContextSubstFormat2 (&ContextSubst->csf.csf2, stream, indent+2, hb_ty
pe); | |
382 break; | |
383 case 3: | |
384 Dump_ContextSubstFormat3 (&ContextSubst->csf.csf3, stream, indent+2, hb_ty
pe); | |
385 break; | |
386 default: | |
387 fprintf(stderr, "invalid subformat!!!!!\n"); | |
388 } | |
389 } | |
390 | |
391 DEF_DUMP (ChainContextSubstFormat1) | |
392 { | |
393 HB_UNUSED(hb_type); | |
394 HB_UNUSED(ChainContextSubstFormat1); | |
395 | |
396 DUMP("<!-- Not implemented!!! -->\n"); | |
397 } | |
398 | |
399 DEF_DUMP (ChainContextSubstFormat2) | |
400 { | |
401 int i; | |
402 | |
403 RECURSE (Coverage, Coverage, &ChainContextSubstFormat2->Coverage); | |
404 DUMP_FUINT (ChainContextSubstFormat2, MaxBacktrackLength); | |
405 RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->Backtrac
kClassDef); | |
406 DUMP_FUINT (ChainContextSubstFormat2, MaxInputLength); | |
407 RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->InputCla
ssDef); | |
408 DUMP_FUINT (ChainContextSubstFormat2, MaxLookaheadLength); | |
409 RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->Lookahea
dClassDef); | |
410 | |
411 DUMP_FUINT (ChainContextSubstFormat2, ChainSubClassSetCount); | |
412 for (i = 0; i < ChainContextSubstFormat2->ChainSubClassSetCount; i++) | |
413 RECURSE (ChainSubClassSet, ChainSubClassSet, &ChainContextSubstFormat2->Chai
nSubClassSet[i]); | |
414 } | |
415 | |
416 DEF_DUMP (ChainContextSubstFormat3) | |
417 { | |
418 int i; | |
419 | |
420 DUMP_FUINT (ChainContextSubstFormat3, BacktrackGlyphCount); | |
421 for (i = 0; i < ChainContextSubstFormat3->BacktrackGlyphCount; i++) | |
422 RECURSE (BacktrackCoverage, Coverage, &ChainContextSubstFormat3->BacktrackCo
verage[i]); | |
423 DUMP_FUINT (ChainContextSubstFormat3, InputGlyphCount); | |
424 for (i = 0; i < ChainContextSubstFormat3->InputGlyphCount; i++) | |
425 RECURSE (InputCoverage, Coverage, &ChainContextSubstFormat3->InputCoverage[i
]); | |
426 DUMP_FUINT (ChainContextSubstFormat3, LookaheadGlyphCount); | |
427 for (i = 0; i < ChainContextSubstFormat3->LookaheadGlyphCount; i++) | |
428 RECURSE (LookaheadCoverage, Coverage, &ChainContextSubstFormat3->LookaheadCo
verage[i]); | |
429 | |
430 for (i = 0; i < ChainContextSubstFormat3->SubstCount; i++) | |
431 RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainContextSubstForm
at3->SubstLookupRecord[i]); | |
432 | |
433 } | |
434 | |
435 static void | |
436 Dump_GSUB_Lookup_Chain (HB_SubTable *subtable, FILE *stream, int indent, HB_Type
hb_type) | |
437 { | |
438 HB_ChainContextSubst *chain = &subtable->st.gsub.chain; | |
439 | |
440 DUMP_FUINT (chain, SubstFormat); | |
441 switch (chain->SubstFormat) | |
442 { | |
443 case 1: | |
444 Dump_ChainContextSubstFormat1 (&chain->ccsf.ccsf1, stream, indent+2, hb_ty
pe); | |
445 break; | |
446 case 2: | |
447 Dump_ChainContextSubstFormat2 (&chain->ccsf.ccsf2, stream, indent+2, hb_ty
pe); | |
448 break; | |
449 case 3: | |
450 Dump_ChainContextSubstFormat3 (&chain->ccsf.ccsf3, stream, indent+2, hb_ty
pe); | |
451 break; | |
452 default: | |
453 fprintf(stderr, "invalid subformat!!!!!\n"); | |
454 } | |
455 } | |
456 | |
457 static void | |
458 Dump_Device (HB_Device *Device, FILE *stream, int indent, HB_Type hb_type) | |
459 { | |
460 int i; | |
461 int bits; | |
462 int n_per; | |
463 unsigned int mask; | |
464 | |
465 HB_UNUSED(hb_type); | |
466 | |
467 DUMP_FUINT (Device, StartSize); | |
468 DUMP_FUINT (Device, EndSize); | |
469 DUMP_FUINT (Device, DeltaFormat); | |
470 switch (Device->DeltaFormat) | |
471 { | |
472 case 1: | |
473 bits = 2; | |
474 break; | |
475 case 2: | |
476 bits = 4; | |
477 break; | |
478 case 3: | |
479 bits = 8; | |
480 break; | |
481 default: | |
482 bits = 0; | |
483 break; | |
484 } | |
485 | |
486 DUMP ("<DeltaValue>"); | |
487 if (!bits) | |
488 { | |
489 | |
490 fprintf(stderr, "invalid DeltaFormat!!!!!\n"); | |
491 } | |
492 else | |
493 { | |
494 n_per = 16 / bits; | |
495 mask = (1 << bits) - 1; | |
496 mask = mask << (16 - bits); | |
497 | |
498 for (i = Device->StartSize; i <= Device->EndSize ; i++) | |
499 { | |
500 HB_UShort val = Device->DeltaValue[i / n_per]; | |
501 HB_Short signed_val = ((val << ((i % n_per) * bits)) & mask); | |
502 dump (stream, indent, "%d", signed_val >> (16 - bits)); | |
503 if (i != Device->EndSize) | |
504 DUMP (", "); | |
505 } | |
506 } | |
507 DUMP ("</DeltaValue>\n"); | |
508 } | |
509 | |
510 static void | |
511 Dump_ValueRecord (HB_ValueRecord *ValueRecord, FILE *stream, int indent, HB_Type
hb_type, HB_UShort value_format) | |
512 { | |
513 if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT) | |
514 DUMP_FINT (ValueRecord, XPlacement); | |
515 if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT) | |
516 DUMP_FINT (ValueRecord, YPlacement); | |
517 if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE) | |
518 DUMP_FINT (ValueRecord, XAdvance); | |
519 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE) | |
520 DUMP_FINT (ValueRecord, XAdvance); | |
521 if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE) | |
522 RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_X_PLACEMENT_DEVICE])
; | |
523 if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE) | |
524 RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_Y_PLACEMENT_DEVICE])
; | |
525 if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE) | |
526 RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_X_ADVANCE_DEVICE]); | |
527 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE) | |
528 RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_Y_ADVANCE_DEVICE]); | |
529 #ifdef HB_SUPPORT_MULTIPLE_MASTER | |
530 if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT) | |
531 DUMP_FUINT (ValueRecord, XIdPlacement); | |
532 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT) | |
533 DUMP_FUINT (ValueRecord, YIdPlacement); | |
534 if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE) | |
535 DUMP_FUINT (ValueRecord, XIdAdvance); | |
536 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE) | |
537 DUMP_FUINT (ValueRecord, XIdAdvance); | |
538 #endif | |
539 } | |
540 | |
541 static void | |
542 Dump_GPOS_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Typ
e hb_type) | |
543 { | |
544 HB_SinglePos *SinglePos = &subtable->st.gpos.single; | |
545 | |
546 DUMP_FUINT (SinglePos, PosFormat); | |
547 RECURSE (Coverage, Coverage, &SinglePos->Coverage); | |
548 | |
549 DUMP_FUINT (SinglePos, ValueFormat); | |
550 | |
551 if (SinglePos->PosFormat == 1) | |
552 { | |
553 DUMP_VALUE_RECORD (&SinglePos->spf.spf1.Value, SinglePos->ValueFormat); | |
554 } | |
555 else | |
556 { | |
557 int i; | |
558 | |
559 DUMP_FUINT (&SinglePos->spf.spf2, ValueCount); | |
560 for (i = 0; i < SinglePos->spf.spf2.ValueCount; i++) | |
561 DUMP_VALUE_RECORD (&SinglePos->spf.spf2.Value[i], SinglePos->ValueFormat
); | |
562 } | |
563 } | |
564 | |
565 static void | |
566 Dump_PairValueRecord (HB_PairValueRecord *PairValueRecord, FILE *stream, int ind
ent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2) | |
567 { | |
568 DUMP_FUINT (PairValueRecord, SecondGlyph); | |
569 DUMP_VALUE_RECORD (&PairValueRecord->Value1, ValueFormat1); | |
570 DUMP_VALUE_RECORD (&PairValueRecord->Value2, ValueFormat2); | |
571 } | |
572 | |
573 static void | |
574 Dump_PairSet (HB_PairSet *PairSet, FILE *stream, int indent, HB_Type hb_type, HB
_UShort ValueFormat1, HB_UShort ValueFormat2) | |
575 { | |
576 int i; | |
577 DUMP_FUINT (PairSet, PairValueCount); | |
578 | |
579 for (i = 0; i < PairSet->PairValueCount; i++) | |
580 { | |
581 DUMP ("<PairValueRecord>\n"); | |
582 Dump_PairValueRecord (&PairSet->PairValueRecord[i], stream, indent + 1, hb
_type, ValueFormat1, ValueFormat2); | |
583 DUMP ("</PairValueRecord>\n"); | |
584 } | |
585 } | |
586 | |
587 static void | |
588 Dump_GPOS_Lookup_Pair (HB_SubTable *subtable, FILE *stream, int indent, HB_Type
hb_type) | |
589 { | |
590 HB_PairPos *PairPos = &subtable->st.gpos.pair; | |
591 | |
592 DUMP_FUINT (PairPos, PosFormat); | |
593 RECURSE (Coverage, Coverage, &PairPos->Coverage); | |
594 | |
595 DUMP_FUINT (PairPos, ValueFormat1); | |
596 DUMP_FUINT (PairPos, ValueFormat2); | |
597 | |
598 if (PairPos->PosFormat == 1) | |
599 { | |
600 int i; | |
601 | |
602 DUMP_FUINT (&PairPos->ppf.ppf1, PairSetCount); | |
603 for (i = 0; i < PairPos->ppf.ppf1.PairSetCount; i++) | |
604 { | |
605 DUMP ("<PairSet>\n"); | |
606 Dump_PairSet (&PairPos->ppf.ppf1.PairSet[i], stream, indent + 1, hb_ty
pe, PairPos->ValueFormat1, PairPos->ValueFormat2); | |
607 DUMP ("</PairSet>\n"); | |
608 } | |
609 } | |
610 else | |
611 { | |
612 } | |
613 } | |
614 | |
615 static void | |
616 Dump_GPOS_Lookup_Markbase (HB_SubTable *subtable, FILE *stream, int indent, HB_T
ype hb_type) | |
617 { | |
618 int i; | |
619 HB_MarkBasePos *markbase = &subtable->st.gpos.markbase; | |
620 | |
621 DUMP_FUINT (markbase, PosFormat); | |
622 RECURSE (Coverage, Coverage, &markbase->MarkCoverage); | |
623 RECURSE (Coverage, Coverage, &markbase->BaseCoverage); | |
624 DUMP_FUINT (markbase, ClassCount); | |
625 RECURSE (MarkArray, MarkArray, &markbase->MarkArray); | |
626 | |
627 DUMP ("<BaseArray>\n"); | |
628 indent++; | |
629 | |
630 DUMP_FUINT (&markbase->BaseArray, BaseCount); | |
631 for (i = 0; i < markbase->BaseArray.BaseCount; i++) | |
632 { | |
633 int j; | |
634 HB_BaseRecord *r = &markbase->BaseArray.BaseRecord[i]; | |
635 DUMP1 ("<BaseRecord> <!-- %d -->\n", i); | |
636 for (j = 0; j < markbase->ClassCount; j++) | |
637 DUMP1 (" <Anchor>%d</Anchor>\n", r->BaseAnchor->PosFormat); | |
638 DUMP ("<BaseRecord>\n"); | |
639 } | |
640 | |
641 indent--; | |
642 DUMP ("</BaseArray>\n"); | |
643 } | |
644 | |
645 DEF_DUMP (Lookup) | |
646 { | |
647 int i; | |
648 const char *lookup_name; | |
649 void (*lookup_func) (HB_SubTable *subtable, FILE *stream, int indent, HB_Type
hb_type) = NULL; | |
650 | |
651 if (hb_type == HB_Type_GSUB) | |
652 { | |
653 switch (Lookup->LookupType) | |
654 { | |
655 case HB_GSUB_LOOKUP_SINGLE: | |
656 lookup_name = "SINGLE"; | |
657 lookup_func = Dump_GSUB_Lookup_Single; | |
658 break; | |
659 case HB_GSUB_LOOKUP_MULTIPLE: | |
660 lookup_name = "MULTIPLE"; | |
661 break; | |
662 case HB_GSUB_LOOKUP_ALTERNATE: | |
663 lookup_name = "ALTERNATE"; | |
664 break; | |
665 case HB_GSUB_LOOKUP_LIGATURE: | |
666 lookup_name = "LIGATURE"; | |
667 lookup_func = Dump_GSUB_Lookup_Ligature; | |
668 break; | |
669 case HB_GSUB_LOOKUP_CONTEXT: | |
670 lookup_name = "CONTEXT"; | |
671 lookup_func = Dump_GSUB_Lookup_Context; | |
672 break; | |
673 case HB_GSUB_LOOKUP_CHAIN: | |
674 lookup_name = "CHAIN"; | |
675 lookup_func = Dump_GSUB_Lookup_Chain; | |
676 break; | |
677 default: | |
678 lookup_name = "(unknown)"; | |
679 lookup_func = NULL; | |
680 break; | |
681 } | |
682 } | |
683 else | |
684 { | |
685 switch (Lookup->LookupType) | |
686 { | |
687 case HB_GPOS_LOOKUP_SINGLE: | |
688 lookup_name = "SINGLE"; | |
689 lookup_func = Dump_GPOS_Lookup_Single; | |
690 break; | |
691 case HB_GPOS_LOOKUP_PAIR: | |
692 lookup_name = "PAIR"; | |
693 lookup_func = Dump_GPOS_Lookup_Pair; | |
694 break; | |
695 case HB_GPOS_LOOKUP_CURSIVE: | |
696 lookup_name = "CURSIVE"; | |
697 break; | |
698 case HB_GPOS_LOOKUP_MARKBASE: | |
699 lookup_name = "MARKBASE"; | |
700 lookup_func = Dump_GPOS_Lookup_Markbase; | |
701 break; | |
702 case HB_GPOS_LOOKUP_MARKLIG: | |
703 lookup_name = "MARKLIG"; | |
704 break; | |
705 case HB_GPOS_LOOKUP_MARKMARK: | |
706 lookup_name = "MARKMARK"; | |
707 break; | |
708 case HB_GPOS_LOOKUP_CONTEXT: | |
709 lookup_name = "CONTEXT"; | |
710 break; | |
711 case HB_GPOS_LOOKUP_CHAIN: | |
712 lookup_name = "CHAIN"; | |
713 break; | |
714 default: | |
715 lookup_name = "(unknown)"; | |
716 lookup_func = NULL; | |
717 break; | |
718 } | |
719 } | |
720 | |
721 DUMP2("<LookupType>%s</LookupType> <!-- %d -->\n", lookup_name, Lookup->Lookup
Type); | |
722 DUMP1("<LookupFlag>%#06x</LookupFlag>\n", Lookup->LookupFlag); | |
723 | |
724 for (i=0; i < Lookup->SubTableCount; i++) | |
725 { | |
726 DUMP ("<Subtable>\n"); | |
727 if (lookup_func) | |
728 (*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, hb_type); | |
729 DUMP ("</Subtable>\n"); | |
730 } | |
731 } | |
732 | |
733 DEF_DUMP (LookupList) | |
734 { | |
735 int i; | |
736 | |
737 DUMP_FUINT (LookupList, LookupCount); | |
738 | |
739 for (i=0; i < LookupList->LookupCount; i++) | |
740 RECURSE_NUM (Lookup, i, Lookup, &LookupList->Lookup[i]); | |
741 } | |
742 | |
743 void | |
744 HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream) | |
745 { | |
746 int indent = 1; | |
747 HB_Type hb_type = HB_Type_GSUB; | |
748 | |
749 do_indent (stream, indent); | |
750 fprintf(stream, "<!-- GSUB -->\n"); | |
751 RECURSE (ScriptList, ScriptList, &gsub->ScriptList); | |
752 RECURSE (FeatureList, FeatureList, &gsub->FeatureList); | |
753 RECURSE (LookupList, LookupList, &gsub->LookupList); | |
754 } | |
755 | |
756 void | |
757 HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream) | |
758 { | |
759 int indent = 1; | |
760 HB_Type hb_type = HB_Type_GPOS; | |
761 | |
762 do_indent (stream, indent); | |
763 fprintf(stream, "<!-- GPOS -->\n"); | |
764 RECURSE (ScriptList, ScriptList, &gpos->ScriptList); | |
765 RECURSE (FeatureList, FeatureList, &gpos->FeatureList); | |
766 RECURSE (LookupList, LookupList, &gpos->LookupList); | |
767 } | |
OLD | NEW |