1 /* otfdrive.c -- OpenType font driver.
3 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA. */
32 extern int debug_flag;
37 #define USHORT unsigned short
39 /* Return nonzero (-1 if ID is zero, 1 otherwise) if OTF_Glyph *G
40 should be ignored according to LookupFlag FLAG. */
41 #define IGNORED_GLYPH(g, flag) \
42 ((g)->glyph_id == 0 ? -1 \
43 : (((flag) & (1 << (g)->GlyphClass)) \
44 || (((flag) & OTF_MarkAttachmentType) \
45 && (g)->GlyphClass == OTF_GlyphClassMark \
46 && ((flag) >> 8) != (g)->MarkAttachClass)))
48 #define GSTRING_DELETE(gstring, from, len) \
50 memmove (gstring->glyphs + from, gstring->glyphs + from + len, \
51 sizeof (OTF_Glyph) * (gstring->used - from - len)); \
52 gstring->used -= len; \
56 #define GSTRING_INSERT(gstring, pos, len) \
58 if (gstring->used + len > gstring->size) \
60 char *errfmt = "GSTRING%s"; \
62 gstring->size = gstring->used + len; \
64 = (OTF_Glyph *) realloc (gstring->glyphs, \
65 sizeof (OTF_Glyph) * gstring->size); \
66 if (! gstring->glyphs) \
67 OTF_ERROR (OTF_ERROR_MEMORY, ""); \
69 memmove (gstring->glyphs + pos + len, gstring->glyphs + pos, \
70 sizeof (OTF_Glyph) * (gstring->used - pos)); \
71 gstring->used += len; \
75 static unsigned get_class_def (OTF_ClassDef *, OTF_GlyphID);
78 gstring_subst (OTF *otf, OTF_GlyphString *gstring, int from, int to, int flag,
79 OTF_GlyphID *ids, int num)
84 int from_idx = gstring->glyphs[from].f.index.from;
85 int to_idx = gstring->glyphs[to - 1].f.index.to;
88 for (i = non_ignored_idx = to - 1; i >= from; i--)
90 OTF_Glyph *g = gstring->glyphs + i;
92 if (IGNORED_GLYPH (g, flag) == 1)
94 /* Move this glyph to the next of the current target of
98 memmove (g, g + 1, sizeof (OTF_Glyph) * (non_ignored_idx - i));
99 temp.f.index.from = from_idx;
100 temp.f.index.to = to_idx;
101 gstring->glyphs[non_ignored_idx--] = temp;
107 GSTRING_INSERT (gstring, from, (num - len));
109 GSTRING_DELETE (gstring, from, (len - num));
110 for (i = 0; i < num; i++)
112 if (gstring->glyphs[from + i].glyph_id != ids[i])
114 gstring->glyphs[from + i].c = 0;
116 gstring->glyphs[from + i].GlyphClass
117 = get_class_def (&otf->gdef->glyph_class_def, ids[i]);
119 gstring->glyphs[from + i].GlyphClass = 0;
121 gstring->glyphs[from + i].glyph_id = ids[i];
122 gstring->glyphs[from + i].positioning_type = 0;
123 gstring->glyphs[from + i].f.index.from = from_idx;
124 gstring->glyphs[from + i].f.index.to = to_idx;
131 get_coverage_index (OTF_Coverage *coverage, OTF_GlyphID id)
135 if (coverage->CoverageFormat == 1)
137 for (i = 0; i < coverage->Count; i++)
138 if (coverage->table.GlyphArray[i] == id)
143 for (i = 0; i < coverage->Count; i++)
144 if (coverage->table.RangeRecord[i].Start <= id
145 && coverage->table.RangeRecord[i].End >= id)
146 return (coverage->table.RangeRecord[i].StartCoverageIndex
147 + (id - coverage->table.RangeRecord[i].Start));
153 get_class_def (OTF_ClassDef *class_def, OTF_GlyphID glyph_id)
155 if (class_def->ClassFormat == 1)
157 int idx = (int) glyph_id - (int) class_def->f.f1.StartGlyph;
159 if (idx >= 0 && idx < class_def->f.f1.GlyphCount)
160 return class_def->f.f1.ClassValueArray[idx];
166 for (i = 0; i < class_def->f.f2.ClassRangeCount; i++)
167 if (glyph_id >= class_def->f.f2.ClassRangeRecord[i].Start
168 && glyph_id <= class_def->f.f2.ClassRangeRecord[i].End)
169 return class_def->f.f2.ClassRangeRecord[i].Class;
175 get_langsys (OTF_ScriptList *script_list,
176 const char *script, const char *language)
179 OTF_Tag script_tag = OTF_tag (script);
180 OTF_Tag langsys_tag = OTF_tag (language);
182 OTF_Tag dflt_tag = OTF_tag ("DFLT");
183 OTF_Script *dflt = NULL;
185 for (i = 0; i < script_list->ScriptCount; i++)
187 OTF_Script *script = script_list->Script + i;
189 if (script_list->Script[i].ScriptTag == dflt_tag)
191 if (script_list->Script[i].ScriptTag == script_tag)
194 return &script->DefaultLangSys;
195 for (j = 0; j < script->LangSysCount; j++)
196 if (script->LangSysRecord[j].LangSysTag == langsys_tag)
197 return script->LangSys + j;
198 return &script->DefaultLangSys;
203 dflt = script_list->Script;
205 return &dflt->DefaultLangSys;
206 for (j = 0; j < dflt->LangSysCount; j++)
207 if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
208 return dflt->LangSys + j;
209 return &dflt->DefaultLangSys;
213 setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
214 OTF_LangSys *LangSys,
215 const char *features, USHORT *lookup_flags)
218 OTF_Feature *feature;
219 int *feature_table = alloca (sizeof (int) * FeatureList->FeatureCount);
223 for (i = 0; i < FeatureList->FeatureCount; i++)
224 feature_table[i] = 0;
225 memset (lookup_flags, 0, sizeof (USHORT) * LookupList->LookupCount);
233 if (*features == '*')
235 /* Consume all remaining features. */
236 for (i = 0; i < LangSys->FeatureCount; i++)
238 int index = LangSys->FeatureIndex[i];
240 if (! feature_table[index])
242 feature = FeatureList->Feature + index;
243 for (j = 0; j < feature->LookupCount; j++)
244 lookup_flags[feature->LookupListIndex[j]] = i + 1;
250 if (*features == '~')
251 use_it = -1, features++;
252 for (i = 0; *features && *features != ','; i++, features++)
253 tagname[i] = *features;
259 tag = OTF_tag (tagname);
260 for (i = 0; i < LangSys->FeatureCount; i++)
262 feature = FeatureList->Feature + LangSys->FeatureIndex[i];
263 if (tag == feature->FeatureTag)
265 if (feature_table[i])
268 for (j = 0; j < feature->LookupCount; j++)
269 lookup_flags[feature->LookupListIndex[j]] = j + 1;
270 feature_table[i] = use_it;
279 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
280 int count, OTF_GlyphID *ids, int direction)
282 OTF_Glyph *g = gstring->glyphs + gidx;
283 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
286 for (i = j = 0; i < count && g != gend; j++, g += direction)
287 if (! IGNORED_GLYPH (g, flag)
288 && g->glyph_id != ids[i++])
290 return (i < count ? -1 : j);
294 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
297 int i = rule->BacktrackGlyphCount;
301 || match_ids (gstring, gidx - 1, flag, i, rule->Backtrack, -1) < 0))
304 i = match_ids (gstring, gidx, flag,
305 rule->InputGlyphCount - 1, rule->Input, 1);
309 i = match_ids (gstring, gidx, flag,
310 rule->LookaheadGlyphCount, rule->LookAhead, 1);
317 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
318 int flag, int count, unsigned *classes, int direction)
320 OTF_Glyph *g = gstring->glyphs + gidx;
321 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
324 for (i = j = 0; i < count && g != gend; j++, g += direction)
325 if (! IGNORED_GLYPH (g, flag)
326 && get_class_def (class_def, g->glyph_id) != classes[i++])
328 return (i < count ? -1 : j);
332 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
333 OTF_ClassDef *BacktrackClassDef,
334 OTF_ClassDef *InputClassDef,
335 OTF_ClassDef *LookaheadClassDef,
336 OTF_ChainClassRule *rule)
338 int i = rule->BacktrackGlyphCount;
342 || match_classes (BacktrackClassDef, gstring, gidx - 1, flag, i,
343 rule->Backtrack, -1) < 0))
346 i = match_classes (InputClassDef, gstring, gidx, flag,
347 rule->InputGlyphCount - 1, rule->Input, 1);
351 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
352 rule->LookaheadGlyphCount, rule->LookAhead, 1);
360 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
361 OTF_Coverage *coverages, int direction)
363 OTF_Glyph *g = gstring->glyphs + gidx;
364 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : - 1);
367 for (i = j = 0; i < count && g != gend; j++, g += direction)
368 if (! IGNORED_GLYPH (g, flag)
369 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
371 return (i < count ? -1 : j);
375 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
376 OTF_GSUB_ChainContext3 *context3)
378 int i = context3->BacktrackGlyphCount;
382 || match_coverages (gstring, gidx - 1, flag, i,
383 context3->Backtrack, -1) < 0))
386 if (context3->InputGlyphCount > 1)
388 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
389 context3->Input + 1, 1);
394 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
395 context3->LookAhead, 1) < 0)
400 /* Apply the lookup indexed by LOOKUP_LIST_INDEX in LOOKUP_LIST to the
401 glyphs indexed by GIDX in GSTRING and the followings. If
402 successfully applied, return the index of the next glyph to apply
403 the lookup. If not applied, return GIDX. If error happened,
407 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
408 OTF_GlyphString *gstring, int gidx, int alternate_subst)
410 char *errfmt = "GSUB Looking up%s";
412 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
413 unsigned int flag = (lookup->LookupFlag
414 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
415 int orig_gidx = gidx;
416 OTF_Glyph *g = gstring->glyphs + gidx;
419 if (IGNORED_GLYPH (g, flag))
422 /* Try all subtables until one of them handles the current glyph. */
423 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
425 unsigned lookup_type = lookup->LookupType;
426 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
429 if (lookup_type == 7)
431 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
433 lookup_type = extension1->ExtensionLookupType;
434 subtable = extension1->ExtensionSubtable;
438 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
439 : (lookup_type == 3))
442 if (subtable->Coverage.offset)
444 coverage_idx = get_coverage_index (&subtable->Coverage,
446 if (coverage_idx < 0)
453 if (subtable->Format == 1)
454 g->glyph_id += subtable->u.single1.DeltaGlyphID;
456 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
461 if (subtable->Format == 1)
463 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
464 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
466 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
467 seq->Substitute, seq->GlyphCount);
468 gidx += seq->GlyphCount;
471 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
475 if (subtable->Format == 1)
477 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
478 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
480 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
481 altset->Alternate, altset->GlyphCount);
482 gidx += altset->GlyphCount;;
485 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
489 if (subtable->Format == 1)
491 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
492 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
496 for (j = 0; j < ligset->LigatureCount; j++)
500 lig = ligset->Ligature + j;
501 n = match_ids (gstring, gidx + 1, flag,
502 lig->CompCount - 1, lig->Component, 1);
505 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
512 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
516 if (subtable->Format == 1)
518 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
519 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
524 for (j = 0; j < set->RuleCount; j++)
526 rule = set->Rule + j;
527 if (match_ids (gstring, gidx + 1, flag,
528 rule->GlyphCount - 1, rule->Input, 1) < 0)
530 orig_used = gstring->used;
531 for (k = 0; k < rule->LookupCount; k++)
532 lookup_gsub (otf, lookup_list,
533 rule->LookupRecord[k].LookupListIndex,
535 gidx + rule->LookupRecord[k].SequenceIndex,
537 gidx += rule->GlyphCount + (gstring->used - orig_used);
541 else if (subtable->Format == 2)
543 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
550 class = get_class_def (&context2->ClassDef, g->glyph_id);
551 set = context2->ClassSet + class;
553 for (j = 0; j < set->ClassRuleCnt; j++)
555 rule = set->ClassRule + j;
556 if (match_classes (&context2->ClassDef,
557 gstring, gidx + 1, flag,
558 rule->GlyphCount - 1, rule->Class, 1)
561 orig_used = gstring->used;
562 for (k = 0; k < rule->LookupCount; k++)
563 lookup_gsub (otf, lookup_list,
564 rule->LookupRecord[k].LookupListIndex,
566 gidx + rule->LookupRecord[k].SequenceIndex,
568 gidx += rule->GlyphCount + (gstring->used - orig_used);
572 else /* subtable->Format == 3 */
574 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
578 if (match_coverages (gstring, gidx + 1, flag,
579 context3->GlyphCount - 1,
580 context3->Coverage + 1, 1) < 0)
582 orig_used = gstring->used;
583 for (j = 0; j < context3->LookupCount; j++)
584 lookup_gsub (otf, lookup_list,
585 context3->LookupRecord[j].LookupListIndex,
587 gidx + context3->LookupRecord[j].SequenceIndex,
589 gidx += context3->GlyphCount + (gstring->used - orig_used);
594 if (subtable->Format == 1)
596 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
597 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
601 for (j = 0; j < set->ChainRuleCount; j++)
603 OTF_ChainRule *rule = set->ChainRule + j;
605 if (gidx < rule->BacktrackGlyphCount
606 || (gidx + rule->InputGlyphCount
607 + rule->LookaheadGlyphCount) > gstring->used)
609 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
611 orig_used = gstring->used;
612 for (k = 0; k < rule->LookupCount; k++)
613 lookup_gsub (otf, lookup_list,
614 rule->LookupRecord[k].LookupListIndex,
616 gidx + rule->LookupRecord[k].SequenceIndex,
618 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
622 else if (subtable->Format == 2)
624 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
625 OTF_ChainClassSet *set;
630 class = get_class_def (&context2->InputClassDef, g->glyph_id);
631 set = context2->ChainClassSet + class;
632 for (j = 0; j < set->ChainClassRuleCnt; j++)
634 OTF_ChainClassRule *rule = set->ChainClassRule + j;
637 if (gidx < rule->BacktrackGlyphCount
638 || (gidx + rule->InputGlyphCount
639 + rule->LookaheadGlyphCount) > gstring->used)
641 if (match_chain_classes (gstring, gidx, flag,
642 &context2->BacktrackClassDef,
643 &context2->InputClassDef,
644 &context2->LookaheadClassDef,
647 orig_used = gstring->used;
648 for (k = 0; k < rule->LookupCount; k++)
649 lookup_gsub (otf, lookup_list,
650 rule->LookupRecord[k].LookupListIndex,
652 gidx + rule->LookupRecord[k].SequenceIndex,
654 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
660 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
664 if (gidx < context3->BacktrackGlyphCount
665 || (gidx + context3->InputGlyphCount
666 + context3->LookaheadGlyphCount) > gstring->used)
668 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
670 orig_used = gstring->used;
671 for (j = 0; j < context3->LookupCount; j++)
672 lookup_gsub (otf, lookup_list,
673 context3->LookupRecord[j].LookupListIndex,
675 gidx + context3->LookupRecord[j].SequenceIndex,
677 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
683 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
684 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
685 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
688 if (back_gidx > gstring->used || ahead_gidx < 0)
691 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
692 if (get_coverage_index (reverse->Backtrack + j,
693 gstring->glyphs[gidx + 1 + j].glyph_id)
696 if (j < reverse->BacktrackGlyphCount)
698 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
699 if (get_coverage_index (reverse->LookAhead + j,
700 gstring->glyphs[gidx - 1 - j].glyph_id)
703 if (j < reverse->LookaheadGlyphCount)
705 g->glyph_id = reverse->Substitute[coverage_idx];
721 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
724 int orig_gidx = gidx++;
726 while (gidx < gstring->used
727 && ! gstring->glyphs[gidx].glyph_id
728 && (gstring->glyphs[gidx].positioning_type & 0xF))
730 GSTRING_INSERT (gstring, gidx, 1);
731 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
732 gstring->glyphs[gidx].glyph_id = 0;
737 print_anchor (char *head, OTF_Anchor *anchor)
739 if (anchor->AnchorFormat == 1)
740 fprintf (stderr, " %s(X:%d Y:%d)", head,
741 anchor->XCoordinate, anchor->YCoordinate);
742 else if (anchor->AnchorFormat == 2)
743 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
744 anchor->XCoordinate, anchor->YCoordinate,
745 anchor->f.f1.AnchorPoint);
747 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
748 anchor->XCoordinate, anchor->YCoordinate);
752 print_glyph_positioning (OTF_Glyph *g, int type)
755 fprintf (stderr, " %0X=", g->glyph_id);
756 switch (g->positioning_type & 0xF)
760 int format = g->f.f1.format;
762 if (format & OTF_XPlacement)
763 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
764 if (format & OTF_XPlaDevice)
765 fprintf (stderr, "+alpha");
766 if (format & OTF_YPlacement)
767 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
768 if (format & OTF_YPlaDevice)
769 fprintf (stderr, "+alpha");
770 if (format & OTF_XAdvance)
771 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
772 if (format & OTF_XAdvDevice)
773 fprintf (stderr, "+alpha");
777 print_anchor ("entry", g->f.f3.entry_anchor);
778 print_anchor ("exit", g->f.f3.entry_anchor);
781 print_anchor ("mark", g->f.f4.mark_anchor);
782 print_anchor ("base", g->f.f4.base_anchor);
785 print_anchor ("mark", g->f.f5.mark_anchor);
786 print_anchor ("lig", g->f.f5.ligature_anchor);
789 print_anchor ("mark1", g->f.f6.mark1_anchor);
790 print_anchor ("mark2", g->f.f6.mark2_anchor);
795 /* See the comment of lookup_gsub. */
798 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
799 OTF_GlyphString *gstring, int gidx, int accumulate)
801 char *errfmt = "GPOS Looking up%s";
803 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
804 unsigned int flag = (lookup->LookupFlag
805 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
806 int orig_gidx = gidx;
807 OTF_Glyph *g = gstring->glyphs + gidx;
811 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
812 g->glyph_id, lookup_list_index);
813 if (IGNORED_GLYPH (g, flag))
816 fprintf (stderr, " glyph ignored\n");
820 /* Try all subtables until one of them handles the current glyph. */
821 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
823 unsigned lookup_type = lookup->LookupType;
824 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
826 int positioning_type;
827 enum OTF_ValueFormat format;
828 OTF_ValueRecord *value;
829 OTF_Anchor *anchor1, *anchor2;
831 if (lookup_type == 9)
833 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
835 lookup_type = extension1->ExtensionLookupType;
836 subtable = extension1->ExtensionSubtable;
840 fprintf (stderr, "/%d", lookup_type);
841 if (subtable->Coverage.offset)
843 coverage_idx = get_coverage_index (&subtable->Coverage,
845 if (coverage_idx < 0)
852 positioning_type = lookup_type;
853 if (subtable->Format == 1)
855 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
857 format = single1->ValueFormat;
858 value = &single1->Value;
860 else if (subtable->Format == 2)
862 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
864 format = single2->ValueFormat;
865 value = single2->Value + coverage_idx;
867 if (accumulate && g->positioning_type)
869 gidx = gstring_insert_for_gpos (gstring, gidx);
870 g = gstring->glyphs + gidx;
873 = (g->positioning_type & 0xFFFFFFF0) | positioning_type;
874 g->f.f1.format = format;
875 g->f.f1.value = value;
877 print_glyph_positioning (g, 0);
886 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
887 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
888 next_gidx++, nextg++);
890 if (next_gidx >= gstring->used)
892 if (subtable->Format == 1)
894 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
895 OTF_PairSet *set = pair1->PairSet + coverage_idx;
898 for (j = 0; j < set->PairValueCount; j++)
899 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
901 if (pair1->ValueFormat1)
903 if (accumulate && (g->positioning_type & 0xF))
905 gidx = gstring_insert_for_gpos (gstring, gidx);
906 g = gstring->glyphs + gidx;
907 next_gidx += gidx - orig_gidx;
908 nextg = gstring->glyphs + next_gidx;
911 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
912 g->f.f2.format = pair1->ValueFormat1;
913 g->f.f2.value = &set->PairValueRecord[j].Value1;
915 print_glyph_positioning (g, 1);
919 if (pair1->ValueFormat2)
921 if (accumulate && (g->positioning_type & 0xF))
923 gidx = gstring_insert_for_gpos (gstring, gidx);
924 g = gstring->glyphs + gidx;
927 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
928 g->f.f2.format = pair1->ValueFormat2;
929 g->f.f2.value = &set->PairValueRecord[j].Value2;
931 print_glyph_positioning (g, 2);
936 else if (subtable->Format == 2)
938 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
939 unsigned class1, class2;
941 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
942 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
943 if (pair2->ValueFormat1)
945 if (accumulate && (g->positioning_type & 0xF))
947 gidx = gstring_insert_for_gpos (gstring, gidx);
948 g = gstring->glyphs + gidx;
949 next_gidx += gidx - orig_gidx;
950 nextg = gstring->glyphs + next_gidx;
953 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
954 g->f.f2.format = pair2->ValueFormat1;
956 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
958 print_glyph_positioning (g, 1);
962 if (pair2->ValueFormat2)
964 if (accumulate && (g->positioning_type & 0xF))
966 gidx = gstring_insert_for_gpos (gstring, gidx);
967 g = gstring->glyphs + gidx;
970 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
971 g->f.f2.format = pair2->ValueFormat2;
973 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
975 print_glyph_positioning (g, 2);
983 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
986 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
988 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
990 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
992 print_glyph_positioning (g, 0);
1000 if (subtable->Format == 1)
1002 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
1003 OTF_MarkRecord *mark_record;
1004 OTF_AnchorRecord *base_record;
1006 int coverage_idx_base;
1007 unsigned int this_flag = flag | OTF_IgnoreMarks;
1010 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
1012 if (baseg < gstring->glyphs)
1015 = get_coverage_index (&mark_base1->BaseCoverage,
1017 if (coverage_idx_base < 0)
1019 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1021 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1022 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1024 = &base_record->Anchor[mark_record->Class];
1026 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
1028 print_glyph_positioning (g, 0);
1036 if (subtable->Format == 1)
1038 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1040 int coverage_idx_lig;
1041 OTF_MarkRecord *mark_record;
1042 OTF_LigatureAttach *attach;
1043 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1046 for (j = 0; j < mark_lig1->ClassCount; j++)
1050 (ligg >= gstring->glyphs
1051 && (IGNORED_GLYPH (ligg, flag)
1052 || ligg->GlyphClass > OTF_GlyphClassLigature));
1054 if ((ligg->positioning_type & 0xF) == 5
1055 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1056 num_class[ligg->MarkAttachClass]++;
1057 if (ligg < gstring->glyphs)
1060 = get_coverage_index (&mark_lig1->LigatureCoverage,
1062 if (coverage_idx_lig < 0)
1064 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1065 g->MarkAttachClass = mark_record->Class;
1066 attach = (mark_lig1->LigatureArray.LigatureAttach
1067 + coverage_idx_lig);
1068 for (j = 0; j < attach->ComponentCount; j++)
1070 OTF_Anchor *lig_anchor
1071 = attach->ComponentRecord[j].LigatureAnchor;
1073 if (lig_anchor[mark_record->Class].AnchorFormat
1074 && num_class[mark_record->Class]-- == 0)
1077 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
1078 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1079 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1081 print_glyph_positioning (g, 0);
1092 if (subtable->Format == 1)
1094 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1095 OTF_MarkRecord *mark1_record;
1096 OTF_AnchorRecord *mark2_record;
1098 int coverage_idx_base;
1101 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1103 if (prevg < gstring->glyphs)
1106 = get_coverage_index (&mark_mark1->Mark2Coverage,
1108 if (coverage_idx_base < 0)
1110 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1112 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1113 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1114 g->f.f6.mark2_anchor
1115 = &mark2_record->Anchor[mark1_record->Class];
1117 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
1119 print_glyph_positioning (g, 0);
1126 if (subtable->Format == 1)
1128 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1129 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1134 for (j = 0; j < set->RuleCount; j++)
1136 rule = set->Rule + j;
1137 if (match_ids (gstring, gidx + 1, flag,
1138 rule->GlyphCount - 1, rule->Input, 1) < 0)
1140 orig_used = gstring->used;
1141 for (k = 0; k < rule->LookupCount; k++)
1142 lookup_gpos (lookup_list,
1143 rule->LookupRecord[k].LookupListIndex,
1145 gidx + rule->LookupRecord[k].SequenceIndex,
1147 gidx += rule->GlyphCount + (gstring->used - orig_used);
1151 else if (subtable->Format == 2)
1153 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1155 OTF_ClassRule *rule;
1160 class = get_class_def (&context2->ClassDef, g->glyph_id);
1161 set = context2->ClassSet + class;
1163 for (j = 0; j < set->ClassRuleCnt; j++)
1165 rule = set->ClassRule + j;
1166 if (match_classes (&context2->ClassDef,
1167 gstring, gidx + 1, flag,
1168 rule->GlyphCount - 1, rule->Class, 1)
1171 orig_used = gstring->used;
1172 for (k = 0; k < rule->LookupCount; k++)
1173 lookup_gpos (lookup_list,
1174 rule->LookupRecord[k].LookupListIndex,
1176 gidx + rule->LookupRecord[k].SequenceIndex,
1178 gidx += rule->GlyphCount + (gstring->used - orig_used);
1182 else /* subtable->Format == 3 */
1184 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1188 if (match_coverages (gstring, gidx + 1, flag,
1189 context3->GlyphCount - 1,
1190 context3->Coverage + 1, 1) < 0)
1192 orig_used = gstring->used;
1193 for (j = 0; j < context3->LookupCount; j++)
1194 lookup_gpos (lookup_list,
1195 context3->LookupRecord[j].LookupListIndex,
1197 gidx + context3->LookupRecord[j].SequenceIndex,
1199 gidx += context3->GlyphCount + (gstring->used - orig_used);
1204 if (subtable->Format == 1)
1206 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1207 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1211 for (j = 0; j < set->ChainRuleCount; j++)
1213 OTF_ChainRule *rule = set->ChainRule + j;
1215 if (gidx < rule->BacktrackGlyphCount
1216 || (gidx + rule->InputGlyphCount
1217 + rule->LookaheadGlyphCount) > gstring->used)
1219 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1221 orig_used = gstring->used;
1222 for (k = 0; k < rule->LookupCount; k++)
1223 lookup_gpos (lookup_list,
1224 rule->LookupRecord[k].LookupListIndex,
1226 gidx + rule->LookupRecord[k].SequenceIndex,
1228 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1232 else if (subtable->Format == 2)
1234 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1235 OTF_ChainClassSet *set;
1240 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1241 set = context2->ChainClassSet + class;
1242 for (j = 0; j < set->ChainClassRuleCnt; j++)
1244 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1247 if (gidx < rule->BacktrackGlyphCount
1248 || (gidx + rule->InputGlyphCount
1249 + rule->LookaheadGlyphCount) > gstring->used)
1251 if (match_chain_classes (gstring, gidx, flag,
1252 &context2->BacktrackClassDef,
1253 &context2->InputClassDef,
1254 &context2->LookaheadClassDef,
1257 orig_used = gstring->used;
1258 for (k = 0; k < rule->LookupCount; k++)
1259 lookup_gpos (lookup_list,
1260 rule->LookupRecord[k].LookupListIndex,
1262 gidx + rule->LookupRecord[k].SequenceIndex,
1264 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1268 else if (subtable->Format == 3)
1270 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1274 if (gidx < context3->BacktrackGlyphCount
1275 || (gidx + context3->InputGlyphCount
1276 + context3->LookaheadGlyphCount) > gstring->used)
1278 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1280 orig_used = gstring->used;
1281 for (j = 0; j < context3->LookupCount; j++)
1282 lookup_gpos (lookup_list,
1283 context3->LookupRecord[j].LookupListIndex,
1285 gidx + context3->LookupRecord[j].SequenceIndex,
1287 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1290 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1299 if (gidx == orig_gidx)
1300 fprintf (stderr, " no match\n");
1302 fprintf (stderr, "\n");
1308 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1310 return ((c < 0 || c >= 256)
1312 : sub->f.f0->glyphIdArray[c]);
1316 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1322 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1325 OTF_EncodingSubtable4 *sub4;
1330 segCount = sub4->segCountX2 / 2;
1331 for (i = 0; i < segCount; i++)
1333 OTF_cmapSegment *seg = sub4->segments + i;
1335 if (c >= seg->startCount && c <= seg->endCount)
1337 if (seg->idRangeOffset == 0xFFFF)
1338 return c + seg->idDelta;
1340 return sub4->glyphIdArray[seg->idRangeOffset
1341 + (c - seg->startCount)];
1348 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1354 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1360 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1366 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1368 OTF_EncodingSubtable12 *sub12;
1369 OTF_cmapGroup *g, *gend;
1375 gend = sub12->Groups + sub12->nGroups;
1378 if (g->startCharCode <= c && c <= g->endCharCode)
1379 return (g->startGlyphID + (c - g->startCharCode));
1385 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1387 static lookup_cmap_func lookup_cmap_func_table[] =
1389 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1390 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1394 get_GlyphID (OTF_cmap *cmap, int c)
1396 OTF_EncodingSubtable *sub;
1397 lookup_cmap_func lookupper;
1399 if (c < 0x10000 && cmap->unicode_table)
1400 return cmap->unicode_table[c];
1401 if (cmap->table_index < 0)
1403 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1404 lookupper = lookup_cmap_func_table[sub->format / 2];
1405 return lookupper (c, sub);
1409 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1411 unsigned nRecords = sub14->nRecords;
1412 OTF_VariationSelectorRecord *record;
1415 for (i = 0; i < nRecords; i++)
1417 record = &sub14->Records[i];
1418 if (record->varSelector == c2)
1420 if (record->defaultUVSOffset)
1422 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1423 unsigned numUVRs = record->numUnicodeValueRanges;
1424 unsigned top = numUVRs, bottom = 0, middle;
1426 if (uVRs[0].startUnicodeValue <= c1)
1428 unsigned additionalCount, startUnicodeValue;
1432 middle = (top + bottom) / 2;
1433 if (c1 < uVRs[middle].startUnicodeValue)
1435 else if (bottom == middle)
1440 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1441 additionalCount = uVRs[bottom].additionalCount;
1442 if (c1 <= startUnicodeValue + additionalCount)
1443 return get_GlyphID (cmap, c1);
1446 if (record->nonDefaultUVSOffset)
1448 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1449 unsigned numUVSMs = record->numUVSMappings;
1450 unsigned top = numUVSMs, bottom = 0, middle;
1452 if (uvsMappings[0].unicodeValue <= c1)
1456 middle = (top + bottom) / 2;
1457 if (c1 < uvsMappings[middle].unicodeValue)
1459 else if (bottom == middle)
1464 if (uvsMappings[bottom].unicodeValue == c1)
1465 return uvsMappings[bottom].glyphID;
1475 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1477 OTF_EncodingSubtable14 *sub14;
1478 int c1 = gstring->glyphs[idx - 1].c;
1479 int c2 = gstring->glyphs[idx].c;
1483 gstring->glyphs[idx].glyph_id = 0;
1484 for (i = 0; i < cmap->numTables; i++)
1485 if (cmap->EncodingRecord[i].subtable.format == 14)
1487 if (i == cmap->numTables)
1489 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1492 gstring->glyphs[idx - 1].glyph_id = code;
1493 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1495 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1496 sizeof (OTF_Glyph) * (gstring->used - idx));
1502 /* Table of GlyphClass and MarkAttackClass.
1504 For the Nth element CHAR, CHAR and the succeeding characters
1505 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1507 This table is generated from the General Category (GC) property of
1508 characters defined in the Unicode Character Database. */
1510 static int glyph_class_table[] =
1511 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1512 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1513 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1514 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1515 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1516 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1517 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1518 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1519 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1520 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1521 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1522 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1523 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1524 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1525 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1526 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1527 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1528 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1529 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1530 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1531 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1532 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1533 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1534 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1535 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1536 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1537 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1538 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1539 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1541 static int get_class_def_auto (int c)
1543 static int table_size
1544 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1547 if (c >= glyph_class_table[table_size - 1])
1550 high = table_size - 1;
1553 mid = (low + high) / 2;
1554 if (c < glyph_class_table[mid])
1556 else if (c >= glyph_class_table[mid + 1])
1561 return ((mid % 2) ? 3 : 1);
1569 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1572 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1576 OTF_EncodingSubtable *sub;
1577 lookup_cmap_func lookupper;
1580 && OTF_get_table (otf, "cmap") < 0)
1584 if (cmap->table_index < 0)
1588 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1589 lookupper = lookup_cmap_func_table[sub->format / 2];
1591 for (i = 0; i < gstring->used; i++)
1592 if (! gstring->glyphs[i].glyph_id)
1594 int c = gstring->glyphs[i].c;
1595 if (c < 32 || ! cmap->unicode_table)
1596 gstring->glyphs[i].glyph_id = 0;
1597 else if (UVS_P (c) && i > 0)
1598 check_cmap_uvs (cmap, gstring, i);
1599 else if (c < 0x10000)
1600 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1602 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1609 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1610 int platform_id, int encoding_id)
1614 char *errfmt = "CMAP Looking up%s";
1616 OTF_EncodingRecord *enc;
1617 lookup_cmap_func lookupper;
1620 && OTF_get_table (otf, "cmap") < 0)
1624 for (i = 0; i < cmap->numTables; i++)
1625 if (cmap->EncodingRecord[i].platformID == platform_id
1626 && cmap->EncodingRecord[i].encodingID == encoding_id)
1628 if (i == cmap->numTables)
1629 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1630 enc = cmap->EncodingRecord + i;
1631 if (enc->subtable.format > 12)
1632 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1633 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1635 for (i = 0; i < gstring->used; i++)
1636 if (! gstring->glyphs[i].glyph_id)
1638 int c = gstring->glyphs[i].c;
1639 if (c < 32 || ! cmap->unicode_table)
1640 gstring->glyphs[i].glyph_id = 0;
1641 else if (UVS_P (c) && i > 0)
1642 check_cmap_uvs (cmap, gstring, i);
1643 else if (c < 0x10000)
1644 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1646 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1652 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1655 && OTF_get_table (otf, "cmap") < 0)
1658 || code > otf->cmap->max_glyph_id
1659 || ! otf->cmap->decode_table)
1661 return otf->cmap->decode_table[code];
1665 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1669 OTF_EncodingSubtable14 *sub14;
1671 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1673 && OTF_get_table (otf, "cmap") < 0)
1676 for (i = 0; i < cmap->numTables; i++)
1677 if (cmap->EncodingRecord[i].subtable.format == 14)
1679 if (i == cmap->numTables)
1681 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1682 for (i = 0, n = 0; i < 256; i++)
1684 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1686 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1694 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1700 && OTF_get_table (otf, "GDEF") < 0)
1704 if (gdef->glyph_class_def.offset)
1705 for (i = 0; i < gstring->used; i++)
1706 gstring->glyphs[i].GlyphClass
1707 = get_class_def (&gdef->glyph_class_def,
1708 gstring->glyphs[i].glyph_id);
1710 for (i = 0; i < gstring->used; i++)
1711 gstring->glyphs[i].GlyphClass
1712 = get_class_def_auto (gstring->glyphs[i].c);
1714 if (gdef->mark_attach_class_def.offset)
1715 for (i = 0; i < gstring->used; i++)
1716 gstring->glyphs[i].MarkAttachClass
1717 = get_class_def (&gdef->mark_attach_class_def,
1718 gstring->glyphs[i].glyph_id);
1724 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1725 const char *script, const char *language,
1726 const char *features,
1727 int alternate_subst, int with_log)
1729 char *errfmt = "GSUB driving%s";
1732 OTF_LangSys *LangSys;
1733 USHORT *lookup_flags;
1737 for (i = 0; i < gstring->used; i++)
1739 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1740 gstring->glyphs[i].positioning_type = 0;
1743 if (OTF_get_table (otf, "GSUB") < 0)
1746 if (gsub->FeatureList.FeatureCount == 0
1747 || gsub->LookupList.LookupCount == 0)
1750 LangSys = get_langsys (&gsub->ScriptList, script, language);
1754 lookup_flags = alloca (sizeof (USHORT) * gsub->LookupList.LookupCount);
1756 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1757 features, lookup_flags) < 0)
1758 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1760 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1765 if (! lookup_flags[i]) continue;
1767 if (gsub->LookupList.Lookup[i].LookupType != 8)
1770 while (gidx < gstring->used)
1772 int result = lookup_gsub (otf, &gsub->LookupList, i, gstring,
1773 gidx, alternate_subst);
1779 for (j = gidx; j < result; j++)
1780 gstring->glyphs[j].positioning_type
1781 = ((gstring->glyphs[j].positioning_type & 0xF)
1782 | (lookup_flags[i] << 4));
1791 gidx = gstring->used - 1;
1794 int result = lookup_gsub (otf, &gsub->LookupList, i, gstring,
1795 gidx, alternate_subst);
1801 for (j = gidx; j > result; j--)
1802 gstring->glyphs[j].positioning_type
1803 = ((gstring->glyphs[j].positioning_type & 0xF)
1804 | (lookup_flags[i] << 4));
1817 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1818 const char *script, const char *language, const char *features)
1821 OTF_get_table (otf, "cmap");
1822 return OTF_drive_gsub_internal (otf, gstring, script, language, features,
1827 OTF_drive_gsub_with_log (OTF *otf, OTF_GlyphString *gstring,
1828 const char *script, const char *language,
1829 const char *features)
1832 OTF_get_table (otf, "cmap");
1833 return OTF_drive_gsub_internal (otf, gstring, script, language, features,
1838 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1839 const char *script, const char *language,
1840 const char *features,
1841 int accumulate, int with_log)
1843 char *errfmt = "GPOS driving%s";
1846 OTF_LangSys *LangSys;
1847 USHORT *lookup_flags;
1850 for (i = 0; i < gstring->used; i++)
1851 gstring->glyphs[i].positioning_type = 0;
1853 if (OTF_get_table (otf, "GPOS") < 0)
1856 if (gpos->FeatureList.FeatureCount == 0
1857 || gpos->LookupList.LookupCount == 0)
1860 LangSys = get_langsys (&gpos->ScriptList, script, language);
1864 lookup_flags = alloca (sizeof (USHORT) * gpos->LookupList.LookupCount);
1866 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1867 features, lookup_flags) < 0)
1868 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1870 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1875 if (! lookup_flags[i]) continue;
1877 while (gidx < gstring->used)
1879 int result = lookup_gpos (&gpos->LookupList, i, gstring, gidx,
1886 for (j = gidx; j < result; j++)
1887 gstring->glyphs[j].positioning_type
1888 = ((gstring->glyphs[j].positioning_type & 0xF)
1889 | (lookup_flags[i] << 4));
1901 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1902 const char *script, const char *language, const char *features)
1905 OTF_get_table (otf, "cmap");
1906 return OTF_drive_gpos_internal (otf, gstring, script, language, features,
1911 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1912 const char *script, const char *language, const char *features)
1915 OTF_get_table (otf, "cmap");
1916 return OTF_drive_gpos_internal (otf, gstring, script, language, features,
1921 OTF_drive_gpos_with_log (OTF *otf, OTF_GlyphString *gstring,
1922 const char *script, const char *language,
1923 const char *features)
1926 OTF_get_table (otf, "cmap");
1927 return OTF_drive_gpos_internal (otf, gstring, script, language, features,
1932 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1933 const char *script, const char *language,
1934 const char *gsub_features, const char *gpos_features)
1936 if (OTF_drive_cmap (otf, gstring) < 0)
1938 if (OTF_drive_gdef (otf, gstring) < 0)
1941 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1944 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1950 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1951 const char *script, const char *language,
1952 const char *features)
1954 return OTF_drive_gsub_internal (otf, gstring, script, language, features,
1959 iterate_coverage (OTF *otf, const char *feature,
1960 OTF_Feature_Callback callback,
1961 OTF_Coverage *coverage)
1965 if (coverage->CoverageFormat == 1)
1967 for (i = 0; i < coverage->Count; i++)
1968 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1973 for (i = 0; i < coverage->Count; i++)
1975 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1977 for (id = range->Start; id <= range->End; id++)
1978 if (callback (otf, feature, id) < 0)
1986 iterate_feature (OTF *otf, const char *feature,
1987 OTF_Feature_Callback callback,
1992 for (i = 0; i < lookup->SubTableCount; i++)
1994 unsigned lookup_type = lookup->LookupType;
1995 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1997 if (lookup_type == 7)
1999 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
2001 lookup_type = extension1->ExtensionLookupType;
2002 subtable = extension1->ExtensionSubtable;
2005 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
2007 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
2011 else if (lookup_type == 4)
2013 OTF_GSUB_Ligature1 *lig1;
2015 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
2018 lig1 = &subtable->u.ligature1;
2019 for (j = 0; j < lig1->LigSetCount; j++)
2021 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
2023 for (k = 0; k < ligset->LigatureCount; k++)
2025 OTF_Ligature *lig = ligset->Ligature + k;
2026 for (l = 0; l < lig->CompCount - 1; l++)
2027 if (callback (otf, feature, lig->Component[l]) < 0)
2032 else if (lookup_type == 6)
2034 if (subtable->Format == 1)
2036 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
2037 for (j = 0; j < context1->ChainRuleSetCount; j++)
2039 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
2040 for (k = 0; k < set->ChainRuleCount; k++)
2042 OTF_ChainRule *rule = set->ChainRule + k;
2043 for (l = 0; l < rule->LookupCount; l++)
2046 = (otf->gsub->LookupList.Lookup
2047 + rule->LookupRecord[l].LookupListIndex);
2048 if (iterate_feature (otf, feature, callback, lkup)
2055 else if (subtable->Format == 2)
2057 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
2059 for (j = 0; j < context2->ChainClassSetCnt; j++)
2061 OTF_ChainClassSet *set = context2->ChainClassSet + j;
2062 for (k = 0; k < set->ChainClassRuleCnt; j++)
2064 OTF_ChainClassRule *rule = set->ChainClassRule + k;
2066 for (l = 0; l < rule->LookupCount; l++)
2069 = (otf->gsub->LookupList.Lookup
2070 + rule->LookupRecord[k].LookupListIndex);
2071 if (iterate_feature (otf, feature, callback, lkup)
2080 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
2081 for (j = 0; j < context3->LookupCount; j++)
2084 = (otf->gsub->LookupList.Lookup
2085 + context3->LookupRecord[j].LookupListIndex);
2086 if (iterate_feature (otf, feature, callback, lkup) < 0)
2096 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2097 const char *script, const char *language,
2098 const char *feature)
2100 char *errfmt = "GSUB iterate feature%s";
2105 OTF_LangSys *langsys;
2106 USHORT *lookup_flags;
2108 if (OTF_get_table (otf, "GSUB") < 0)
2111 if (gsub->FeatureList.FeatureCount == 0
2112 || gsub->LookupList.LookupCount == 0)
2114 langsys = get_langsys (&gsub->ScriptList, script, language);
2117 lookup_flags = alloca (sizeof (USHORT) * gsub->LookupList.LookupCount);
2119 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2120 feature, lookup_flags) < 0)
2121 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2123 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2124 if (lookup_flags[i])
2125 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)