1 /* otfdrive.c -- OpenType font driver.
3 Copyright (C) 2003, 2004
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;
34 /* Return nonzero (-1 if ID is zero, 1 otherwise) if OTF_Glyph *G
35 should be ignored according to LookupFlag FLAG. */
36 #define IGNORED_GLYPH(g, flag) \
37 ((g)->glyph_id == 0 ? -1 \
38 : (((flag) & (1 << (g)->GlyphClass)) \
39 || (((flag) & OTF_MarkAttachmentType) \
40 && (g)->GlyphClass == OTF_GlyphClassMark \
41 && ((flag) >> 8) != (g)->MarkAttachClass)))
43 #define GSTRING_DELETE(gstring, from, len) \
45 memmove (gstring->glyphs + from, gstring->glyphs + from + len, \
46 sizeof (OTF_Glyph) * (gstring->used - from - len)); \
47 gstring->used -= len; \
51 #define GSTRING_INSERT(gstring, pos, len) \
53 if (gstring->used + len > gstring->size) \
55 char *errfmt = "GSTRING%s"; \
57 gstring->size = gstring->used + len; \
59 = (OTF_Glyph *) realloc (gstring->glyphs, \
60 sizeof (OTF_Glyph) * gstring->size); \
61 if (! gstring->glyphs) \
62 OTF_ERROR (OTF_ERROR_MEMORY, ""); \
64 memmove (gstring->glyphs + pos + len, gstring->glyphs + pos, \
65 sizeof (OTF_Glyph) * (gstring->used - pos)); \
66 gstring->used += len; \
70 static unsigned get_class_def (OTF_ClassDef *, OTF_GlyphID);
73 gstring_subst (OTF *otf, OTF_GlyphString *gstring, int from, int to, int flag,
74 OTF_GlyphID *ids, int num)
79 int from_idx = gstring->glyphs[from].f.index.from;
80 int to_idx = gstring->glyphs[to - 1].f.index.to;
83 for (i = non_ignored_idx = to - 1; i >= from; i--)
85 OTF_Glyph *g = gstring->glyphs + i;
87 if (IGNORED_GLYPH (g, flag) == 1)
89 /* Move this glyph to the next of the current target of
93 memmove (g, g + 1, sizeof (OTF_Glyph) * (non_ignored_idx - i));
94 temp.f.index.from = from_idx;
95 temp.f.index.to = to_idx;
96 gstring->glyphs[non_ignored_idx--] = temp;
102 GSTRING_INSERT (gstring, from, (num - len));
104 GSTRING_DELETE (gstring, from, (len - num));
105 for (i = 0; i < num; i++)
107 if (gstring->glyphs[from + i].glyph_id != ids[i])
109 gstring->glyphs[from + i].c = 0;
111 gstring->glyphs[from + i].GlyphClass
112 = get_class_def (&otf->gdef->glyph_class_def, ids[i]);
114 gstring->glyphs[from + i].GlyphClass = 0;
116 gstring->glyphs[from + i].glyph_id = ids[i];
117 gstring->glyphs[from + i].positioning_type = 0;
118 gstring->glyphs[from + i].f.index.from = from_idx;
119 gstring->glyphs[from + i].f.index.to = to_idx;
126 get_coverage_index (OTF_Coverage *coverage, OTF_GlyphID id)
130 if (coverage->CoverageFormat == 1)
132 for (i = 0; i < coverage->Count; i++)
133 if (coverage->table.GlyphArray[i] == id)
138 for (i = 0; i < coverage->Count; i++)
139 if (coverage->table.RangeRecord[i].Start <= id
140 && coverage->table.RangeRecord[i].End >= id)
141 return (coverage->table.RangeRecord[i].StartCoverageIndex
142 + (id - coverage->table.RangeRecord[i].Start));
148 get_class_def (OTF_ClassDef *class_def, OTF_GlyphID glyph_id)
150 if (class_def->ClassFormat == 1)
152 int idx = (int) glyph_id - (int) class_def->f.f1.StartGlyph;
154 if (idx >= 0 && idx < class_def->f.f1.GlyphCount)
155 return class_def->f.f1.ClassValueArray[idx];
161 for (i = 0; i < class_def->f.f2.ClassRangeCount; i++)
162 if (glyph_id >= class_def->f.f2.ClassRangeRecord[i].Start
163 && glyph_id <= class_def->f.f2.ClassRangeRecord[i].End)
164 return class_def->f.f2.ClassRangeRecord[i].Class;
170 get_langsys (OTF_ScriptList *script_list,
171 const char *script, const char *language)
174 OTF_Tag script_tag = OTF_tag (script);
175 OTF_Tag langsys_tag = OTF_tag (language);
177 OTF_Tag dflt_tag = OTF_tag ("DFLT");
178 OTF_Script *dflt = NULL;
180 for (i = 0; i < script_list->ScriptCount; i++)
182 OTF_Script *script = script_list->Script + i;
184 if (script_list->Script[i].ScriptTag == dflt_tag)
186 if (script_list->Script[i].ScriptTag == script_tag)
189 return &script->DefaultLangSys;
190 for (j = 0; j < script->LangSysCount; j++)
191 if (script->LangSysRecord[j].LangSysTag == langsys_tag)
192 return script->LangSys + j;
193 return &script->DefaultLangSys;
198 dflt = script_list->Script;
200 return &dflt->DefaultLangSys;
201 for (j = 0; j < dflt->LangSysCount; j++)
202 if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
203 return dflt->LangSys + j;
204 return &dflt->DefaultLangSys;
208 setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
209 OTF_LangSys *LangSys,
210 const char *features, char *lookup_flags)
213 OTF_Feature *feature;
214 int *feature_table = alloca (sizeof (int) * FeatureList->FeatureCount);
218 for (i = 0; i < FeatureList->FeatureCount; i++)
219 feature_table[i] = 0;
220 memset (lookup_flags, 0, LookupList->LookupCount);
228 if (*features == '*')
230 /* Consume all remaining features. */
231 for (i = 0; i < LangSys->FeatureCount; i++)
233 int index = LangSys->FeatureIndex[i];
235 if (! feature_table[index])
237 feature = FeatureList->Feature + index;
238 for (j = 0; j < feature->LookupCount; j++)
239 lookup_flags[feature->LookupListIndex[j]] = 1;
245 if (*features == '~')
246 use_it = -1, features++;
247 for (i = 0; *features && *features != ','; i++, features++)
248 tagname[i] = *features;
254 tag = OTF_tag (tagname);
255 for (i = 0; i < LangSys->FeatureCount; i++)
257 feature = FeatureList->Feature + LangSys->FeatureIndex[i];
258 if (tag == feature->FeatureTag)
260 if (feature_table[i])
263 for (j = 0; j < feature->LookupCount; j++)
264 lookup_flags[feature->LookupListIndex[j]] = 1;
265 feature_table[i] = use_it;
274 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
275 int count, OTF_GlyphID *ids)
277 OTF_Glyph *gbeg = gstring->glyphs + gidx;
278 OTF_Glyph *gend = gstring->glyphs + gstring->used;
282 for (g = gbeg, i = 0; g < gend && i < count; g++)
283 if (! IGNORED_GLYPH (g, flag) && g->glyph_id != ids[i++])
285 return (i < count ? -1 : g - gbeg);
289 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
292 int i = rule->BacktrackGlyphCount;
299 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
300 if (! IGNORED_GLYPH (g, flag) && --i == 0)
304 if (match_ids (gstring, j, flag,
305 rule->BacktrackGlyphCount, rule->Backtrack)
310 i = match_ids (gstring, gidx, flag,
311 rule->InputGlyphCount - 1, rule->Input);
315 i = match_ids (gstring, gidx, flag,
316 rule->LookaheadGlyphCount, rule->LookAhead);
323 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
324 int flag, int count, unsigned *classes)
326 OTF_Glyph *gbeg = gstring->glyphs + gidx;
327 OTF_Glyph *gend = gstring->glyphs + gstring->used;
331 for (g = gbeg, i = 0; g < gend && i < count; g++)
332 if (! IGNORED_GLYPH (g, flag)
333 && get_class_def (class_def, g->glyph_id) != classes[i++])
335 return (i < count ? -1 : g - gbeg);
339 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
340 OTF_ClassDef *BacktrackClassDef,
341 OTF_ClassDef *InputClassDef,
342 OTF_ClassDef *LookaheadClassDef,
343 OTF_ChainClassRule *rule)
345 int i = rule->BacktrackGlyphCount;
352 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
353 if (! IGNORED_GLYPH (g, flag) && i-- == 0)
357 if (match_classes (BacktrackClassDef, gstring, j, flag,
358 rule->BacktrackGlyphCount, rule->Backtrack) < 0);
362 i = match_classes (InputClassDef, gstring, gidx, flag,
363 rule->InputGlyphCount - 1, rule->Input);
367 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
368 rule->LookaheadGlyphCount, rule->LookAhead);
376 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
377 OTF_Coverage *coverages)
379 OTF_Glyph *gbeg = gstring->glyphs + gidx;
380 OTF_Glyph *gend = gstring->glyphs + gstring->used;
384 for (g = gbeg, i = 0; g < gend && i < count; g++)
385 if (! IGNORED_GLYPH (g, flag)
386 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
388 return (i < count ? -1 : g - gbeg);
392 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
393 OTF_GSUB_ChainContext3 *context3)
395 int i = context3->BacktrackGlyphCount;
402 for (j = gidx - 1, g= gstring->glyphs +j; j >= 0; j--, g--)
403 if (! IGNORED_GLYPH (g, flag) && --i == 0)
407 if (match_coverages (gstring, j, flag, context3->BacktrackGlyphCount,
408 context3->Backtrack) < 0)
412 if (context3->InputGlyphCount > 1)
414 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
415 context3->Input + 1);
420 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
421 context3->LookAhead) < 0)
427 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
428 OTF_GlyphString *gstring, int gidx, int alternate_subst)
430 char *errfmt = "GSUB Looking up%s";
432 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
433 unsigned int flag = (lookup->LookupFlag
434 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
435 int orig_gidx = gidx;
436 OTF_Glyph *g = gstring->glyphs + gidx;
439 if (IGNORED_GLYPH (g, flag))
442 /* Try all subtables until one of them handles the current glyph. */
443 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
445 unsigned lookup_type = lookup->LookupType;
446 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
449 if (lookup_type == 7)
451 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
453 lookup_type = extension1->ExtensionLookupType;
454 subtable = extension1->ExtensionSubtable;
458 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
459 : (lookup_type == 3))
462 if (subtable->Coverage.offset)
464 coverage_idx = get_coverage_index (&subtable->Coverage,
466 if (coverage_idx < 0)
473 if (subtable->Format == 1)
474 g->glyph_id += subtable->u.single1.DeltaGlyphID;
476 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
481 if (subtable->Format == 1)
483 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
484 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
486 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
487 seq->Substitute, seq->GlyphCount);
488 gidx += seq->GlyphCount;
491 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
495 if (subtable->Format == 1)
497 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
498 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
500 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
501 altset->Alternate, altset->GlyphCount);
502 gidx += altset->GlyphCount;;
505 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
509 if (subtable->Format == 1)
511 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
512 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
516 for (j = 0; j < ligset->LigatureCount; j++)
520 lig = ligset->Ligature + j;
521 n = match_ids (gstring, gidx + 1, flag,
522 lig->CompCount - 1, lig->Component);
525 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
532 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
536 if (subtable->Format == 1)
538 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
539 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
544 for (j = 0; j < set->RuleCount; j++)
546 rule = set->Rule + j;
547 if (match_ids (gstring, gidx + 1, flag,
548 rule->GlyphCount - 1, rule->Input) < 0)
550 orig_used = gstring->used;
551 for (k = 0; k < rule->LookupCount; k++)
552 lookup_gsub (otf, lookup_list,
553 rule->LookupRecord[k].LookupListIndex,
555 gidx + rule->LookupRecord[k].SequenceIndex,
557 gidx += rule->GlyphCount + (gstring->used - orig_used);
561 else if (subtable->Format == 2)
563 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
570 class = get_class_def (&context2->ClassDef, g->glyph_id);
571 set = context2->ClassSet + class;
573 for (j = 0; j < set->ClassRuleCnt; j++)
575 rule = set->ClassRule + j;
576 if (match_classes (&context2->ClassDef,
577 gstring, gidx + 1, flag,
578 rule->GlyphCount - 1, rule->Class)
581 orig_used = gstring->used;
582 for (k = 0; k < rule->LookupCount; k++)
583 lookup_gsub (otf, lookup_list,
584 rule->LookupRecord[k].LookupListIndex,
586 gidx + rule->LookupRecord[k].SequenceIndex,
588 gidx += rule->GlyphCount + (gstring->used - orig_used);
592 else /* subtable->Format == 3 */
594 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
598 if (match_coverages (gstring, gidx + 1, flag,
599 context3->GlyphCount - 1,
600 context3->Coverage + 1) < 0)
602 orig_used = gstring->used;
603 for (j = 0; j < context3->LookupCount; j++)
604 lookup_gsub (otf, lookup_list,
605 context3->LookupRecord[j].LookupListIndex,
607 gidx + context3->LookupRecord[j].SequenceIndex,
609 gidx += context3->GlyphCount + (gstring->used - orig_used);
614 if (subtable->Format == 1)
616 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
617 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
621 for (j = 0; j < set->ChainRuleCount; j++)
623 OTF_ChainRule *rule = set->ChainRule + j;
625 if (gidx < rule->BacktrackGlyphCount
626 || (gidx + rule->InputGlyphCount
627 + rule->LookaheadGlyphCount) > gstring->used)
629 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
631 orig_used = gstring->used;
632 for (k = 0; k < rule->LookupCount; k++)
633 lookup_gsub (otf, lookup_list,
634 rule->LookupRecord[k].LookupListIndex,
636 gidx + rule->LookupRecord[k].SequenceIndex,
638 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
642 else if (subtable->Format == 2)
644 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
645 OTF_ChainClassSet *set;
650 class = get_class_def (&context2->InputClassDef, g->glyph_id);
651 set = context2->ChainClassSet + class;
652 for (j = 0; j < set->ChainClassRuleCnt; j++)
654 OTF_ChainClassRule *rule = set->ChainClassRule + j;
657 if (gidx < rule->BacktrackGlyphCount
658 || (gidx + rule->InputGlyphCount
659 + rule->LookaheadGlyphCount) > gstring->used)
661 if (match_chain_classes (gstring, gidx, flag,
662 &context2->BacktrackClassDef,
663 &context2->InputClassDef,
664 &context2->LookaheadClassDef,
667 orig_used = gstring->used;
668 for (k = 0; k < rule->LookupCount; k++)
669 lookup_gsub (otf, lookup_list,
670 rule->LookupRecord[k].LookupListIndex,
672 gidx + rule->LookupRecord[k].SequenceIndex,
674 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
680 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
684 if (gidx < context3->BacktrackGlyphCount
685 || (gidx + context3->InputGlyphCount
686 + context3->LookaheadGlyphCount) > gstring->used)
688 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
690 orig_used = gstring->used;
691 for (j = 0; j < context3->LookupCount; j++)
692 lookup_gsub (otf, lookup_list,
693 context3->LookupRecord[j].LookupListIndex,
695 gidx + context3->LookupRecord[j].SequenceIndex,
697 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
703 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
704 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
705 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
708 if (back_gidx > gstring->used || ahead_gidx < 0)
711 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
712 if (get_coverage_index (reverse->Backtrack + j,
713 gstring->glyphs[gidx + 1 + j].glyph_id)
716 if (j < reverse->BacktrackGlyphCount)
718 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
719 if (get_coverage_index (reverse->LookAhead + j,
720 gstring->glyphs[gidx - 1 - j].glyph_id)
723 if (j < reverse->LookaheadGlyphCount)
725 g->glyph_id = reverse->Substitute[coverage_idx];
733 if (gidx == orig_gidx)
742 get_anchor (OTF_Anchor *anchor, OTF_ValueRecord *rec)
744 unsigned value_format = OTF_XPlacement | OTF_YPlacement;
746 rec->XPlacement = anchor->XCoordinate;
747 rec->YPlacement = anchor->YCoordinate;
748 if (anchor->AnchorFormat == 1)
751 else if (anchor->AnchorFormat == 2)
752 /* Not yet implemented */
754 else if (anchor->AnchorFormat == 3)
755 /* Not yet implemented */
761 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
764 int orig_gidx = gidx++;
766 while (gidx < gstring->used
767 && ! gstring->glyphs[gidx].glyph_id
768 && gstring->glyphs[gidx].positioning_type)
770 GSTRING_INSERT (gstring, gidx, 1);
771 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
772 gstring->glyphs[gidx].glyph_id = 0;
777 print_anchor (char *head, OTF_Anchor *anchor)
779 if (anchor->AnchorFormat == 1)
780 fprintf (stderr, " %s(X:%d Y:%d)", head,
781 anchor->XCoordinate, anchor->YCoordinate);
782 else if (anchor->AnchorFormat == 2)
783 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
784 anchor->XCoordinate, anchor->YCoordinate,
785 anchor->f.f1.AnchorPoint);
787 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
788 anchor->XCoordinate, anchor->YCoordinate);
792 print_glyph_positioning (OTF_Glyph *g, int type)
795 fprintf (stderr, " %0X=", g->glyph_id);
796 switch (g->positioning_type)
800 int format = g->f.f1.format;
802 if (format & OTF_XPlacement)
803 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
804 if (format & OTF_XPlaDevice)
805 fprintf (stderr, "+alpha");
806 if (format & OTF_YPlacement)
807 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
808 if (format & OTF_YPlaDevice)
809 fprintf (stderr, "+alpha");
810 if (format & OTF_XAdvance)
811 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
812 if (format & OTF_XAdvDevice)
813 fprintf (stderr, "+alpha");
817 print_anchor ("entry", g->f.f3.entry_anchor);
818 print_anchor ("exit", g->f.f3.entry_anchor);
821 print_anchor ("mark", g->f.f4.mark_anchor);
822 print_anchor ("base", g->f.f4.base_anchor);
825 print_anchor ("mark", g->f.f5.mark_anchor);
826 print_anchor ("lig", g->f.f5.ligature_anchor);
829 print_anchor ("mark1", g->f.f6.mark1_anchor);
830 print_anchor ("mark2", g->f.f6.mark2_anchor);
836 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
837 OTF_GlyphString *gstring, int gidx, int accumulate)
839 char *errfmt = "GPOS Looking up%s";
841 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
842 unsigned int flag = (lookup->LookupFlag
843 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
844 int orig_gidx = gidx;
845 OTF_Glyph *g = gstring->glyphs + gidx;
849 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
850 g->glyph_id, lookup_list_index);
851 if (IGNORED_GLYPH (g, flag))
854 fprintf (stderr, " glyph ignored\n");
858 /* Try all subtables until one of them handles the current glyph. */
859 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
861 unsigned lookup_type = lookup->LookupType;
862 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
864 int positioning_type;
865 enum OTF_ValueFormat format;
866 OTF_ValueRecord *value;
867 OTF_Anchor *anchor1, *anchor2;
869 if (lookup_type == 9)
871 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
873 lookup_type = extension1->ExtensionLookupType;
874 subtable = extension1->ExtensionSubtable;
878 fprintf (stderr, "/%d", lookup_type);
879 if (subtable->Coverage.offset)
881 coverage_idx = get_coverage_index (&subtable->Coverage,
883 if (coverage_idx < 0)
890 positioning_type = lookup_type;
891 if (subtable->Format == 1)
893 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
895 format = single1->ValueFormat;
896 value = &single1->Value;
898 else if (subtable->Format == 2)
900 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
902 format = single2->ValueFormat;
903 value = single2->Value + coverage_idx;
905 if (accumulate && g->positioning_type)
907 gidx = gstring_insert_for_gpos (gstring, gidx);
908 g = gstring->glyphs + gidx;
910 g->positioning_type = positioning_type;
911 g->f.f1.format = format;
912 g->f.f1.value = value;
914 print_glyph_positioning (g, 0);
923 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
924 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
925 next_gidx++, nextg++);
927 if (next_gidx >= gstring->used)
929 if (subtable->Format == 1)
931 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
932 OTF_PairSet *set = pair1->PairSet + coverage_idx;
935 for (j = 0; j < set->PairValueCount; j++)
936 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
938 if (pair1->ValueFormat1)
940 if (accumulate && g->positioning_type)
942 gidx = gstring_insert_for_gpos (gstring, gidx);
943 g = gstring->glyphs + gidx;
944 next_gidx += gidx - orig_gidx;
945 nextg = gstring->glyphs + next_gidx;
947 g->positioning_type = lookup_type;
948 g->f.f2.format = pair1->ValueFormat1;
949 g->f.f2.value = &set->PairValueRecord[j].Value1;
951 print_glyph_positioning (g, 1);
955 if (pair1->ValueFormat2)
957 if (accumulate && g->positioning_type)
959 gidx = gstring_insert_for_gpos (gstring, gidx);
960 g = gstring->glyphs + gidx;
962 g->positioning_type = lookup_type;
963 g->f.f2.format = pair1->ValueFormat2;
964 g->f.f2.value = &set->PairValueRecord[j].Value2;
966 print_glyph_positioning (g, 2);
971 else if (subtable->Format == 2)
973 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
974 unsigned class1, class2;
976 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
977 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
978 if (pair2->ValueFormat1)
980 if (accumulate && g->positioning_type)
982 gidx = gstring_insert_for_gpos (gstring, gidx);
983 g = gstring->glyphs + gidx;
984 next_gidx += gidx - orig_gidx;
985 nextg = gstring->glyphs + next_gidx;
987 g->positioning_type = lookup_type;
988 g->f.f2.format = pair2->ValueFormat1;
990 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
992 print_glyph_positioning (g, 1);
996 if (pair2->ValueFormat2)
998 if (accumulate && g->positioning_type)
1000 gidx = gstring_insert_for_gpos (gstring, gidx);
1001 g = gstring->glyphs + gidx;
1003 g->positioning_type = lookup_type;
1004 g->f.f2.format = pair2->ValueFormat2;
1006 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
1008 print_glyph_positioning (g, 2);
1016 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
1018 g->positioning_type = lookup_type;
1019 g->f.f3.entry_anchor
1020 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
1022 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
1024 print_glyph_positioning (g, 0);
1032 if (subtable->Format == 1)
1034 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
1035 OTF_MarkRecord *mark_record;
1036 OTF_AnchorRecord *base_record;
1038 int coverage_idx_base;
1039 unsigned int this_flag = flag | OTF_IgnoreMarks;
1042 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
1044 if (baseg < gstring->glyphs)
1047 = get_coverage_index (&mark_base1->BaseCoverage,
1049 if (coverage_idx_base < 0)
1051 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1053 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1054 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1056 = &base_record->Anchor[mark_record->Class];
1057 g->positioning_type = lookup_type;
1059 print_glyph_positioning (g, 0);
1067 if (subtable->Format == 1)
1069 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1071 int coverage_idx_lig;
1072 OTF_MarkRecord *mark_record;
1073 OTF_LigatureAttach *attach;
1074 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1077 for (j = 0; j < mark_lig1->ClassCount; j++)
1081 (ligg >= gstring->glyphs
1082 && (IGNORED_GLYPH (ligg, flag)
1083 || ligg->GlyphClass > OTF_GlyphClassLigature));
1085 if (ligg->positioning_type == 5
1086 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1087 num_class[ligg->MarkAttachClass]++;
1088 if (ligg < gstring->glyphs)
1091 = get_coverage_index (&mark_lig1->LigatureCoverage,
1093 if (coverage_idx_lig < 0)
1095 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1096 g->MarkAttachClass = mark_record->Class;
1097 attach = (mark_lig1->LigatureArray.LigatureAttach
1098 + coverage_idx_lig);
1099 for (j = 0; j < attach->ComponentCount; j++)
1101 OTF_Anchor *lig_anchor
1102 = attach->ComponentRecord[j].LigatureAnchor;
1104 if (lig_anchor[mark_record->Class].AnchorFormat
1105 && num_class[mark_record->Class]-- == 0)
1107 g->positioning_type = lookup_type;
1108 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1109 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1111 print_glyph_positioning (g, 0);
1122 if (subtable->Format == 1)
1124 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1125 OTF_MarkRecord *mark1_record;
1126 OTF_AnchorRecord *mark2_record;
1128 int coverage_idx_base;
1131 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1133 if (prevg < gstring->glyphs)
1136 = get_coverage_index (&mark_mark1->Mark2Coverage,
1138 if (coverage_idx_base < 0)
1140 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1142 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1143 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1144 g->f.f6.mark2_anchor
1145 = &mark2_record->Anchor[mark1_record->Class];
1146 g->positioning_type = lookup_type;
1148 print_glyph_positioning (g, 0);
1155 if (subtable->Format == 1)
1157 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1158 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1163 for (j = 0; j < set->RuleCount; j++)
1165 rule = set->Rule + j;
1166 if (match_ids (gstring, gidx + 1, flag,
1167 rule->GlyphCount - 1, rule->Input) < 0)
1169 orig_used = gstring->used;
1170 for (k = 0; k < rule->LookupCount; k++)
1171 lookup_gpos (lookup_list,
1172 rule->LookupRecord[k].LookupListIndex,
1174 gidx + rule->LookupRecord[k].SequenceIndex,
1176 gidx += rule->GlyphCount + (gstring->used - orig_used);
1180 else if (subtable->Format == 2)
1182 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1184 OTF_ClassRule *rule;
1189 class = get_class_def (&context2->ClassDef, g->glyph_id);
1190 set = context2->ClassSet + class;
1192 for (j = 0; j < set->ClassRuleCnt; j++)
1194 rule = set->ClassRule + j;
1195 if (match_classes (&context2->ClassDef,
1196 gstring, gidx + 1, flag,
1197 rule->GlyphCount - 1, rule->Class)
1200 orig_used = gstring->used;
1201 for (k = 0; k < rule->LookupCount; k++)
1202 lookup_gpos (lookup_list,
1203 rule->LookupRecord[k].LookupListIndex,
1205 gidx + rule->LookupRecord[k].SequenceIndex,
1207 gidx += rule->GlyphCount + (gstring->used - orig_used);
1211 else /* subtable->Format == 3 */
1213 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1217 if (match_coverages (gstring, gidx + 1, flag,
1218 context3->GlyphCount - 1,
1219 context3->Coverage + 1) < 0)
1221 orig_used = gstring->used;
1222 for (j = 0; j < context3->LookupCount; j++)
1223 lookup_gpos (lookup_list,
1224 context3->LookupRecord[j].LookupListIndex,
1226 gidx + context3->LookupRecord[j].SequenceIndex,
1228 gidx += context3->GlyphCount + (gstring->used - orig_used);
1233 if (subtable->Format == 1)
1235 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1236 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1240 for (j = 0; j < set->ChainRuleCount; j++)
1242 OTF_ChainRule *rule = set->ChainRule + j;
1244 if (gidx < rule->BacktrackGlyphCount
1245 || (gidx + rule->InputGlyphCount
1246 + rule->LookaheadGlyphCount) > gstring->used)
1248 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1250 orig_used = gstring->used;
1251 for (k = 0; k < rule->LookupCount; k++)
1252 lookup_gpos (lookup_list,
1253 rule->LookupRecord[k].LookupListIndex,
1255 gidx + rule->LookupRecord[k].SequenceIndex,
1257 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1261 else if (subtable->Format == 2)
1263 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1264 OTF_ChainClassSet *set;
1269 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1270 set = context2->ChainClassSet + class;
1271 for (j = 0; j < set->ChainClassRuleCnt; j++)
1273 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1276 if (gidx < rule->BacktrackGlyphCount
1277 || (gidx + rule->InputGlyphCount
1278 + rule->LookaheadGlyphCount) > gstring->used)
1280 if (match_chain_classes (gstring, gidx, flag,
1281 &context2->BacktrackClassDef,
1282 &context2->InputClassDef,
1283 &context2->LookaheadClassDef,
1286 orig_used = gstring->used;
1287 for (k = 0; k < rule->LookupCount; k++)
1288 lookup_gpos (lookup_list,
1289 rule->LookupRecord[k].LookupListIndex,
1291 gidx + rule->LookupRecord[k].SequenceIndex,
1293 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1297 else if (subtable->Format == 3)
1299 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1303 if (gidx < context3->BacktrackGlyphCount
1304 || (gidx + context3->InputGlyphCount
1305 + context3->LookaheadGlyphCount) > gstring->used)
1307 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1309 orig_used = gstring->used;
1310 for (j = 0; j < context3->LookupCount; j++)
1311 lookup_gpos (lookup_list,
1312 context3->LookupRecord[j].LookupListIndex,
1314 gidx + context3->LookupRecord[j].SequenceIndex,
1316 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1319 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1326 if (gidx == orig_gidx)
1329 fprintf (stderr, " no match\n");
1332 else if (debug_flag)
1333 fprintf (stderr, "\n");
1338 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1340 return ((c < 0 || c >= 256)
1342 : sub->f.f0->glyphIdArray[c]);
1346 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1352 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1355 OTF_EncodingSubtable4 *sub4;
1360 segCount = sub4->segCountX2 / 2;
1361 for (i = 0; i < segCount; i++)
1363 OTF_cmapSegment *seg = sub4->segments + i;
1365 if (c >= seg->startCount && c <= seg->endCount)
1367 if (seg->idRangeOffset == 0xFFFF)
1368 return c + seg->idDelta;
1370 return sub4->glyphIdArray[seg->idRangeOffset
1371 + (c - seg->startCount)];
1378 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1384 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1390 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1396 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1398 OTF_EncodingSubtable12 *sub12;
1399 OTF_cmapGroup *g, *gend;
1405 gend = sub12->Groups + sub12->nGroups;
1408 if (g->startCharCode <= c && c <= g->endCharCode)
1409 return (g->startGlyphID + (c - g->startCharCode));
1415 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1417 static lookup_cmap_func lookup_cmap_func_table[] =
1419 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1420 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1424 get_GlyphID (OTF_cmap *cmap, int c)
1426 OTF_EncodingSubtable *sub;
1427 lookup_cmap_func lookupper;
1429 if (c < 0x10000 && cmap->unicode_table)
1430 return cmap->unicode_table[c];
1431 if (cmap->table_index < 0)
1433 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1434 lookupper = lookup_cmap_func_table[sub->format / 2];
1435 return lookupper (c, sub);
1439 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1441 unsigned nRecords = sub14->nRecords;
1442 OTF_VariationSelectorRecord *record;
1445 for (i = 0; i < nRecords; i++)
1447 record = &sub14->Records[i];
1448 if (record->varSelector == c2)
1450 if (record->defaultUVSOffset)
1452 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1453 unsigned numUVRs = record->numUnicodeValueRanges;
1454 unsigned top = numUVRs, bottom = 0, middle;
1456 if (uVRs[0].startUnicodeValue <= c1)
1458 unsigned additionalCount, startUnicodeValue;
1462 middle = (top + bottom) / 2;
1463 if (c1 < uVRs[middle].startUnicodeValue)
1465 else if (bottom == middle)
1470 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1471 additionalCount = uVRs[bottom].additionalCount;
1472 if (c1 <= startUnicodeValue + additionalCount)
1473 return get_GlyphID (cmap, c1);
1476 if (record->nonDefaultUVSOffset)
1478 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1479 unsigned numUVSMs = record->numUVSMappings;
1480 unsigned top = numUVSMs, bottom = 0, middle;
1482 if (uvsMappings[0].unicodeValue <= c1)
1486 middle = (top + bottom) / 2;
1487 if (c1 < uvsMappings[middle].unicodeValue)
1489 else if (bottom == middle)
1494 if (uvsMappings[bottom].unicodeValue == c1)
1495 return uvsMappings[bottom].glyphID;
1505 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1507 OTF_EncodingSubtable14 *sub14;
1508 int c1 = gstring->glyphs[idx - 1].c;
1509 int c2 = gstring->glyphs[idx].c;
1513 gstring->glyphs[idx].glyph_id = 0;
1514 for (i = 0; i < cmap->numTables; i++)
1515 if (cmap->EncodingRecord[i].subtable.format == 14)
1517 if (i == cmap->numTables)
1519 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1522 gstring->glyphs[idx - 1].glyph_id = code;
1523 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1525 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1526 sizeof (OTF_Glyph) * (gstring->used - idx));
1532 /* Table of GlyphClass and MarkAttackClass.
1534 For the Nth element CHAR, CHAR and the succeeding characters
1535 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1537 This table is generated from the General Category (GC) property of
1538 characters defined in the Unicode Character Database. */
1540 static int glyph_class_table[] =
1541 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1542 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1543 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1544 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1545 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1546 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1547 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1548 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1549 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1550 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1551 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1552 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1553 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1554 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1555 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1556 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1557 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1558 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1559 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1560 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1561 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1562 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1563 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1564 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1565 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1566 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1567 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1568 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1569 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1571 int get_class_def_auto (int c)
1573 static int table_size
1574 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1577 if (c >= glyph_class_table[table_size - 1])
1580 high = table_size - 1;
1583 mid = (low + high) / 2;
1584 if (c < glyph_class_table[mid])
1586 else if (c >= glyph_class_table[mid + 1])
1591 return ((mid % 2) ? 3 : 1);
1599 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1602 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1606 OTF_EncodingSubtable *sub;
1607 lookup_cmap_func lookupper;
1610 && OTF_get_table (otf, "cmap") < 0)
1614 if (cmap->table_index < 0)
1618 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1619 lookupper = lookup_cmap_func_table[sub->format / 2];
1621 for (i = 0; i < gstring->used; i++)
1622 if (! gstring->glyphs[i].glyph_id)
1624 int c = gstring->glyphs[i].c;
1625 if (c < 32 || ! cmap->unicode_table)
1626 gstring->glyphs[i].glyph_id = 0;
1627 else if (UVS_P (c) && i > 0)
1628 check_cmap_uvs (cmap, gstring, i);
1629 else if (c < 0x10000)
1630 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1632 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1639 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1640 int platform_id, int encoding_id)
1644 char *errfmt = "CMAP Looking up%s";
1646 OTF_EncodingRecord *enc;
1647 lookup_cmap_func lookupper;
1650 && OTF_get_table (otf, "cmap") < 0)
1654 for (i = 0; i < cmap->numTables; i++)
1655 if (cmap->EncodingRecord[i].platformID == platform_id
1656 && cmap->EncodingRecord[i].encodingID == encoding_id)
1658 if (i == cmap->numTables)
1659 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1660 enc = cmap->EncodingRecord + i;
1661 if (enc->subtable.format > 12)
1662 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1663 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1665 for (i = 0; i < gstring->used; i++)
1666 if (! gstring->glyphs[i].glyph_id)
1668 int c = gstring->glyphs[i].c;
1669 if (c < 32 || ! cmap->unicode_table)
1670 gstring->glyphs[i].glyph_id = 0;
1671 else if (UVS_P (c) && i > 0)
1672 check_cmap_uvs (cmap, gstring, i);
1673 else if (c < 0x10000)
1674 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1676 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1682 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1685 && OTF_get_table (otf, "cmap") < 0)
1688 || code > otf->cmap->max_glyph_id
1689 || ! otf->cmap->decode_table)
1691 return otf->cmap->decode_table[code];
1695 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1699 OTF_EncodingSubtable14 *sub14;
1701 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1703 && OTF_get_table (otf, "cmap") < 0)
1706 for (i = 0; i < cmap->numTables; i++)
1707 if (cmap->EncodingRecord[i].subtable.format == 14)
1709 if (i == cmap->numTables)
1711 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1712 for (i = 0, n = 0; i < 256; i++)
1714 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1716 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1724 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1730 && OTF_get_table (otf, "GDEF") < 0)
1734 if (gdef->glyph_class_def.offset)
1735 for (i = 0; i < gstring->used; i++)
1736 gstring->glyphs[i].GlyphClass
1737 = get_class_def (&gdef->glyph_class_def,
1738 gstring->glyphs[i].glyph_id);
1740 for (i = 0; i < gstring->used; i++)
1741 gstring->glyphs[i].GlyphClass
1742 = get_class_def_auto (gstring->glyphs[i].c);
1744 if (gdef->mark_attach_class_def.offset)
1745 for (i = 0; i < gstring->used; i++)
1746 gstring->glyphs[i].MarkAttachClass
1747 = get_class_def (&gdef->mark_attach_class_def,
1748 gstring->glyphs[i].glyph_id);
1754 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1755 const char *script, const char *language,
1756 const char *features,
1757 int alternate_subst)
1759 char *errfmt = "GSUB driving%s";
1762 OTF_LangSys *LangSys;
1766 for (i = 0; i < gstring->used; i++)
1768 gstring->glyphs[i].positioning_type = 0;
1769 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1772 if (OTF_get_table (otf, "GSUB") < 0)
1775 if (gsub->FeatureList.FeatureCount == 0
1776 || gsub->LookupList.LookupCount == 0)
1779 LangSys = get_langsys (&gsub->ScriptList, script, language);
1783 lookup_flags = alloca (gsub->LookupList.LookupCount);
1785 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1786 features, lookup_flags) < 0)
1787 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1789 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1793 if (! lookup_flags[i]) continue;
1795 if (gsub->LookupList.Lookup[i].LookupType != 8)
1798 while (gidx < gstring->used)
1800 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1808 gidx = gstring->used - 1;
1811 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1823 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1824 const char *script, const char *language, const char *features)
1827 OTF_get_table (otf, "cmap");
1828 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
1832 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1833 const char *script, const char *language,
1834 const char *features,
1837 char *errfmt = "GPOS driving%s";
1840 OTF_LangSys *LangSys;
1844 for (i = 0; i < gstring->used; i++)
1845 gstring->glyphs[i].positioning_type = 0;
1847 if (OTF_get_table (otf, "GPOS") < 0)
1850 if (gpos->FeatureList.FeatureCount == 0
1851 || gpos->LookupList.LookupCount == 0)
1854 LangSys = get_langsys (&gpos->ScriptList, script, language);
1858 lookup_flags = alloca (gpos->LookupList.LookupCount);
1860 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1861 features, lookup_flags) < 0)
1862 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1864 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1868 if (! lookup_flags[i]) continue;
1870 while (gidx < gstring->used)
1872 gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
1882 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1883 const char *script, const char *language, const char *features)
1886 OTF_get_table (otf, "cmap");
1887 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
1891 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1892 const char *script, const char *language, const char *features)
1895 OTF_get_table (otf, "cmap");
1896 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
1900 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1901 const char *script, const char *language,
1902 const char *gsub_features, const char *gpos_features)
1904 if (OTF_drive_cmap (otf, gstring) < 0)
1906 if (OTF_drive_gdef (otf, gstring) < 0)
1909 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1912 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1918 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1919 const char *script, const char *language,
1920 const char *features)
1922 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
1926 iterate_coverage (OTF *otf, const char *feature,
1927 OTF_Feature_Callback callback,
1928 OTF_Coverage *coverage)
1932 if (coverage->CoverageFormat == 1)
1934 for (i = 0; i < coverage->Count; i++)
1935 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1940 for (i = 0; i < coverage->Count; i++)
1942 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1944 for (id = range->Start; id <= range->End; id++)
1945 if (callback (otf, feature, id) < 0)
1953 iterate_feature (OTF *otf, const char *feature,
1954 OTF_Feature_Callback callback,
1959 for (i = 0; i < lookup->SubTableCount; i++)
1961 unsigned lookup_type = lookup->LookupType;
1962 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1964 if (lookup_type == 7)
1966 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
1968 lookup_type = extension1->ExtensionLookupType;
1969 subtable = extension1->ExtensionSubtable;
1972 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
1974 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1978 else if (lookup_type == 4)
1980 OTF_GSUB_Ligature1 *lig1;
1982 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1985 lig1 = &subtable->u.ligature1;
1986 for (j = 0; j < lig1->LigSetCount; j++)
1988 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
1990 for (k = 0; k < ligset->LigatureCount; k++)
1992 OTF_Ligature *lig = ligset->Ligature + k;
1993 for (l = 0; l < lig->CompCount - 1; l++)
1994 if (callback (otf, feature, lig->Component[l]) < 0)
1999 else if (lookup_type == 6)
2001 if (subtable->Format == 1)
2003 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
2004 for (j = 0; j < context1->ChainRuleSetCount; j++)
2006 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
2007 for (k = 0; k < set->ChainRuleCount; k++)
2009 OTF_ChainRule *rule = set->ChainRule + k;
2010 for (l = 0; l < rule->LookupCount; l++)
2013 = (otf->gsub->LookupList.Lookup
2014 + rule->LookupRecord[l].LookupListIndex);
2015 if (iterate_feature (otf, feature, callback, lkup)
2022 else if (subtable->Format == 2)
2024 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
2026 for (j = 0; j < context2->ChainClassSetCnt; j++)
2028 OTF_ChainClassSet *set = context2->ChainClassSet + j;
2029 for (k = 0; k < set->ChainClassRuleCnt; j++)
2031 OTF_ChainClassRule *rule = set->ChainClassRule + k;
2033 for (l = 0; l < rule->LookupCount; l++)
2036 = (otf->gsub->LookupList.Lookup
2037 + rule->LookupRecord[k].LookupListIndex);
2038 if (iterate_feature (otf, feature, callback, lkup)
2047 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
2048 for (j = 0; j < context3->LookupCount; j++)
2051 = (otf->gsub->LookupList.Lookup
2052 + context3->LookupRecord[j].LookupListIndex);
2053 if (iterate_feature (otf, feature, callback, lkup) < 0)
2063 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2064 const char *script, const char *language,
2065 const char *feature)
2067 char *errfmt = "GSUB iterate feature%s";
2072 OTF_LangSys *langsys;
2075 if (OTF_get_table (otf, "GSUB") < 0)
2078 if (gsub->FeatureList.FeatureCount == 0
2079 || gsub->LookupList.LookupCount == 0)
2081 langsys = get_langsys (&gsub->ScriptList, script, language);
2084 lookup_flags = alloca (gsub->LookupList.LookupCount);
2086 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2087 feature, lookup_flags) < 0)
2088 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2090 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2091 if (lookup_flags[i])
2092 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)