~jammy-zhou/+junk/skia

« back to all changes in this revision

Viewing changes to third_party/harfbuzz/src/harfbuzz-dump.c

  • Committer: Jammy Zhou
  • Date: 2010-11-05 22:47:35 UTC
  • Revision ID: jammy.zhou@linaro.org-20101105224735-i1miyqbyxwslg7t2
initial version (upstream r622)

http://code.google.com/p/skia/source/list

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 *stream, int indent, HB_Type hb_type)
 
47
#define RECURSE(name, type, val) do {  DUMP ("<" #name ">\n"); Dump_ ## type (val, 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_ValueRecord (val, stream, indent + 1, hb_type, frmt); DUMP ("</ValueRecord>\n"); } while (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->ClassValueArray[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->ClassRangeRecord[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->BacktrackGlyphCount);
 
267
  DUMP_USHORT_ARRAY (ChainSubClassRule, Input, ChainSubClassRule->InputGlyphCount - 1);
 
268
  DUMP_USHORT_ARRAY (ChainSubClassRule, Lookahead, ChainSubClassRule->LookaheadGlyphCount);
 
269
 
 
270
  for (i = 0; i < ChainSubClassRule->SubstCount; i++)
 
271
    RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainSubClassRule->SubstLookupRecord[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->ChainSubClassRule[i]);
 
283
}
 
284
 
 
285
static void
 
286
Dump_GSUB_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type 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.ssf2.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_Type 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_Type 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_type);
 
379
      break;
 
380
    case 2:
 
381
      Dump_ContextSubstFormat2 (&ContextSubst->csf.csf2, stream, indent+2, hb_type);
 
382
      break;
 
383
    case 3:
 
384
      Dump_ContextSubstFormat3 (&ContextSubst->csf.csf3, stream, indent+2, hb_type);
 
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->BacktrackClassDef);
 
406
  DUMP_FUINT (ChainContextSubstFormat2, MaxInputLength);
 
407
  RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->InputClassDef);
 
408
  DUMP_FUINT (ChainContextSubstFormat2, MaxLookaheadLength);
 
409
  RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->LookaheadClassDef);
 
410
 
 
411
  DUMP_FUINT (ChainContextSubstFormat2, ChainSubClassSetCount);
 
412
  for (i = 0; i < ChainContextSubstFormat2->ChainSubClassSetCount; i++)
 
413
    RECURSE (ChainSubClassSet, ChainSubClassSet, &ChainContextSubstFormat2->ChainSubClassSet[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->BacktrackCoverage[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->LookaheadCoverage[i]);
 
429
 
 
430
  for (i = 0; i < ChainContextSubstFormat3->SubstCount; i++)
 
431
    RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainContextSubstFormat3->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_type);
 
445
      break;
 
446
    case 2:
 
447
      Dump_ChainContextSubstFormat2 (&chain->ccsf.ccsf2, stream, indent+2, hb_type);
 
448
      break;
 
449
    case 3:
 
450
      Dump_ChainContextSubstFormat3 (&chain->ccsf.ccsf3, stream, indent+2, hb_type);
 
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_Type 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 indent, 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_type, 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_Type 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->LookupType);
 
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
}