w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

gpos.c
Go to the documentation of this file.
1 /* gpos.c -- Glyph Positioning Table
2  */
3 #ifdef HAVE_CONFIG_H
4 #include <config.h>
5 #endif
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "ttf.h"
10 #include "ttfutil.h"
11 
13 {
14  USHORT valueFormat = ttfGetUSHORT (fp);
15 
16  if (valueFormat & ValueFormat_Reserved)
17  ttfError ("Unrecognized GPOS valueFormat\n");
18 
19  return valueFormat;
20 }
21 
22 static ValueRecordPtr
24 {
25  int i;
27 
28  if (valueFormat == 0)
29  return NULL;
30 
32  for (i = 0; i < 4; i++)
33  if (valueFormat & (ValueFormat_XPlacement << i))
34  value->valDesign[i] = ttfGetSHORT (fp);
35  for (i = 0; i < 4; i++)
36  if (valueFormat & (ValueFormat_XPlaDevice << i))
37  value->valDevice[i].offset = ttfGetUSHORT (fp);
38 
39  return value;
40 }
41 
42 static void
44 {
45  int i;
46 
47  if (value == NULL)
48  return;
49  for (i = 0; i < 4; i++)
50  if (value->valDevice[i].offset)
51  value->valDevice[i].device = otfMakeDevice (fp, offset + value->valDevice[i].offset);
52 }
53 
54 static const char *txtDesign[4] = {
55  "XPlacement",
56  "YPlacement",
57  "XAdvance",
58  "YAdvance"
59 };
60 
61 static const char *txtDevice[4] = {
62  "XPlaDevice",
63  "YPlaDevice",
64  "XAdvDevice",
65  "YAdvDevice"
66 };
67 
68 static void
69 gposPrintValueRecord (FILE *fp, const char *str, USHORT valueFormat, ValueRecordPtr value)
70 {
71  const char *s = ":";
72  int i;
73 
74  for (i = 0; i < 4; i++)
75  if (valueFormat & (ValueFormat_XPlacement << i)) {
76  fprintf (fp, "%s %s = %d\n", s, txtDesign[i], value->valDesign[i]);
77  s = str;
78  }
79  for (i = 0; i < 4; i++)
80  if (value->valDevice[i].device) {
81  fprintf (fp, "%s %s:", s, txtDevice[i]);
82  otfPrintDevice (fp, value->valDevice[i].device);
83  s = str;
84  }
85 }
86 
88 {
89  if (value) {
90  int i;
91 
92  for (i = 0; i < 4; i++)
93  if (value->valDevice[i].device)
94  free (value->valDevice[i].device);
95  free (value);
96  }
97 }
98 
100 {
101  AnchorPtr anchor;
102  USHORT anchorFormat;
103  USHORT xOffset, yOffset;
104 
105  xfseek (fp, offset, SEEK_SET, "gposMakeAnchor");
106 
107  anchorFormat = ttfGetUSHORT (fp);
108  switch (anchorFormat)
109  {
110  case 1:
111  anchor.anchor1 = XCALLOC1 (Anchor1);
112  break;
113  case 2:
114  anchor.anchor2 = XCALLOC1 (Anchor2);
115  break;
116  case 3:
117  anchor.anchor3 = XCALLOC1 (Anchor3);
118  break;
119  default:
120  ttfError ("Unrecognized GPOS anchorFormat\n");
121  }
122  anchor.anchor1->anchorFormat = anchorFormat;
123  anchor.anchor1->xCoordinate = ttfGetSHORT (fp);
124  anchor.anchor1->yCoordinate = ttfGetSHORT (fp);
125 
126  switch (anchorFormat)
127  {
128  case 2:
129  anchor.anchor2->anchorPoint = ttfGetUSHORT (fp);
130  break;
131  case 3:
132  xOffset = ttfGetUSHORT (fp);
133  yOffset = ttfGetUSHORT (fp);
134  if (xOffset)
135  anchor.anchor3->xDevice = otfMakeDevice (fp, offset + xOffset);
136  if (yOffset)
137  anchor.anchor3->yDevice = otfMakeDevice (fp, offset + yOffset);
138  break;
139  }
140 
141  return anchor;
142 }
143 
144 static void
145 gposPrintAnchor (FILE *fp, const char *str, AnchorPtr anchor)
146 {
147  fprintf (fp, "anchorFormat = %d, xCoordinate = %d, yCoordinate = %d\n",
148  anchor.anchor1->anchorFormat, anchor.anchor1->xCoordinate, anchor.anchor1->yCoordinate);
149 
150  switch (anchor.anchor1->anchorFormat)
151  {
152  case 2:
153  fprintf (fp, "%sanchorPoint = %d\n", str, anchor.anchor2->anchorPoint);
154  break;
155  case 3:
156  if (anchor.anchor3->xDevice) {
157  fprintf (fp, "%sxDevice: ", str);
158  otfPrintDevice (fp, anchor.anchor3->xDevice);
159  }
160  if (anchor.anchor3->yDevice) {
161  fprintf (fp, "%syDevice: ", str);
162  otfPrintDevice (fp, anchor.anchor3->yDevice);
163  }
164  break;
165  }
166 }
167 
168 static void freeAnchor (AnchorPtr anchor)
169 {
170  if (anchor.anchor3) {
171  if (anchor.anchor3->anchorFormat == 3) {
172  if (anchor.anchor3->xDevice)
173  free (anchor.anchor3->xDevice);
174  if (anchor.anchor3->yDevice)
175  free (anchor.anchor3->yDevice);
176  }
177  free (anchor.anchor3);
178  }
179 }
180 
181 static MarkRecordPtr
183 {
184  int i;
185  MarkRecordPtr markArray;
186  USHORT *aOffset;
187 
188  xfseek (fp, offset, SEEK_SET, "gposMakeMarkArray");
189 
190  *markCount = ttfGetUSHORT (fp);
191  markArray = XCALLOC (*markCount, MarkRecord);
192  aOffset = XCALLOC (*markCount, USHORT);
193  for (i = 0; i < *markCount; i++) {
194  markArray[i].class = ttfGetUSHORT (fp);
195  aOffset[i] = ttfGetUSHORT (fp);
196  }
197  for (i = 0; i < *markCount; i++)
198  markArray[i].markAnchor = gposMakeAnchor (fp, offset + aOffset[i]);
199  free (aOffset);
200 
201  return markArray;
202 }
203 
204 static void
206 {
207  int i;
208 
209  for (i = 0; i < markCount; i++) {
210  fprintf (fp, "\t %2d. class: %d - ", i, markArray[i].class);
211  gposPrintAnchor (fp, "\t\t ", markArray[i].markAnchor);
212  }
213 }
214 
215 /* Used for both pos41->baseArray and pos61->mark2Array. */
216 static AnchorPtr *
217 gposMakeBaseArray (FILE *fp, USHORT *baseCount, USHORT classCount, ULONG offset)
218 {
219  int i;
220  AnchorPtr *baseArray;
221  USHORT *aOffset;
222 
223  xfseek (fp, offset, SEEK_SET, "gposMakeBaseArray");
224 
225  *baseCount = ttfGetUSHORT (fp);
226  aOffset = ttfMakeUSHORT (*baseCount * classCount, fp);
227  baseArray = XCALLOC (*baseCount * classCount, AnchorPtr);
228  for (i = 0; i < *baseCount * classCount; i++)
229  if (aOffset[i])
230  baseArray[i] = gposMakeAnchor (fp, offset + aOffset[i]);
231  free (aOffset);
232 
233  return baseArray;
234 }
235 
237 {
238  USHORT cOffset;
240 
241  cOffset = ttfGetUSHORT (fp);
242  pos->valueFormat = getValueFormat (fp);
243  pos->value = gposMakeValueRecord (pos->valueFormat, fp);
244  pos->coverage = otfMakeCoverage (fp, offset + cOffset);
245  gposLoadValueRecord (pos->value, fp, offset);
246 
247  return pos;
248 }
249 
250 static void printGPOS11 (FILE *fp, Pos11Ptr pos)
251 {
252  fprintf (fp, " - Single Adjustment Value\n\t ");
253  otfPrintCoverage (fp, pos->coverage);
254  fprintf (fp, "\t valueFormat: 0x%04x\n", pos->valueFormat);
255  if (pos->valueFormat) {
256  fprintf (fp, "\t value");
257  gposPrintValueRecord (fp, "\t\t", pos->valueFormat, pos->value);
258  }
259 }
260 
261 static void freeGPOS11 (Pos11Ptr pos)
262 {
263  freeValueRecord (pos->value);
264  otfFreeCoverage (pos->coverage);
265 }
266 
268 {
269  int i;
270  USHORT cOffset;
272 
273  cOffset = ttfGetUSHORT (fp);
274  pos->valueFormat = getValueFormat (fp);
275  pos->valueCount = ttfGetUSHORT (fp);
276  pos->value = XCALLOC (pos->valueCount, ValueRecordPtr);
277  for (i = 0; i < pos->valueCount; i++)
278  pos->value[i] = gposMakeValueRecord (pos->valueFormat, fp);
279  pos->coverage = otfMakeCoverage (fp, offset + cOffset);
280  for (i = 0; i < pos->valueCount; i++)
281  gposLoadValueRecord (pos->value[i], fp, offset);
282 
283  return pos;
284 }
285 
286 static void printGPOS12 (FILE *fp, Pos12Ptr pos)
287 {
288  int i;
289 
290  fprintf (fp, " - Single Adjustment List\n\t ");
291  otfPrintCoverage (fp, pos->coverage);
292  fprintf (fp, "\t valueFormat: 0x%04x, valueCount: %d\n", pos->valueFormat, pos->valueCount);
293  for (i = 0; i < pos->valueCount; i++) {
294  fprintf (fp, "\t %2d. value", i);
295  gposPrintValueRecord (fp, "\t\t ", pos->valueFormat, pos->value[i]);
296  }
297 }
298 
299 static void freeGPOS12 (Pos12Ptr pos)
300 {
301  int i;
302 
303  for (i = 0; i < pos->valueCount; i++)
304  freeValueRecord (pos->value[i]);
305  free (pos->value);
306  otfFreeCoverage (pos->coverage);
307 }
308 
310 {
311  int j;
312  PairSetPtr pairSet = &pos->pairSet[i];
313 
314  xfseek (fp, offset, SEEK_SET, "gposLoadPairSet");
315 
316  pairSet->pairValueCount = ttfGetUSHORT (fp);
317  pairSet->pairValue = XCALLOC (pairSet->pairValueCount, PairValueRecord);
318  for (j = 0; j < pairSet->pairValueCount; j++) {
319  pairSet->pairValue[j].secondGlyph = ttfGetUSHORT (fp);
320  pairSet->pairValue[j].value1 = gposMakeValueRecord (pos->valueFormat1, fp);
321  pairSet->pairValue[j].value2 = gposMakeValueRecord (pos->valueFormat2, fp);
322  }
323 }
324 
326 {
327  int i;
328  USHORT cOffset;
329  USHORT *pOffset;
331 
332  cOffset = ttfGetUSHORT (fp);
333  pos->valueFormat1 = getValueFormat (fp);
334  pos->valueFormat2 = getValueFormat (fp);
335  pos->pairSetCount = ttfGetUSHORT (fp);
336  pOffset = ttfMakeUSHORT (pos->pairSetCount, fp);
337  pos->coverage = otfMakeCoverage (fp, offset + cOffset);
338  pos->pairSet = XCALLOC (pos->pairSetCount, PairSet);
339  for (i = 0; i < pos->pairSetCount; i++)
340  gposLoadPairSet (pos, i, fp, offset + pOffset[i]);
341  free (pOffset);
342  for (i = 0; i < pos->pairSetCount; i++) {
343  int j;
344 
345  for (j = 0; j < pos->pairSet[i].pairValueCount; j++) {
346  gposLoadValueRecord (pos->pairSet[i].pairValue[j].value1, fp, offset);
347  gposLoadValueRecord (pos->pairSet[i].pairValue[j].value2, fp, offset);
348  }
349  }
350 
351  return pos;
352 }
353 
354 static void printGPOS21 (FILE *fp, Pos21Ptr pos)
355 {
356  int i;
357 
358  fprintf (fp, " - Pair Adjustment List\n\t ");
359  otfPrintCoverage (fp, pos->coverage);
360  fprintf (fp, "\t valueFormat1: 0x%04x, valueFormat2: 0x%04x, pairSetCount: %d\n",
361  pos->valueFormat1, pos->valueFormat2, pos->pairSetCount);
362  for (i = 0; i < pos->pairSetCount; i++) {
363  int j;
364 
365  fprintf (fp, "\t %2d. pairValueCount: %d\n", i, pos->pairSet[i].pairValueCount);
366  for (j = 0; j < pos->pairSet[i].pairValueCount; j++) {
367  fprintf (fp, "\t %2d. secondGlyph: %d\n", j,
368  pos->pairSet[i].pairValue[j].secondGlyph);
369  if (pos->valueFormat1) {
370  fprintf (fp, "\t\t value1");
371  gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat1,
372  pos->pairSet[i].pairValue[j].value1);
373  }
374  if (pos->valueFormat2) {
375  fprintf (fp, "\t\t value2");
376  gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat2,
377  pos->pairSet[i].pairValue[j].value2);
378  }
379  }
380  }
381 }
382 
383 static void freeGPOS21 (Pos21Ptr pos)
384 {
385  int i;
386 
387  for (i = 0; i < pos->pairSetCount; i++) {
388  int j;
389  for (j = 0; j < pos->pairSet[i].pairValueCount; j++) {
390  freeValueRecord (pos->pairSet[i].pairValue[j].value1);
391  freeValueRecord (pos->pairSet[i].pairValue[j].value2);
392  }
393  free (pos->pairSet[i].pairValue);
394  }
395  free (pos->pairSet);
396  otfFreeCoverage (pos->coverage);
397 }
398 
400 {
401  int i;
402  USHORT cOffset, cOffset1, cOffset2;
404 
405  cOffset = ttfGetUSHORT (fp);
406  pos->valueFormat1 = getValueFormat (fp);
407  pos->valueFormat2 = getValueFormat (fp);
408  cOffset1 = ttfGetUSHORT (fp);
409  cOffset2 = ttfGetUSHORT (fp);
410  pos->class1Count = ttfGetUSHORT (fp);
411  pos->class2Count = ttfGetUSHORT (fp);
412  pos->values = XCALLOC (2 * pos->class1Count * pos->class2Count, ValueRecordPtr);
413  for (i = 0; i < 2 * pos->class1Count * pos->class2Count; i++)
414  pos->values[i] = gposMakeValueRecord (i & 1 ? pos->valueFormat2 : pos->valueFormat1, fp);
415  pos->coverage = otfMakeCoverage (fp, offset + cOffset);
416  pos->classDef1 = otfMakeClassDef (fp, offset + cOffset1);
417  pos->classDef2 = otfMakeClassDef (fp, offset + cOffset2);
418  for (i = 0; i < 2 * pos->class1Count * pos->class2Count; i++)
419  gposLoadValueRecord (pos->values[i], fp, offset);
420 
421  return pos;
422 }
423 
424 static void printGPOS22 (FILE *fp, Pos22Ptr pos)
425 {
426  int i, num = 0;
427 
428  fprintf (fp, " - Pair Adjustment Class\n\t ");
429  otfPrintCoverage (fp, pos->coverage);
430  fprintf (fp, "\t valueFormat1: 0x%04x, valueFormat2: 0x%04x\n",
431  pos->valueFormat1, pos->valueFormat2);
432  fprintf (fp, "\t ClassDef1 - ");
433  otfPrintClassDef (fp, pos->classDef1);
434  fprintf (fp, "\t ClassDef2 - ");
435  otfPrintClassDef (fp, pos->classDef2);
436  fprintf (fp, "\t class1Count: %d, class2Count: %d\n",
437  pos->class1Count, pos->class2Count);
438  for (i = 0; i < pos->class1Count; i++) {
439  int j;
440  const char *s = "";
441 
442  fprintf (fp, "\t %2d.", i);
443  for (j = 0; j < pos->class2Count; j++) {
444  fprintf (fp, "%s %2d.", s, j);
445  s = "\t ";
446 
447  if (pos->valueFormat1) {
448  fprintf (fp, " value1");
449  gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat1,
450  pos->values[num]);
451  }
452  num++;
453  if (pos->valueFormat2) {
454  fprintf (fp, " value2");
455  gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat2,
456  pos->values[num]);
457  }
458  num++;
459  }
460  }
461 }
462 
463 static void freeGPOS22 (Pos22Ptr pos)
464 {
465  int i;
466 
467  for (i = 0; i < 2 * pos->class1Count * pos->class2Count; i++)
468  freeValueRecord (pos->values[i]);
469  free (pos->values);
470  otfFreeCoverage (pos->coverage);
471  otfFreeClassDef (pos->classDef1);
472  otfFreeClassDef (pos->classDef2);
473 }
474 
476 {
477  int i;
478  USHORT cOffset;
479  USHORT *eOffset;
481 
482  cOffset = ttfGetUSHORT (fp);
483  pos->entryExitCount = ttfGetUSHORT (fp);
484  eOffset = ttfMakeUSHORT (2 * pos->entryExitCount, fp);
485  pos->coverage = otfMakeCoverage (fp, offset + cOffset);
486  pos->entryExit = XCALLOC (2 * pos->entryExitCount, AnchorPtr);
487  for (i = 0; i < 2 * pos->entryExitCount; i++)
488  if (eOffset[i])
489  pos->entryExit[i] = gposMakeAnchor (fp, offset + eOffset[i]);
490  free (eOffset);
491 
492  return pos;
493 }
494 
495 static void printGPOS31 (FILE *fp, Pos31Ptr pos)
496 {
497  int i, num = 0;
498 
499  fprintf (fp, " - Cursive Attachment\n\t ");
500  otfPrintCoverage (fp, pos->coverage);
501  fprintf (fp, "\t entryExitCount: %d\n", pos->entryExitCount);
502  for (i = 0; i < pos->entryExitCount; i++) {
503  int j;
504  const char *s = "";
505 
506  fprintf (fp, "\t %2d. ", i);
507  for (j = 0; j < 2; j++) {
508  if (pos->entryExit[num].anchor1) {
509  fprintf (fp, "%s%sAnchor - ", s, j ? "exit" : "entry");
510  gposPrintAnchor (fp, "\t\t ", pos->entryExit[num]);
511  s = "\t ";
512  }
513  num++;
514  }
515  }
516 }
517 
518 static void freeGPOS31 (Pos31Ptr pos)
519 {
520  int i;
521 
522  for (i = 0; i < 2 * pos->entryExitCount; i++)
523  freeAnchor (pos->entryExit[i]);
524  free (pos->entryExit);
525  otfFreeCoverage (pos->coverage);
526 }
527 
529 {
530  USHORT mcOffset, bcOffset, maOffset, baOffset;
532 
533  mcOffset = ttfGetUSHORT (fp);
534  bcOffset = ttfGetUSHORT (fp);
535  pos->classCount = ttfGetUSHORT (fp);
536  maOffset = ttfGetUSHORT (fp);
537  baOffset = ttfGetUSHORT (fp);
538  pos->markCoverage = otfMakeCoverage (fp, offset + mcOffset);
539  pos->baseCoverage = otfMakeCoverage (fp, offset + bcOffset);
540  pos->markArray = gposMakeMarkArray (fp, &pos->markCount, offset + maOffset);
541  pos->baseArray = gposMakeBaseArray (fp, &pos->baseCount, pos->classCount, offset + baOffset);
542 
543  return pos;
544 }
545 
546 static void printGPOS41 (FILE *fp, Pos41Ptr pos)
547 {
548  int i, num = 0;
549 
550  fprintf (fp, " - Mark To Base Attachment\n\t mark");
551  otfPrintCoverage (fp, pos->markCoverage);
552  fprintf (fp, "\t markArray - markCount: %d\n", pos->markCount);
553  gposPrintMarkArray (fp, pos->markCount, pos->markArray);
554  fprintf (fp, "\t base");
555  otfPrintCoverage (fp, pos->baseCoverage);
556  fprintf (fp, "\t baseArray - baseCount: %d, classCount: %d\n",
557  pos->baseCount, pos->classCount);
558  for (i = 0; i < pos->baseCount; i++) {
559  int j;
560  const char *s = "";
561 
562  fprintf (fp, "\t %2d. ", i);
563  for (j = 0; j < pos->classCount; j++) {
564  if (pos->baseArray[num].anchor1) {
565  fprintf (fp, "%s%2d. ", s, j);
566  gposPrintAnchor (fp, "\t\t ", pos->baseArray[num]);
567  s = "\t ";
568  }
569  num++;
570  }
571  }
572 }
573 
574 static void freeGPOS41 (Pos41Ptr pos)
575 {
576  int i;
577 
578  for (i = 0; i < pos->markCount; i++)
579  freeAnchor (pos->markArray[i].markAnchor);
580  free (pos->markArray);
581  for (i = 0; i < pos->baseCount * pos->classCount; i++)
582  freeAnchor (pos->baseArray[i]);
583  free (pos->baseArray);
584  otfFreeCoverage (pos->markCoverage);
585  otfFreeCoverage (pos->baseCoverage);
586 }
587 
588 static void
590 {
591  int i;
592  USHORT *aOffset;
593 
594  xfseek (fp, offset, SEEK_SET, "gposLoadLigatureArray");
595 
596  ligatureArray->componentCount = ttfGetUSHORT (fp);
597  aOffset = ttfMakeUSHORT (ligatureArray->componentCount * classCount, fp);
598  ligatureArray->componentRecord = XCALLOC (ligatureArray->componentCount * classCount, AnchorPtr);
599  for (i = 0; i < ligatureArray->componentCount * classCount; i++)
600  if (aOffset[i])
601  ligatureArray->componentRecord[i] = gposMakeAnchor (fp, offset + aOffset[i]);
602  free (aOffset);
603 }
604 
605 static LigatureAttachPtr
606 gposMakeLigatureArray (FILE *fp, USHORT *ligatureCount, USHORT classCount, ULONG offset)
607 {
608  int i;
609  LigatureAttachPtr ligatureArray;
610  USHORT *aOffset;
611 
612  xfseek (fp, offset, SEEK_SET, "gposMakeLigatureArray");
613 
614  *ligatureCount = ttfGetUSHORT (fp);
615  aOffset = ttfMakeUSHORT (*ligatureCount, fp);
616  ligatureArray = XCALLOC (*ligatureCount, LigatureAttach);
617  for (i = 0; i < *ligatureCount; i++)
618  gposLoadLigatureArray (&ligatureArray[i], classCount, fp, offset + aOffset[i]);
619  free (aOffset);
620 
621  return ligatureArray;
622 }
623 
625 {
626  USHORT mcOffset, lcOffset, maOffset, laOffset;
628 
629  mcOffset = ttfGetUSHORT (fp);
630  lcOffset = ttfGetUSHORT (fp);
631  pos->classCount = ttfGetUSHORT (fp);
632  maOffset = ttfGetUSHORT (fp);
633  laOffset = ttfGetUSHORT (fp);
634  pos->markCoverage = otfMakeCoverage (fp, offset + mcOffset);
635  pos->ligatureCoverage = otfMakeCoverage (fp, offset + lcOffset);
636  pos->markArray = gposMakeMarkArray (fp, &pos->markCount, offset + maOffset);
637  pos->ligatureArray = gposMakeLigatureArray (fp, &pos->ligatureCount, pos->classCount, offset + laOffset);
638 
639  return pos;
640 }
641 
642 static void printGPOS51 (FILE *fp, Pos51Ptr pos)
643 {
644  int i;
645 
646  fprintf (fp, " - Mark To Ligature Attachment\n\t mark");
647  otfPrintCoverage (fp, pos->markCoverage);
648  fprintf (fp, "\t markArray - markCount: %d\n", pos->markCount);
649  gposPrintMarkArray (fp, pos->markCount, pos->markArray);
650  fprintf (fp, "\t ligature");
651  otfPrintCoverage (fp, pos->ligatureCoverage);
652  fprintf (fp, "\t ligatureArray - ligatureCount: %d\n", pos->ligatureCount);
653  for (i = 0; i < pos->ligatureCount; i++) {
654  int j, num = 0;
655 
656  fprintf (fp, "\t %2d. componentCount: %d, classCount: %d\n", i,
657  pos->ligatureArray[i].componentCount, pos->classCount);
658  for (j = 0; j < pos->ligatureArray[i].componentCount; j++) {
659  int k;
660  const char *s = "";
661 
662  fprintf (fp, "\t %2d. ", j);
663  for (k = 0; k < pos->classCount; k++) {
664  if (pos->ligatureArray[i].componentRecord[num].anchor1) {
665  fprintf (fp, "%s%2d. ", s, k);
666  gposPrintAnchor (fp, "\t\t ", pos->ligatureArray[i].componentRecord[num]);
667  s = "\t\t ";
668  }
669  num++;
670  }
671  }
672  }
673 }
674 
675 static void freeGPOS51 (Pos51Ptr pos)
676 {
677  int i;
678 
679  for (i = 0; i < pos->markCount; i++)
680  freeAnchor (pos->markArray[i].markAnchor);
681  free (pos->markArray);
682  for (i = 0; i < pos->ligatureCount; i++) {
683  int j;
684 
685  for (j = 0; j < pos->ligatureArray[i].componentCount * pos->classCount; j++)
686  freeAnchor (pos->ligatureArray[i].componentRecord[j]);
687  }
688  free (pos->ligatureArray);
689  otfFreeCoverage (pos->markCoverage);
690  otfFreeCoverage (pos->ligatureCoverage);
691 }
692 
694 {
695  USHORT c1Offset, c2Offset, a1Offset, a2Offset;
697 
698  c1Offset = ttfGetUSHORT (fp);
699  c2Offset = ttfGetUSHORT (fp);
700  pos->classCount = ttfGetUSHORT (fp);
701  a1Offset = ttfGetUSHORT (fp);
702  a2Offset = ttfGetUSHORT (fp);
703  pos->mark1Coverage = otfMakeCoverage (fp, offset + c1Offset);
704  pos->mark2Coverage = otfMakeCoverage (fp, offset + c2Offset);
705  pos->mark1Array = gposMakeMarkArray (fp, &pos->mark1Count, offset + a1Offset);
706  pos->mark2Array = gposMakeBaseArray (fp, &pos->mark2Count, pos->classCount, offset + a2Offset);
707 
708  return pos;
709 }
710 
711 static void printGPOS61 (FILE *fp, Pos61Ptr pos)
712 {
713  int i, num = 0;
714 
715  fprintf (fp, " - Mark To Mark Attachment\n\t mark1");
716  otfPrintCoverage (fp, pos->mark1Coverage);
717  fprintf (fp, "\t mark1Array - mark1Count: %d\n", pos->mark1Count);
718  gposPrintMarkArray (fp, pos->mark1Count, pos->mark1Array);
719  fprintf (fp, "\t mark2");
720  otfPrintCoverage (fp, pos->mark2Coverage);
721  fprintf (fp, "\t mark2Array - mark2Count: %d, classCount: %d\n",
722  pos->mark2Count, pos->classCount);
723  for (i = 0; i < pos->mark2Count; i++) {
724  int j;
725  const char *s = "";
726 
727  fprintf (fp, "\t %2d. ", i);
728  for (j = 0; j < pos->classCount; j++) {
729  if (pos->mark2Array[num].anchor1) {
730  fprintf (fp, "%s%2d. ", s, j);
731  gposPrintAnchor (fp, "\t\t ", pos->mark2Array[num]);
732  s = "\t ";
733  }
734  num++;
735  }
736  }
737 }
738 
739 static void freeGPOS61 (Pos61Ptr pos)
740 {
741  int i;
742 
743  for (i = 0; i < pos->mark1Count; i++)
744  freeAnchor (pos->mark1Array[i].markAnchor);
745  free (pos->mark1Array);
746  for (i = 0; i < pos->mark2Count * pos->classCount; i++)
747  freeAnchor (pos->mark2Array[i]);
748  free (pos->mark2Array);
749  otfFreeCoverage (pos->mark1Coverage);
750  otfFreeCoverage (pos->mark2Coverage);
751 }
752 
753 #define makeGPOS71 makeOTFCtx1
754 #define printGPOS71 printOTFCtx1
755 #define freeGPOS71 freeOTFCtx1
756 
757 #define makeGPOS72 makeOTFCtx2
758 #define printGPOS72 printOTFCtx2
759 #define freeGPOS72 freeOTFCtx2
760 
761 #define makeGPOS73 makeOTFCtx3
762 #define printGPOS73 printOTFCtx3
763 #define freeGPOS73 freeOTFCtx3
764 
765 #define makeGPOS81 makeOTFChn1
766 #define printGPOS81 printOTFChn1
767 #define freeGPOS81 freeOTFChn1
768 
769 #define makeGPOS82 makeOTFChn2
770 #define printGPOS82 printOTFChn2
771 #define freeGPOS82 freeOTFChn2
772 
773 #define makeGPOS83 makeOTFChn3
774 #define printGPOS83 printOTFChn3
775 #define freeGPOS83 freeOTFChn3
776 
778 {
780  USHORT lookupFormat;
781 
782 again:
783  if (lookupType == 0 || lookupType > PosLookup_Max)
784  ttfError ("Unrecognized GPOS lookupType\n");
785 
786  xfseek (fp, offset, SEEK_SET, "makeGPOSLookup");
787 
788  lookupFormat = ttfGetUSHORT (fp);
789  if (lookupFormat & 0xfff0)
790  lookupFormat = 0x000f;
791 
792  switch (lookupType << 4 | lookupFormat)
793  {
794  case 0x011:
795  lookup.pos.pos11 = makeGPOS11 (fp, offset);
796  break;
797  case 0x012:
798  lookup.pos.pos12 = makeGPOS12 (fp, offset);
799  break;
800  case 0x021:
801  lookup.pos.pos21 = makeGPOS21 (fp, offset);
802  break;
803  case 0x022:
804  lookup.pos.pos22 = makeGPOS22 (fp, offset);
805  break;
806  case 0x031:
807  lookup.pos.pos31 = makeGPOS31 (fp, offset);
808  break;
809  case 0x041:
810  lookup.pos.pos41 = makeGPOS41 (fp, offset);
811  break;
812  case 0x051:
813  lookup.pos.pos51 = makeGPOS51 (fp, offset);
814  break;
815  case 0x061:
816  lookup.pos.pos61 = makeGPOS61 (fp, offset);
817  break;
818  case 0x071:
819  lookup.pos.pos71 = makeGPOS71 (fp, offset);
820  break;
821  case 0x072:
822  lookup.pos.pos72 = makeGPOS72 (fp, offset);
823  break;
824  case 0x073:
825  lookup.pos.pos73 = makeGPOS73 (fp, offset);
826  break;
827  case 0x081:
828  lookup.pos.pos81 = makeGPOS81 (fp, offset);
829  break;
830  case 0x082:
831  lookup.pos.pos82 = makeGPOS82 (fp, offset);
832  break;
833  case 0x083:
834  lookup.pos.pos83 = makeGPOS83 (fp, offset);
835  break;
836  case 0x091:
837  lookupType = ttfGetUSHORT (fp);
838  if (lookupType == 9)
839  ttfError ("Invalid GPOS extensionLookupType\n");
840  offset += ttfGetULONG (fp);
841  goto again;
842  default:
843  ttfError ("Unrecognized GPOS lookupFormat\n");
844  }
845 
846  lookup.otf->lookupType = lookupType;
847  lookup.otf->lookupFormat = lookupFormat;
848 
849  return lookup;
850 }
851 
853 {
854  switch (lookup.otf->lookupType << 4 | lookup.otf->lookupFormat)
855  {
856  case 0x011:
857  printGPOS11 (fp, lookup.pos.pos11);
858  break;
859  case 0x012:
860  printGPOS12 (fp, lookup.pos.pos12);
861  break;
862  case 0x021:
863  printGPOS21 (fp, lookup.pos.pos21);
864  break;
865  case 0x022:
866  printGPOS22 (fp, lookup.pos.pos22);
867  break;
868  case 0x031:
869  printGPOS31 (fp, lookup.pos.pos31);
870  break;
871  case 0x041:
872  printGPOS41 (fp, lookup.pos.pos41);
873  break;
874  case 0x051:
875  printGPOS51 (fp, lookup.pos.pos51);
876  break;
877  case 0x061:
878  printGPOS61 (fp, lookup.pos.pos61);
879  break;
880  case 0x071:
881  printGPOS71 (fp, lookup.pos.pos71);
882  break;
883  case 0x072:
884  printGPOS72 (fp, lookup.pos.pos72);
885  break;
886  case 0x073:
887  printGPOS73 (fp, lookup.pos.pos73);
888  break;
889  case 0x081:
890  printGPOS81 (fp, lookup.pos.pos81);
891  break;
892  case 0x082:
893  printGPOS82 (fp, lookup.pos.pos82);
894  break;
895  case 0x083:
896  printGPOS83 (fp, lookup.pos.pos83);
897  break;
898  default:
899  ttfError ("Internal error: printGPOSLookup\n");
900  }
901 }
902 
904 {
905  switch (lookup.otf->lookupType << 4 | lookup.otf->lookupFormat)
906  {
907  case 0x011:
908  freeGPOS11 (lookup.pos.pos11);
909  break;
910  case 0x012:
911  freeGPOS12 (lookup.pos.pos12);
912  break;
913  case 0x021:
914  freeGPOS21 (lookup.pos.pos21);
915  break;
916  case 0x022:
917  freeGPOS22 (lookup.pos.pos22);
918  break;
919  case 0x031:
920  freeGPOS31 (lookup.pos.pos31);
921  break;
922  case 0x041:
923  freeGPOS41 (lookup.pos.pos41);
924  break;
925  case 0x051:
926  freeGPOS51 (lookup.pos.pos51);
927  break;
928  case 0x061:
929  freeGPOS61 (lookup.pos.pos61);
930  break;
931  case 0x071:
932  freeGPOS71 (lookup.pos.pos71);
933  break;
934  case 0x072:
935  freeGPOS72 (lookup.pos.pos72);
936  break;
937  case 0x073:
938  freeGPOS73 (lookup.pos.pos73);
939  break;
940  case 0x081:
941  freeGPOS81 (lookup.pos.pos81);
942  break;
943  case 0x082:
944  freeGPOS82 (lookup.pos.pos82);
945  break;
946  case 0x083:
947  freeGPOS83 (lookup.pos.pos83);
948  break;
949  default:
950  ttfError ("Internal error: freeGPOSLookup\n");
951  }
952 }
953 
954 static void ttfLoadGPOS (FILE *fp, GPOSPtr gpos, ULONG offset)
955 {
956  USHORT sOffset, fOffset, lOffset;
957 
958  xfseek (fp, offset, SEEK_SET, "ttfLoadGPOS");
959 
960  gpos->version = ttfGetFixed (fp);
961  sOffset = ttfGetUSHORT (fp);
962  fOffset = ttfGetUSHORT (fp);
963  lOffset = ttfGetUSHORT (fp);
964 
965  gpos->scriptList = otfMakeScriptList (fp, offset + sOffset);
966  gpos->featureList = otfMakeFeatureList (fp, offset + fOffset);
967  gpos->lookupList = otfMakeLookupList (fp, offset + lOffset, &makeGPOSLookup);
968 }
969 
971 {
972  ULONG tag = FT_MAKE_TAG ('G', 'P', 'O', 'S');
973  TableDirPtr ptd;
974 
975  if ((ptd = ttfLookUpTableDir (tag, font)) != NULL)
976  {
977  font->gpos = XCALLOC1 (GPOS);
978  ttfLoadGPOS (font->fp, font->gpos, ptd->offset);
979  }
980 }
981 
983 {
984  int b[2];
985 
986  FixedSplit (gpos->version, b);
987 
988  fprintf (fp, "'GPOS' Table - Glyph Positioning Data\n");
989  fprintf (fp, "-------------------------------------\n");
990  fprintf (fp, "\t 'GPOS' Version:\t %d.%d\n",b[1],b[0]);
991 
995 }
996 
997 void ttfFreeGPOS (GPOSPtr gpos)
998 {
999  if (gpos != NULL)
1000  {
1001  otfFreeScriptList (gpos->scriptList);
1004  free (gpos);
1005  }
1006 }
int lookup(const char *)
#define b
Definition: jpegint.h:372
#define free(a)
Definition: decNumber.cpp:310
#define s
Definition: afcover.h:80
static void printGPOS51(FILE *fp, Pos51Ptr pos)
Definition: gpos.c:642
static Pos11Ptr makeGPOS11(FILE *fp, ULONG offset)
Definition: gpos.c:236
static void freeGPOS11(Pos11Ptr pos)
Definition: gpos.c:261
static const char * txtDesign[4]
Definition: gpos.c:54
#define makeGPOS82
Definition: gpos.c:769
void ttfPrintGPOS(FILE *fp, GPOSPtr gpos)
Definition: gpos.c:982
static void freeGPOSLookup(LookupPtr lookup)
Definition: gpos.c:903
static void freeValueRecord(ValueRecordPtr value)
Definition: gpos.c:87
#define printGPOS82
Definition: gpos.c:770
static void gposLoadValueRecord(ValueRecordPtr value, FILE *fp, ULONG offset)
Definition: gpos.c:43
#define freeGPOS82
Definition: gpos.c:771
static void freeAnchor(AnchorPtr anchor)
Definition: gpos.c:168
static const char * txtDevice[4]
Definition: gpos.c:61
#define freeGPOS81
Definition: gpos.c:767
#define freeGPOS72
Definition: gpos.c:759
#define makeGPOS81
Definition: gpos.c:765
static Pos31Ptr makeGPOS31(FILE *fp, ULONG offset)
Definition: gpos.c:475
static void freeGPOS41(Pos41Ptr pos)
Definition: gpos.c:574
static void freeGPOS22(Pos22Ptr pos)
Definition: gpos.c:463
#define printGPOS81
Definition: gpos.c:766
static AnchorPtr * gposMakeBaseArray(FILE *fp, USHORT *baseCount, USHORT classCount, ULONG offset)
Definition: gpos.c:217
static LookupPtr makeGPOSLookup(FILE *fp, USHORT lookupType, ULONG offset)
Definition: gpos.c:777
static void printGPOS11(FILE *fp, Pos11Ptr pos)
Definition: gpos.c:250
#define freeGPOS73
Definition: gpos.c:763
#define freeGPOS71
Definition: gpos.c:755
static Pos12Ptr makeGPOS12(FILE *fp, ULONG offset)
Definition: gpos.c:267
static void freeGPOS61(Pos61Ptr pos)
Definition: gpos.c:739
static Pos22Ptr makeGPOS22(FILE *fp, ULONG offset)
Definition: gpos.c:399
#define printGPOS72
Definition: gpos.c:758
#define printGPOS71
Definition: gpos.c:754
#define makeGPOS71
Definition: gpos.c:753
#define makeGPOS72
Definition: gpos.c:757
#define makeGPOS83
Definition: gpos.c:773
static ValueRecordPtr gposMakeValueRecord(USHORT valueFormat, FILE *fp)
Definition: gpos.c:23
static void freeGPOS21(Pos21Ptr pos)
Definition: gpos.c:383
static void freeGPOS12(Pos12Ptr pos)
Definition: gpos.c:299
static void ttfLoadGPOS(FILE *fp, GPOSPtr gpos, ULONG offset)
Definition: gpos.c:954
static void gposLoadPairSet(Pos21Ptr pos, int i, FILE *fp, ULONG offset)
Definition: gpos.c:309
static USHORT getValueFormat(FILE *fp)
Definition: gpos.c:12
#define printGPOS83
Definition: gpos.c:774
static void printGPOSLookup(FILE *fp, LookupPtr lookup)
Definition: gpos.c:852
static LigatureAttachPtr gposMakeLigatureArray(FILE *fp, USHORT *ligatureCount, USHORT classCount, ULONG offset)
Definition: gpos.c:606
static Pos51Ptr makeGPOS51(FILE *fp, ULONG offset)
Definition: gpos.c:624
static void gposPrintValueRecord(FILE *fp, const char *str, USHORT valueFormat, ValueRecordPtr value)
Definition: gpos.c:69
void ttfFreeGPOS(GPOSPtr gpos)
Definition: gpos.c:997
static void printGPOS31(FILE *fp, Pos31Ptr pos)
Definition: gpos.c:495
static MarkRecordPtr gposMakeMarkArray(FILE *fp, USHORT *markCount, ULONG offset)
Definition: gpos.c:182
static void freeGPOS31(Pos31Ptr pos)
Definition: gpos.c:518
#define makeGPOS73
Definition: gpos.c:761
static AnchorPtr gposMakeAnchor(FILE *fp, ULONG offset)
Definition: gpos.c:99
static void printGPOS41(FILE *fp, Pos41Ptr pos)
Definition: gpos.c:546
static void printGPOS21(FILE *fp, Pos21Ptr pos)
Definition: gpos.c:354
static Pos21Ptr makeGPOS21(FILE *fp, ULONG offset)
Definition: gpos.c:325
static void printGPOS61(FILE *fp, Pos61Ptr pos)
Definition: gpos.c:711
void ttfInitGPOS(TTFontPtr font)
Definition: gpos.c:970
#define freeGPOS83
Definition: gpos.c:775
static Pos61Ptr makeGPOS61(FILE *fp, ULONG offset)
Definition: gpos.c:693
#define printGPOS73
Definition: gpos.c:762
static Pos41Ptr makeGPOS41(FILE *fp, ULONG offset)
Definition: gpos.c:528
static void gposPrintAnchor(FILE *fp, const char *str, AnchorPtr anchor)
Definition: gpos.c:145
static void printGPOS22(FILE *fp, Pos22Ptr pos)
Definition: gpos.c:424
static void freeGPOS51(Pos51Ptr pos)
Definition: gpos.c:675
static void gposLoadLigatureArray(LigatureAttachPtr ligatureArray, USHORT classCount, FILE *fp, ULONG offset)
Definition: gpos.c:589
static void printGPOS12(FILE *fp, Pos12Ptr pos)
Definition: gpos.c:286
static void gposPrintMarkArray(FILE *fp, USHORT markCount, MarkRecordPtr markArray)
Definition: gpos.c:205
#define PosLookup_Max
Definition: gpos.h:30
#define ValueFormat_XPlaDevice
Definition: gpos.h:13
#define ValueFormat_XPlacement
Definition: gpos.h:8
#define ValueFormat_Reserved
Definition: gpos.h:18
#define SEEK_SET
Definition: jmemansi.c:26
#define FT_MAKE_TAG(_x1, _x2, _x3, _x4)
Definition: fttypes.h:488
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
int num
Definition: disdvi.c:621
unsigned short USHORT
Definition: sfnt.h:36
KPSEDLL void xfseek(FILE *fp, long offset, int wherefrom, const_string filename)
Definition: xfseek.c:22
#define fprintf
Definition: mendex.h:64
ULONG ttfGetULONG(FILE *fp)
Definition: ttfread.c:66
SHORT ttfGetSHORT(FILE *fp)
Definition: ttfread.c:57
USHORT ttfGetUSHORT(FILE *fp)
Definition: ttfread.c:48
Fixed ttfGetFixed(FILE *fp)
Definition: ttfread.c:88
USHORT * ttfMakeUSHORT(size_t nelem, FILE *fp)
Definition: ttfread.c:145
void otfFreeLookupList(LookupListPtr lookupList, FreeLookupFunc freeLookup)
Definition: otfcommon.c:316
ClassDefPtr otfMakeClassDef(FILE *fp, ULONG offset)
Definition: otfcommon.c:418
void otfFreeCoverage(CoveragePtr coverage)
Definition: otfcommon.c:401
void otfFreeClassDef(ClassDefPtr classDef)
Definition: otfcommon.c:482
void otfFreeScriptList(ScriptListPtr scriptList)
Definition: otfcommon.c:155
void otfPrintCoverage(FILE *fp, CoveragePtr coverage)
Definition: otfcommon.c:371
void otfPrintClassDef(FILE *fp, ClassDefPtr classDef)
Definition: otfcommon.c:454
CoveragePtr otfMakeCoverage(FILE *fp, ULONG offset)
Definition: otfcommon.c:336
ScriptListPtr otfMakeScriptList(FILE *fp, ULONG offset)
Definition: otfcommon.c:61
void otfPrintFeatureList(FILE *fp, FeatureListPtr featureList)
Definition: otfcommon.c:220
void otfPrintDevice(FILE *fp, DevicePtr device)
Definition: otfcommon.c:523
void otfPrintScriptList(FILE *fp, ScriptListPtr scriptList)
Definition: otfcommon.c:122
void otfPrintLookupList(FILE *fp, LookupListPtr lookupList, PrintLookupFunc printLookup)
Definition: otfcommon.c:291
FeatureListPtr otfMakeFeatureList(FILE *fp, ULONG offset)
Definition: otfcommon.c:176
DevicePtr otfMakeDevice(FILE *fp, ULONG offset)
Definition: otfcommon.c:499
void otfFreeFeatureList(FeatureListPtr featureList)
Definition: otfcommon.c:234
TableDirPtr ttfLookUpTableDir(ULONG tag, TTFontPtr font)
Definition: tabledir.c:61
LookupListPtr otfMakeLookupList(FILE *fp, ULONG offset, MakeLookupFunc makeLookup)
Definition: otfcommon.c:268
const int * pos
Definition: combiners.h:905
union value value
Definition: obx.h:44
int k
Definition: otp-parser.c:70
unsigned long ULONG
Definition: pdfgen.h:158
#define fp
static int offset
Definition: ppmtogif.c:642
#define str(s)
Definition: sh6.c:399
Definition: gpos.h:45
SHORT yCoordinate
Definition: gpos.h:48
USHORT anchorFormat
Definition: gpos.h:46
SHORT xCoordinate
Definition: gpos.h:47
Definition: gpos.h:53
USHORT anchorPoint
Definition: gpos.h:57
Definition: gpos.h:62
DevicePtr yDevice
Definition: gpos.h:67
DevicePtr xDevice
Definition: gpos.h:66
USHORT anchorFormat
Definition: gpos.h:63
LookupListPtr lookupList
Definition: otftables.h:355
Fixed version
Definition: otftables.h:352
ScriptListPtr scriptList
Definition: otftables.h:353
FeatureListPtr featureList
Definition: otftables.h:354
USHORT componentCount
Definition: gpos.h:175
AnchorPtr * componentRecord
Definition: gpos.h:176
USHORT class
Definition: gpos.h:81
Definition: gpos.h:116
USHORT pairValueCount
Definition: gpos.h:117
PairValueRecordPtr pairValue
Definition: gpos.h:118
ValueRecordPtr value2
Definition: gpos.h:111
USHORT secondGlyph
Definition: gpos.h:109
ValueRecordPtr value1
Definition: gpos.h:110
Definition: gpos.h:87
Definition: gpos.h:97
Definition: gpos.h:123
Definition: gpos.h:135
Definition: gpos.h:150
Definition: gpos.h:160
Definition: gpos.h:181
Definition: gpos.h:195
Definition: ttf.h:110
ULONG offset
Definition: tables.h:30
Definition: pbmfont.h:11
Definition: zic.c:306
Definition: xmlparse.c:179
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
#define XCALLOC1(t)
Definition: ttfutil.h:60
void ttfError(const char *msg)
Definition: ttfutil.c:32
#define XCALLOC(n, t)
Definition: ttfutil.h:59
void FixedSplit(Fixed f, int b[])
Definition: ttfutil.c:14
Definition: gpos.h:72
Anchor3Ptr anchor3
Definition: gpos.h:75
Anchor1Ptr anchor1
Definition: gpos.h:73
Anchor2Ptr anchor2
Definition: gpos.h:74
Definition: obx.h:51