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->XPlacementDevice); | |
523 if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE) | |
524 RECURSE (Device, Device, &ValueRecord->YPlacementDevice); | |
525 if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE) | |
526 RECURSE (Device, Device, &ValueRecord->XAdvanceDevice); | |
527 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE) | |
528 RECURSE (Device, Device, &ValueRecord->YAdvanceDevice); | |
529 if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT) | |
530 DUMP_FUINT (ValueRecord, XIdPlacement); | |
531 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT) | |
532 DUMP_FUINT (ValueRecord, YIdPlacement); | |
533 if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE) | |
534 DUMP_FUINT (ValueRecord, XIdAdvance); | |
535 if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE) | |
536 DUMP_FUINT (ValueRecord, XIdAdvance); | |
537 } | |
538 | |
539 static void | |
540 Dump_GPOS_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Typ
e hb_type) | |
541 { | |
542 HB_SinglePos *SinglePos = &subtable->st.gpos.single; | |
543 | |
544 DUMP_FUINT (SinglePos, PosFormat); | |
545 RECURSE (Coverage, Coverage, &SinglePos->Coverage); | |
546 | |
547 DUMP_FUINT (SinglePos, ValueFormat); | |
548 | |
549 if (SinglePos->PosFormat == 1) | |
550 { | |
551 DUMP_VALUE_RECORD (&SinglePos->spf.spf1.Value, SinglePos->ValueFormat); | |
552 } | |
553 else | |
554 { | |
555 int i; | |
556 | |
557 DUMP_FUINT (&SinglePos->spf.spf2, ValueCount); | |
558 for (i = 0; i < SinglePos->spf.spf2.ValueCount; i++) | |
559 DUMP_VALUE_RECORD (&SinglePos->spf.spf2.Value[i], SinglePos->ValueFormat
); | |
560 } | |
561 } | |
562 | |
563 static void | |
564 Dump_PairValueRecord (HB_PairValueRecord *PairValueRecord, FILE *stream, int ind
ent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2) | |
565 { | |
566 DUMP_FUINT (PairValueRecord, SecondGlyph); | |
567 DUMP_VALUE_RECORD (&PairValueRecord->Value1, ValueFormat1); | |
568 DUMP_VALUE_RECORD (&PairValueRecord->Value2, ValueFormat2); | |
569 } | |
570 | |
571 static void | |
572 Dump_PairSet (HB_PairSet *PairSet, FILE *stream, int indent, HB_Type hb_type, HB
_UShort ValueFormat1, HB_UShort ValueFormat2) | |
573 { | |
574 int i; | |
575 DUMP_FUINT (PairSet, PairValueCount); | |
576 | |
577 for (i = 0; i < PairSet->PairValueCount; i++) | |
578 { | |
579 DUMP ("<PairValueRecord>\n"); | |
580 Dump_PairValueRecord (&PairSet->PairValueRecord[i], stream, indent + 1, hb
_type, ValueFormat1, ValueFormat2); | |
581 DUMP ("</PairValueRecord>\n"); | |
582 } | |
583 } | |
584 | |
585 static void | |
586 Dump_GPOS_Lookup_Pair (HB_SubTable *subtable, FILE *stream, int indent, HB_Type
hb_type) | |
587 { | |
588 HB_PairPos *PairPos = &subtable->st.gpos.pair; | |
589 | |
590 DUMP_FUINT (PairPos, PosFormat); | |
591 RECURSE (Coverage, Coverage, &PairPos->Coverage); | |
592 | |
593 DUMP_FUINT (PairPos, ValueFormat1); | |
594 DUMP_FUINT (PairPos, ValueFormat2); | |
595 | |
596 if (PairPos->PosFormat == 1) | |
597 { | |
598 int i; | |
599 | |
600 DUMP_FUINT (&PairPos->ppf.ppf1, PairSetCount); | |
601 for (i = 0; i < PairPos->ppf.ppf1.PairSetCount; i++) | |
602 { | |
603 DUMP ("<PairSet>\n"); | |
604 Dump_PairSet (&PairPos->ppf.ppf1.PairSet[i], stream, indent + 1, hb_ty
pe, PairPos->ValueFormat1, PairPos->ValueFormat2); | |
605 DUMP ("</PairSet>\n"); | |
606 } | |
607 } | |
608 else | |
609 { | |
610 } | |
611 } | |
612 | |
613 static void | |
614 Dump_GPOS_Lookup_Markbase (HB_SubTable *subtable, FILE *stream, int indent, HB_T
ype hb_type) | |
615 { | |
616 int i; | |
617 HB_MarkBasePos *markbase = &subtable->st.gpos.markbase; | |
618 | |
619 DUMP_FUINT (markbase, PosFormat); | |
620 RECURSE (Coverage, Coverage, &markbase->MarkCoverage); | |
621 RECURSE (Coverage, Coverage, &markbase->BaseCoverage); | |
622 DUMP_FUINT (markbase, ClassCount); | |
623 RECURSE (MarkArray, MarkArray, &markbase->MarkArray); | |
624 | |
625 DUMP ("<BaseArray>\n"); | |
626 indent++; | |
627 | |
628 DUMP_FUINT (&markbase->BaseArray, BaseCount); | |
629 for (i = 0; i < markbase->BaseArray.BaseCount; i++) | |
630 { | |
631 int j; | |
632 HB_BaseRecord *r = &markbase->BaseArray.BaseRecord[i]; | |
633 DUMP1 ("<BaseRecord> <!-- %d -->\n", i); | |
634 for (j = 0; j < markbase->ClassCount; j++) | |
635 DUMP1 (" <Anchor>%d</Anchor>\n", r->BaseAnchor->PosFormat); | |
636 DUMP ("<BaseRecord>\n"); | |
637 } | |
638 | |
639 indent--; | |
640 DUMP ("</BaseArray>\n"); | |
641 } | |
642 | |
643 DEF_DUMP (Lookup) | |
644 { | |
645 int i; | |
646 const char *lookup_name; | |
647 void (*lookup_func) (HB_SubTable *subtable, FILE *stream, int indent, HB_Type
hb_type) = NULL; | |
648 | |
649 if (hb_type == HB_Type_GSUB) | |
650 { | |
651 switch (Lookup->LookupType) | |
652 { | |
653 case HB_GSUB_LOOKUP_SINGLE: | |
654 lookup_name = "SINGLE"; | |
655 lookup_func = Dump_GSUB_Lookup_Single; | |
656 break; | |
657 case HB_GSUB_LOOKUP_MULTIPLE: | |
658 lookup_name = "MULTIPLE"; | |
659 break; | |
660 case HB_GSUB_LOOKUP_ALTERNATE: | |
661 lookup_name = "ALTERNATE"; | |
662 break; | |
663 case HB_GSUB_LOOKUP_LIGATURE: | |
664 lookup_name = "LIGATURE"; | |
665 lookup_func = Dump_GSUB_Lookup_Ligature; | |
666 break; | |
667 case HB_GSUB_LOOKUP_CONTEXT: | |
668 lookup_name = "CONTEXT"; | |
669 lookup_func = Dump_GSUB_Lookup_Context; | |
670 break; | |
671 case HB_GSUB_LOOKUP_CHAIN: | |
672 lookup_name = "CHAIN"; | |
673 lookup_func = Dump_GSUB_Lookup_Chain; | |
674 break; | |
675 default: | |
676 lookup_name = "(unknown)"; | |
677 lookup_func = NULL; | |
678 break; | |
679 } | |
680 } | |
681 else | |
682 { | |
683 switch (Lookup->LookupType) | |
684 { | |
685 case HB_GPOS_LOOKUP_SINGLE: | |
686 lookup_name = "SINGLE"; | |
687 lookup_func = Dump_GPOS_Lookup_Single; | |
688 break; | |
689 case HB_GPOS_LOOKUP_PAIR: | |
690 lookup_name = "PAIR"; | |
691 lookup_func = Dump_GPOS_Lookup_Pair; | |
692 break; | |
693 case HB_GPOS_LOOKUP_CURSIVE: | |
694 lookup_name = "CURSIVE"; | |
695 break; | |
696 case HB_GPOS_LOOKUP_MARKBASE: | |
697 lookup_name = "MARKBASE"; | |
698 lookup_func = Dump_GPOS_Lookup_Markbase; | |
699 break; | |
700 case HB_GPOS_LOOKUP_MARKLIG: | |
701 lookup_name = "MARKLIG"; | |
702 break; | |
703 case HB_GPOS_LOOKUP_MARKMARK: | |
704 lookup_name = "MARKMARK"; | |
705 break; | |
706 case HB_GPOS_LOOKUP_CONTEXT: | |
707 lookup_name = "CONTEXT"; | |
708 break; | |
709 case HB_GPOS_LOOKUP_CHAIN: | |
710 lookup_name = "CHAIN"; | |
711 break; | |
712 default: | |
713 lookup_name = "(unknown)"; | |
714 lookup_func = NULL; | |
715 break; | |
716 } | |
717 } | |
718 | |
719 DUMP2("<LookupType>%s</LookupType> <!-- %d -->\n", lookup_name, Lookup->Lookup
Type); | |
720 DUMP1("<LookupFlag>%#06x</LookupFlag>\n", Lookup->LookupFlag); | |
721 | |
722 for (i=0; i < Lookup->SubTableCount; i++) | |
723 { | |
724 DUMP ("<Subtable>\n"); | |
725 if (lookup_func) | |
726 (*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, hb_type); | |
727 DUMP ("</Subtable>\n"); | |
728 } | |
729 } | |
730 | |
731 DEF_DUMP (LookupList) | |
732 { | |
733 int i; | |
734 | |
735 DUMP_FUINT (LookupList, LookupCount); | |
736 | |
737 for (i=0; i < LookupList->LookupCount; i++) | |
738 RECURSE_NUM (Lookup, i, Lookup, &LookupList->Lookup[i]); | |
739 } | |
740 | |
741 void | |
742 HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream) | |
743 { | |
744 int indent = 1; | |
745 HB_Type hb_type = HB_Type_GSUB; | |
746 | |
747 do_indent (stream, indent); | |
748 fprintf(stream, "<!-- GSUB -->\n"); | |
749 RECURSE (ScriptList, ScriptList, &gsub->ScriptList); | |
750 RECURSE (FeatureList, FeatureList, &gsub->FeatureList); | |
751 RECURSE (LookupList, LookupList, &gsub->LookupList); | |
752 } | |
753 | |
754 void | |
755 HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream) | |
756 { | |
757 int indent = 1; | |
758 HB_Type hb_type = HB_Type_GPOS; | |
759 | |
760 do_indent (stream, indent); | |
761 fprintf(stream, "<!-- GPOS -->\n"); | |
762 RECURSE (ScriptList, ScriptList, &gpos->ScriptList); | |
763 RECURSE (FeatureList, FeatureList, &gpos->FeatureList); | |
764 RECURSE (LookupList, LookupList, &gpos->LookupList); | |
765 } | |
OLD | NEW |