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 = 1;
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]] = index + 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 int index = LangSys->FeatureIndex[i];
264 feature = FeatureList->Feature + index;
265 if (tag == feature->FeatureTag)
267 if (feature_table[i])
270 for (j = 0; j < feature->LookupCount; j++)
271 lookup_flags[feature->LookupListIndex[j]] = index + 1;
272 feature_table[i] = use_it;
281 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
282 int count, OTF_GlyphID *ids, int direction)
284 OTF_Glyph *g = gstring->glyphs + gidx;
285 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
288 for (i = j = 0; i < count && g != gend; j++, g += direction)
289 if (! IGNORED_GLYPH (g, flag)
290 && g->glyph_id != ids[i++])
292 return (i < count ? -1 : j);
296 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
299 int i = rule->BacktrackGlyphCount;
303 || match_ids (gstring, gidx - 1, flag, i, rule->Backtrack, -1) < 0))
306 i = match_ids (gstring, gidx, flag,
307 rule->InputGlyphCount - 1, rule->Input, 1);
311 i = match_ids (gstring, gidx, flag,
312 rule->LookaheadGlyphCount, rule->LookAhead, 1);
319 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
320 int flag, int count, unsigned *classes, int direction)
322 OTF_Glyph *g = gstring->glyphs + gidx;
323 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
326 for (i = j = 0; i < count && g != gend; j++, g += direction)
327 if (! IGNORED_GLYPH (g, flag)
328 && get_class_def (class_def, g->glyph_id) != classes[i++])
330 return (i < count ? -1 : j);
334 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
335 OTF_ClassDef *BacktrackClassDef,
336 OTF_ClassDef *InputClassDef,
337 OTF_ClassDef *LookaheadClassDef,
338 OTF_ChainClassRule *rule)
340 int i = rule->BacktrackGlyphCount;
344 || match_classes (BacktrackClassDef, gstring, gidx - 1, flag, i,
345 rule->Backtrack, -1) < 0))
348 i = match_classes (InputClassDef, gstring, gidx, flag,
349 rule->InputGlyphCount - 1, rule->Input, 1);
353 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
354 rule->LookaheadGlyphCount, rule->LookAhead, 1);
362 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
363 OTF_Coverage *coverages, int direction)
365 OTF_Glyph *g = gstring->glyphs + gidx;
366 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : - 1);
369 for (i = j = 0; i < count && g != gend; j++, g += direction)
370 if (! IGNORED_GLYPH (g, flag)
371 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
373 return (i < count ? -1 : j);
377 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
378 OTF_GSUB_ChainContext3 *context3)
380 int i = context3->BacktrackGlyphCount;
384 || match_coverages (gstring, gidx - 1, flag, i,
385 context3->Backtrack, -1) < 0))
388 if (context3->InputGlyphCount > 1)
390 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
391 context3->Input + 1, 1);
396 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
397 context3->LookAhead, 1) < 0)
402 /* Apply the lookup indexed by LOOKUP_LIST_INDEX in LOOKUP_LIST to the
403 glyphs indexed by GIDX in GSTRING and the followings. If
404 successfully applied, return the index of the next glyph to apply
405 the lookup. If not applied, return GIDX. If error happened,
409 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
410 OTF_GlyphString *gstring, int gidx, int alternate_subst)
412 char *errfmt = "GSUB Looking up%s";
414 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
415 unsigned int flag = (lookup->LookupFlag
416 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
417 int orig_gidx = gidx;
418 OTF_Glyph *g = gstring->glyphs + gidx;
421 if (IGNORED_GLYPH (g, flag))
424 /* Try all subtables until one of them handles the current glyph. */
425 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
427 unsigned lookup_type = lookup->LookupType;
428 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
431 if (lookup_type == 7)
433 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
435 lookup_type = extension1->ExtensionLookupType;
436 subtable = extension1->ExtensionSubtable;
440 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
441 : (lookup_type == 3))
444 if (subtable->Coverage.offset)
446 coverage_idx = get_coverage_index (&subtable->Coverage,
448 if (coverage_idx < 0)
455 if (subtable->Format == 1)
456 g->glyph_id += subtable->u.single1.DeltaGlyphID;
458 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
459 g->positioning_type = 1;
464 if (subtable->Format == 1)
466 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
467 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
469 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
470 seq->Substitute, seq->GlyphCount);
471 gidx += seq->GlyphCount;
474 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
478 if (subtable->Format == 1)
480 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
481 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
483 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
484 altset->Alternate, altset->GlyphCount);
485 gidx += altset->GlyphCount;;
488 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
492 if (subtable->Format == 1)
494 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
495 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
499 for (j = 0; j < ligset->LigatureCount; j++)
503 lig = ligset->Ligature + j;
504 n = match_ids (gstring, gidx + 1, flag,
505 lig->CompCount - 1, lig->Component, 1);
508 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
515 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
519 if (subtable->Format == 1)
521 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
522 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
527 for (j = 0; j < set->RuleCount; j++)
529 rule = set->Rule + j;
530 if (match_ids (gstring, gidx + 1, flag,
531 rule->GlyphCount - 1, rule->Input, 1) < 0)
533 orig_used = gstring->used;
534 for (k = 0; k < rule->LookupCount; k++)
535 lookup_gsub (otf, lookup_list,
536 rule->LookupRecord[k].LookupListIndex,
538 gidx + rule->LookupRecord[k].SequenceIndex,
540 gidx += rule->GlyphCount + (gstring->used - orig_used);
544 else if (subtable->Format == 2)
546 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
553 class = get_class_def (&context2->ClassDef, g->glyph_id);
554 set = context2->ClassSet + class;
556 for (j = 0; j < set->ClassRuleCnt; j++)
558 rule = set->ClassRule + j;
559 if (match_classes (&context2->ClassDef,
560 gstring, gidx + 1, flag,
561 rule->GlyphCount - 1, rule->Class, 1)
564 orig_used = gstring->used;
565 for (k = 0; k < rule->LookupCount; k++)
566 lookup_gsub (otf, lookup_list,
567 rule->LookupRecord[k].LookupListIndex,
569 gidx + rule->LookupRecord[k].SequenceIndex,
571 gidx += rule->GlyphCount + (gstring->used - orig_used);
575 else /* subtable->Format == 3 */
577 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
581 if (match_coverages (gstring, gidx + 1, flag,
582 context3->GlyphCount - 1,
583 context3->Coverage + 1, 1) < 0)
585 orig_used = gstring->used;
586 for (j = 0; j < context3->LookupCount; j++)
587 lookup_gsub (otf, lookup_list,
588 context3->LookupRecord[j].LookupListIndex,
590 gidx + context3->LookupRecord[j].SequenceIndex,
592 gidx += context3->GlyphCount + (gstring->used - orig_used);
597 if (subtable->Format == 1)
599 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
600 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
604 for (j = 0; j < set->ChainRuleCount; j++)
606 OTF_ChainRule *rule = set->ChainRule + j;
608 if (gidx < rule->BacktrackGlyphCount
609 || (gidx + rule->InputGlyphCount
610 + rule->LookaheadGlyphCount) > gstring->used)
612 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
614 orig_used = gstring->used;
615 for (k = 0; k < rule->LookupCount; k++)
616 lookup_gsub (otf, lookup_list,
617 rule->LookupRecord[k].LookupListIndex,
619 gidx + rule->LookupRecord[k].SequenceIndex,
621 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
625 else if (subtable->Format == 2)
627 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
628 OTF_ChainClassSet *set;
633 class = get_class_def (&context2->InputClassDef, g->glyph_id);
634 set = context2->ChainClassSet + class;
635 for (j = 0; j < set->ChainClassRuleCnt; j++)
637 OTF_ChainClassRule *rule = set->ChainClassRule + j;
640 if (gidx < rule->BacktrackGlyphCount
641 || (gidx + rule->InputGlyphCount
642 + rule->LookaheadGlyphCount) > gstring->used)
644 if (match_chain_classes (gstring, gidx, flag,
645 &context2->BacktrackClassDef,
646 &context2->InputClassDef,
647 &context2->LookaheadClassDef,
650 orig_used = gstring->used;
651 for (k = 0; k < rule->LookupCount; k++)
652 lookup_gsub (otf, lookup_list,
653 rule->LookupRecord[k].LookupListIndex,
655 gidx + rule->LookupRecord[k].SequenceIndex,
657 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
663 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
667 if (gidx < context3->BacktrackGlyphCount
668 || (gidx + context3->InputGlyphCount
669 + context3->LookaheadGlyphCount) > gstring->used)
671 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
673 orig_used = gstring->used;
674 for (j = 0; j < context3->LookupCount; j++)
675 lookup_gsub (otf, lookup_list,
676 context3->LookupRecord[j].LookupListIndex,
678 gidx + context3->LookupRecord[j].SequenceIndex,
680 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
686 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
687 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
688 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
691 if (back_gidx > gstring->used || ahead_gidx < 0)
694 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
695 if (get_coverage_index (reverse->Backtrack + j,
696 gstring->glyphs[gidx + 1 + j].glyph_id)
699 if (j < reverse->BacktrackGlyphCount)
701 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
702 if (get_coverage_index (reverse->LookAhead + j,
703 gstring->glyphs[gidx - 1 - j].glyph_id)
706 if (j < reverse->LookaheadGlyphCount)
708 g->glyph_id = reverse->Substitute[coverage_idx];
709 g->positioning_type = 1;
725 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
728 int orig_gidx = gidx++;
730 while (gidx < gstring->used
731 && ! gstring->glyphs[gidx].glyph_id
732 && (gstring->glyphs[gidx].positioning_type & 0xF))
734 GSTRING_INSERT (gstring, gidx, 1);
735 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
736 gstring->glyphs[gidx].glyph_id = 0;
741 print_anchor (char *head, OTF_Anchor *anchor)
743 if (anchor->AnchorFormat == 1)
744 fprintf (stderr, " %s(X:%d Y:%d)", head,
745 anchor->XCoordinate, anchor->YCoordinate);
746 else if (anchor->AnchorFormat == 2)
747 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
748 anchor->XCoordinate, anchor->YCoordinate,
749 anchor->f.f1.AnchorPoint);
751 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
752 anchor->XCoordinate, anchor->YCoordinate);
756 print_glyph_positioning (OTF_Glyph *g, int type)
759 fprintf (stderr, " %0X=", g->glyph_id);
760 switch (g->positioning_type & 0xF)
764 int format = g->f.f1.format;
766 if (format & OTF_XPlacement)
767 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
768 if (format & OTF_XPlaDevice)
769 fprintf (stderr, "+alpha");
770 if (format & OTF_YPlacement)
771 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
772 if (format & OTF_YPlaDevice)
773 fprintf (stderr, "+alpha");
774 if (format & OTF_XAdvance)
775 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
776 if (format & OTF_XAdvDevice)
777 fprintf (stderr, "+alpha");
781 print_anchor ("entry", g->f.f3.entry_anchor);
782 print_anchor ("exit", g->f.f3.entry_anchor);
785 print_anchor ("mark", g->f.f4.mark_anchor);
786 print_anchor ("base", g->f.f4.base_anchor);
789 print_anchor ("mark", g->f.f5.mark_anchor);
790 print_anchor ("lig", g->f.f5.ligature_anchor);
793 print_anchor ("mark1", g->f.f6.mark1_anchor);
794 print_anchor ("mark2", g->f.f6.mark2_anchor);
799 /* See the comment of lookup_gsub. */
802 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
803 OTF_GlyphString *gstring, int gidx, int accumulate)
805 char *errfmt = "GPOS Looking up%s";
807 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
808 unsigned int flag = (lookup->LookupFlag
809 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
810 int orig_gidx = gidx;
811 OTF_Glyph *g = gstring->glyphs + gidx;
815 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
816 g->glyph_id, lookup_list_index);
817 if (IGNORED_GLYPH (g, flag))
820 fprintf (stderr, " glyph ignored\n");
824 /* Try all subtables until one of them handles the current glyph. */
825 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
827 unsigned lookup_type = lookup->LookupType;
828 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
830 int positioning_type;
831 enum OTF_ValueFormat format;
832 OTF_ValueRecord *value;
833 OTF_Anchor *anchor1, *anchor2;
835 if (lookup_type == 9)
837 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
839 lookup_type = extension1->ExtensionLookupType;
840 subtable = extension1->ExtensionSubtable;
844 fprintf (stderr, "/%d", lookup_type);
845 if (subtable->Coverage.offset)
847 coverage_idx = get_coverage_index (&subtable->Coverage,
849 if (coverage_idx < 0)
856 if (subtable->Format == 1)
858 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
860 format = single1->ValueFormat;
861 value = &single1->Value;
863 else if (subtable->Format == 2)
865 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
867 format = single2->ValueFormat;
868 value = single2->Value + coverage_idx;
870 if (accumulate && (g->positioning_type & 0xF))
872 gidx = gstring_insert_for_gpos (gstring, gidx);
873 g = gstring->glyphs + gidx;
876 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
877 g->f.f1.format = format;
878 g->f.f1.value = value;
880 print_glyph_positioning (g, 0);
889 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
890 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
891 next_gidx++, nextg++);
893 if (next_gidx >= gstring->used)
895 if (subtable->Format == 1)
897 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
898 OTF_PairSet *set = pair1->PairSet + coverage_idx;
901 for (j = 0; j < set->PairValueCount; j++)
902 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
904 if (pair1->ValueFormat1)
906 if (accumulate && (g->positioning_type & 0xF))
908 gidx = gstring_insert_for_gpos (gstring, gidx);
909 g = gstring->glyphs + gidx;
910 next_gidx += gidx - orig_gidx;
911 nextg = gstring->glyphs + next_gidx;
914 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
915 g->f.f2.format = pair1->ValueFormat1;
916 g->f.f2.value = &set->PairValueRecord[j].Value1;
918 print_glyph_positioning (g, 1);
922 if (pair1->ValueFormat2)
924 if (accumulate && (g->positioning_type & 0xF))
926 gidx = gstring_insert_for_gpos (gstring, gidx);
927 g = gstring->glyphs + gidx;
930 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
931 g->f.f2.format = pair1->ValueFormat2;
932 g->f.f2.value = &set->PairValueRecord[j].Value2;
934 print_glyph_positioning (g, 2);
939 else if (subtable->Format == 2)
941 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
942 unsigned class1, class2;
944 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
945 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
946 if (pair2->ValueFormat1)
948 if (accumulate && (g->positioning_type & 0xF))
950 gidx = gstring_insert_for_gpos (gstring, gidx);
951 g = gstring->glyphs + gidx;
952 next_gidx += gidx - orig_gidx;
953 nextg = gstring->glyphs + next_gidx;
956 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
957 g->f.f2.format = pair2->ValueFormat1;
959 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
961 print_glyph_positioning (g, 1);
965 if (pair2->ValueFormat2)
967 if (accumulate && (g->positioning_type & 0xF))
969 gidx = gstring_insert_for_gpos (gstring, gidx);
970 g = gstring->glyphs + gidx;
973 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
974 g->f.f2.format = pair2->ValueFormat2;
976 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
978 print_glyph_positioning (g, 2);
986 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
989 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
991 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
993 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
995 print_glyph_positioning (g, 0);
1003 if (subtable->Format == 1)
1005 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
1006 OTF_MarkRecord *mark_record;
1007 OTF_AnchorRecord *base_record;
1009 int coverage_idx_base;
1010 unsigned int this_flag = flag | OTF_IgnoreMarks;
1013 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
1015 if (baseg < gstring->glyphs)
1018 = get_coverage_index (&mark_base1->BaseCoverage,
1020 if (coverage_idx_base < 0)
1022 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1024 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1025 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1027 = &base_record->Anchor[mark_record->Class];
1029 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
1031 print_glyph_positioning (g, 0);
1039 if (subtable->Format == 1)
1041 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1043 int coverage_idx_lig;
1044 OTF_MarkRecord *mark_record;
1045 OTF_LigatureAttach *attach;
1046 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1049 for (j = 0; j < mark_lig1->ClassCount; j++)
1053 (ligg >= gstring->glyphs
1054 && (IGNORED_GLYPH (ligg, flag)
1055 || ligg->GlyphClass > OTF_GlyphClassLigature));
1057 if ((ligg->positioning_type & 0xF) == 5
1058 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1059 num_class[ligg->MarkAttachClass]++;
1060 if (ligg < gstring->glyphs)
1063 = get_coverage_index (&mark_lig1->LigatureCoverage,
1065 if (coverage_idx_lig < 0)
1067 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1068 g->MarkAttachClass = mark_record->Class;
1069 attach = (mark_lig1->LigatureArray.LigatureAttach
1070 + coverage_idx_lig);
1071 for (j = 0; j < attach->ComponentCount; j++)
1073 OTF_Anchor *lig_anchor
1074 = attach->ComponentRecord[j].LigatureAnchor;
1076 if (lig_anchor[mark_record->Class].AnchorFormat
1077 && num_class[mark_record->Class]-- == 0)
1080 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
1081 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1082 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1084 print_glyph_positioning (g, 0);
1095 if (subtable->Format == 1)
1097 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1098 OTF_MarkRecord *mark1_record;
1099 OTF_AnchorRecord *mark2_record;
1101 int coverage_idx_base;
1104 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1106 if (prevg < gstring->glyphs)
1109 = get_coverage_index (&mark_mark1->Mark2Coverage,
1111 if (coverage_idx_base < 0)
1113 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1115 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1116 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1117 g->f.f6.mark2_anchor
1118 = &mark2_record->Anchor[mark1_record->Class];
1120 = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
1122 print_glyph_positioning (g, 0);
1129 if (subtable->Format == 1)
1131 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1132 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1137 for (j = 0; j < set->RuleCount; j++)
1139 rule = set->Rule + j;
1140 if (match_ids (gstring, gidx + 1, flag,
1141 rule->GlyphCount - 1, rule->Input, 1) < 0)
1143 orig_used = gstring->used;
1144 for (k = 0; k < rule->LookupCount; k++)
1145 lookup_gpos (lookup_list,
1146 rule->LookupRecord[k].LookupListIndex,
1148 gidx + rule->LookupRecord[k].SequenceIndex,
1150 gidx += rule->GlyphCount + (gstring->used - orig_used);
1154 else if (subtable->Format == 2)
1156 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1158 OTF_ClassRule *rule;
1163 class = get_class_def (&context2->ClassDef, g->glyph_id);
1164 set = context2->ClassSet + class;
1166 for (j = 0; j < set->ClassRuleCnt; j++)
1168 rule = set->ClassRule + j;
1169 if (match_classes (&context2->ClassDef,
1170 gstring, gidx + 1, flag,
1171 rule->GlyphCount - 1, rule->Class, 1)
1174 orig_used = gstring->used;
1175 for (k = 0; k < rule->LookupCount; k++)
1176 lookup_gpos (lookup_list,
1177 rule->LookupRecord[k].LookupListIndex,
1179 gidx + rule->LookupRecord[k].SequenceIndex,
1181 gidx += rule->GlyphCount + (gstring->used - orig_used);
1185 else /* subtable->Format == 3 */
1187 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1191 if (match_coverages (gstring, gidx + 1, flag,
1192 context3->GlyphCount - 1,
1193 context3->Coverage + 1, 1) < 0)
1195 orig_used = gstring->used;
1196 for (j = 0; j < context3->LookupCount; j++)
1197 lookup_gpos (lookup_list,
1198 context3->LookupRecord[j].LookupListIndex,
1200 gidx + context3->LookupRecord[j].SequenceIndex,
1202 gidx += context3->GlyphCount + (gstring->used - orig_used);
1207 if (subtable->Format == 1)
1209 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1210 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1214 for (j = 0; j < set->ChainRuleCount; j++)
1216 OTF_ChainRule *rule = set->ChainRule + j;
1218 if (gidx < rule->BacktrackGlyphCount
1219 || (gidx + rule->InputGlyphCount
1220 + rule->LookaheadGlyphCount) > gstring->used)
1222 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1224 orig_used = gstring->used;
1225 for (k = 0; k < rule->LookupCount; k++)
1226 lookup_gpos (lookup_list,
1227 rule->LookupRecord[k].LookupListIndex,
1229 gidx + rule->LookupRecord[k].SequenceIndex,
1231 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1235 else if (subtable->Format == 2)
1237 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1238 OTF_ChainClassSet *set;
1243 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1244 set = context2->ChainClassSet + class;
1245 for (j = 0; j < set->ChainClassRuleCnt; j++)
1247 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1250 if (gidx < rule->BacktrackGlyphCount
1251 || (gidx + rule->InputGlyphCount
1252 + rule->LookaheadGlyphCount) > gstring->used)
1254 if (match_chain_classes (gstring, gidx, flag,
1255 &context2->BacktrackClassDef,
1256 &context2->InputClassDef,
1257 &context2->LookaheadClassDef,
1260 orig_used = gstring->used;
1261 for (k = 0; k < rule->LookupCount; k++)
1262 lookup_gpos (lookup_list,
1263 rule->LookupRecord[k].LookupListIndex,
1265 gidx + rule->LookupRecord[k].SequenceIndex,
1267 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1271 else if (subtable->Format == 3)
1273 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1277 if (gidx < context3->BacktrackGlyphCount
1278 || (gidx + context3->InputGlyphCount
1279 + context3->LookaheadGlyphCount) > gstring->used)
1281 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1283 orig_used = gstring->used;
1284 for (j = 0; j < context3->LookupCount; j++)
1285 lookup_gpos (lookup_list,
1286 context3->LookupRecord[j].LookupListIndex,
1288 gidx + context3->LookupRecord[j].SequenceIndex,
1290 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1293 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1302 if (gidx == orig_gidx)
1303 fprintf (stderr, " no match\n");
1305 fprintf (stderr, "\n");
1311 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1313 return ((c < 0 || c >= 256)
1315 : sub->f.f0->glyphIdArray[c]);
1319 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1325 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1328 OTF_EncodingSubtable4 *sub4;
1333 segCount = sub4->segCountX2 / 2;
1334 for (i = 0; i < segCount; i++)
1336 OTF_cmapSegment *seg = sub4->segments + i;
1338 if (c >= seg->startCount && c <= seg->endCount)
1340 if (seg->idRangeOffset == 0xFFFF)
1341 return c + seg->idDelta;
1343 return sub4->glyphIdArray[seg->idRangeOffset
1344 + (c - seg->startCount)];
1351 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1357 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1363 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1369 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1371 OTF_EncodingSubtable12 *sub12;
1372 OTF_cmapGroup *g, *gend;
1378 gend = sub12->Groups + sub12->nGroups;
1381 if (g->startCharCode <= c && c <= g->endCharCode)
1382 return (g->startGlyphID + (c - g->startCharCode));
1388 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1390 static lookup_cmap_func lookup_cmap_func_table[] =
1392 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1393 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1397 get_GlyphID (OTF_cmap *cmap, int c)
1399 OTF_EncodingSubtable *sub;
1400 lookup_cmap_func lookupper;
1402 if (c < 0x10000 && cmap->unicode_table)
1403 return cmap->unicode_table[c];
1404 if (cmap->table_index < 0)
1406 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1407 lookupper = lookup_cmap_func_table[sub->format / 2];
1408 return lookupper (c, sub);
1412 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1414 unsigned nRecords = sub14->nRecords;
1415 OTF_VariationSelectorRecord *record;
1418 for (i = 0; i < nRecords; i++)
1420 record = &sub14->Records[i];
1421 if (record->varSelector == c2)
1423 if (record->defaultUVSOffset)
1425 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1426 unsigned numUVRs = record->numUnicodeValueRanges;
1427 unsigned top = numUVRs, bottom = 0, middle;
1429 if (uVRs[0].startUnicodeValue <= c1)
1431 unsigned additionalCount, startUnicodeValue;
1435 middle = (top + bottom) / 2;
1436 if (c1 < uVRs[middle].startUnicodeValue)
1438 else if (bottom == middle)
1443 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1444 additionalCount = uVRs[bottom].additionalCount;
1445 if (c1 <= startUnicodeValue + additionalCount)
1446 return get_GlyphID (cmap, c1);
1449 if (record->nonDefaultUVSOffset)
1451 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1452 unsigned numUVSMs = record->numUVSMappings;
1453 unsigned top = numUVSMs, bottom = 0, middle;
1455 if (uvsMappings[0].unicodeValue <= c1)
1459 middle = (top + bottom) / 2;
1460 if (c1 < uvsMappings[middle].unicodeValue)
1462 else if (bottom == middle)
1467 if (uvsMappings[bottom].unicodeValue == c1)
1468 return uvsMappings[bottom].glyphID;
1478 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1480 OTF_EncodingSubtable14 *sub14;
1481 int c1 = gstring->glyphs[idx - 1].c;
1482 int c2 = gstring->glyphs[idx].c;
1486 gstring->glyphs[idx].glyph_id = 0;
1487 for (i = 0; i < cmap->numTables; i++)
1488 if (cmap->EncodingRecord[i].subtable.format == 14)
1490 if (i == cmap->numTables)
1492 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1495 gstring->glyphs[idx - 1].glyph_id = code;
1496 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1498 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1499 sizeof (OTF_Glyph) * (gstring->used - idx));
1505 /* Table of GlyphClass and MarkAttackClass.
1507 For the Nth element CHAR, CHAR and the succeeding characters
1508 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1510 This table is generated from the General Category (GC) property of
1511 characters defined in the Unicode Character Database. */
1513 static int glyph_class_table[] =
1514 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1515 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1516 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1517 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1518 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1519 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1520 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1521 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1522 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1523 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1524 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1525 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1526 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1527 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1528 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1529 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1530 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1531 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1532 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1533 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1534 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1535 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1536 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1537 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1538 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1539 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1540 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1541 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1542 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1544 static int get_class_def_auto (int c)
1546 static int table_size
1547 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1550 if (c >= glyph_class_table[table_size - 1])
1553 high = table_size - 1;
1556 mid = (low + high) / 2;
1557 if (c < glyph_class_table[mid])
1559 else if (c >= glyph_class_table[mid + 1])
1564 return ((mid % 2) ? 3 : 1);
1572 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1575 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1579 OTF_EncodingSubtable *sub;
1580 lookup_cmap_func lookupper;
1583 && OTF_get_table (otf, "cmap") < 0)
1587 if (cmap->table_index < 0)
1591 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1592 lookupper = lookup_cmap_func_table[sub->format / 2];
1594 for (i = 0; i < gstring->used; i++)
1595 if (! gstring->glyphs[i].glyph_id)
1597 int c = gstring->glyphs[i].c;
1598 if (c < 32 || ! cmap->unicode_table)
1599 gstring->glyphs[i].glyph_id = 0;
1600 else if (UVS_P (c) && i > 0)
1601 check_cmap_uvs (cmap, gstring, i);
1602 else if (c < 0x10000)
1603 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1605 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1612 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1613 int platform_id, int encoding_id)
1617 char *errfmt = "CMAP Looking up%s";
1619 OTF_EncodingRecord *enc;
1620 lookup_cmap_func lookupper;
1623 && OTF_get_table (otf, "cmap") < 0)
1627 for (i = 0; i < cmap->numTables; i++)
1628 if (cmap->EncodingRecord[i].platformID == platform_id
1629 && cmap->EncodingRecord[i].encodingID == encoding_id)
1631 if (i == cmap->numTables)
1632 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1633 enc = cmap->EncodingRecord + i;
1634 if (enc->subtable.format > 12)
1635 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1636 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1638 for (i = 0; i < gstring->used; i++)
1639 if (! gstring->glyphs[i].glyph_id)
1641 int c = gstring->glyphs[i].c;
1642 if (c < 32 || ! cmap->unicode_table)
1643 gstring->glyphs[i].glyph_id = 0;
1644 else if (UVS_P (c) && i > 0)
1645 check_cmap_uvs (cmap, gstring, i);
1646 else if (c < 0x10000)
1647 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1649 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1655 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1658 && OTF_get_table (otf, "cmap") < 0)
1661 || code > otf->cmap->max_glyph_id
1662 || ! otf->cmap->decode_table)
1664 return otf->cmap->decode_table[code];
1668 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1672 OTF_EncodingSubtable14 *sub14;
1674 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1676 && OTF_get_table (otf, "cmap") < 0)
1679 for (i = 0; i < cmap->numTables; i++)
1680 if (cmap->EncodingRecord[i].subtable.format == 14)
1682 if (i == cmap->numTables)
1684 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1685 for (i = 0, n = 0; i < 256; i++)
1687 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1689 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1697 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1703 && OTF_get_table (otf, "GDEF") < 0)
1707 if (gdef->glyph_class_def.offset)
1708 for (i = 0; i < gstring->used; i++)
1709 gstring->glyphs[i].GlyphClass
1710 = get_class_def (&gdef->glyph_class_def,
1711 gstring->glyphs[i].glyph_id);
1713 for (i = 0; i < gstring->used; i++)
1714 gstring->glyphs[i].GlyphClass
1715 = get_class_def_auto (gstring->glyphs[i].c);
1717 if (gdef->mark_attach_class_def.offset)
1718 for (i = 0; i < gstring->used; i++)
1719 gstring->glyphs[i].MarkAttachClass
1720 = get_class_def (&gdef->mark_attach_class_def,
1721 gstring->glyphs[i].glyph_id);
1727 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1728 const char *script, const char *language,
1729 const char *features,
1730 int alternate_subst, int with_log)
1732 char *errfmt = "GSUB driving%s";
1735 OTF_LangSys *LangSys;
1736 USHORT *lookup_flags;
1740 for (i = 0; i < gstring->used; i++)
1742 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1743 gstring->glyphs[i].positioning_type = 0;
1746 if (OTF_get_table (otf, "GSUB") < 0)
1749 if (gsub->FeatureList.FeatureCount == 0
1750 || gsub->LookupList.LookupCount == 0)
1753 LangSys = get_langsys (&gsub->ScriptList, script, language);
1757 lookup_flags = alloca (sizeof (USHORT) * gsub->LookupList.LookupCount);
1759 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1760 features, lookup_flags) < 0)
1761 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1763 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1768 if (! lookup_flags[i]) continue;
1770 if (gsub->LookupList.Lookup[i].LookupType != 8)
1773 while (gidx < gstring->used)
1775 int result = lookup_gsub (otf, &gsub->LookupList, i, gstring,
1776 gidx, alternate_subst);
1781 for (j = gidx; j < result; j++)
1782 gstring->glyphs[j].positioning_type
1783 = with_log ? (lookup_flags[i] << 4) : 0;
1792 gidx = gstring->used - 1;
1795 int result = lookup_gsub (otf, &gsub->LookupList, i, gstring,
1796 gidx, alternate_subst);
1801 for (j = gidx; j > result; j--)
1802 gstring->glyphs[j].positioning_type
1803 = with_log ? (lookup_flags[i] << 4) : 0;
1816 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1817 const char *script, const char *language, const char *features)
1820 OTF_get_table (otf, "cmap");
1821 return OTF_drive_gsub_internal (otf, gstring, script, language, features,
1826 OTF_drive_gsub_with_log (OTF *otf, OTF_GlyphString *gstring,
1827 const char *script, const char *language,
1828 const char *features)
1831 OTF_get_table (otf, "cmap");
1832 return OTF_drive_gsub_internal (otf, gstring, script, language, features,
1837 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1838 const char *script, const char *language,
1839 const char *features,
1840 int accumulate, int with_log)
1842 char *errfmt = "GPOS driving%s";
1845 OTF_LangSys *LangSys;
1846 USHORT *lookup_flags;
1849 for (i = 0; i < gstring->used; i++)
1850 gstring->glyphs[i].positioning_type = 0;
1852 if (OTF_get_table (otf, "GPOS") < 0)
1855 if (gpos->FeatureList.FeatureCount == 0
1856 || gpos->LookupList.LookupCount == 0)
1859 LangSys = get_langsys (&gpos->ScriptList, script, language);
1863 lookup_flags = alloca (sizeof (USHORT) * gpos->LookupList.LookupCount);
1865 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1866 features, lookup_flags) < 0)
1867 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1869 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1874 if (! lookup_flags[i]) continue;
1876 while (gidx < gstring->used)
1878 int result = lookup_gpos (&gpos->LookupList, i, gstring, gidx,
1884 for (j = gidx; j < result; j++)
1886 int positioning_type
1887 = gstring->glyphs[j].positioning_type & 0xF;
1889 if (with_log && positioning_type)
1890 gstring->glyphs[j].positioning_type
1891 = positioning_type | (lookup_flags[i] << 4);
1904 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1905 const char *script, const char *language, const char *features)
1908 OTF_get_table (otf, "cmap");
1909 return OTF_drive_gpos_internal (otf, gstring, script, language, features,
1914 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1915 const char *script, const char *language, const char *features)
1918 OTF_get_table (otf, "cmap");
1919 return OTF_drive_gpos_internal (otf, gstring, script, language, features,
1924 OTF_drive_gpos_with_log (OTF *otf, OTF_GlyphString *gstring,
1925 const char *script, const char *language,
1926 const char *features)
1929 OTF_get_table (otf, "cmap");
1930 return OTF_drive_gpos_internal (otf, gstring, script, language, features,
1935 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1936 const char *script, const char *language,
1937 const char *gsub_features, const char *gpos_features)
1939 if (OTF_drive_cmap (otf, gstring) < 0)
1941 if (OTF_drive_gdef (otf, gstring) < 0)
1944 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1947 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1953 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1954 const char *script, const char *language,
1955 const char *features)
1957 return OTF_drive_gsub_internal (otf, gstring, script, language, features,
1962 iterate_coverage (OTF *otf, const char *feature,
1963 OTF_Feature_Callback callback,
1964 OTF_Coverage *coverage)
1968 if (coverage->CoverageFormat == 1)
1970 for (i = 0; i < coverage->Count; i++)
1971 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1976 for (i = 0; i < coverage->Count; i++)
1978 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1980 for (id = range->Start; id <= range->End; id++)
1981 if (callback (otf, feature, id) < 0)
1989 iterate_feature (OTF *otf, const char *feature,
1990 OTF_Feature_Callback callback,
1995 for (i = 0; i < lookup->SubTableCount; i++)
1997 unsigned lookup_type = lookup->LookupType;
1998 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
2000 if (lookup_type == 7)
2002 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
2004 lookup_type = extension1->ExtensionLookupType;
2005 subtable = extension1->ExtensionSubtable;
2008 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
2010 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
2014 else if (lookup_type == 4)
2016 OTF_GSUB_Ligature1 *lig1;
2018 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
2021 lig1 = &subtable->u.ligature1;
2022 for (j = 0; j < lig1->LigSetCount; j++)
2024 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
2026 for (k = 0; k < ligset->LigatureCount; k++)
2028 OTF_Ligature *lig = ligset->Ligature + k;
2029 for (l = 0; l < lig->CompCount - 1; l++)
2030 if (callback (otf, feature, lig->Component[l]) < 0)
2035 else if (lookup_type == 6)
2037 if (subtable->Format == 1)
2039 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
2040 for (j = 0; j < context1->ChainRuleSetCount; j++)
2042 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
2043 for (k = 0; k < set->ChainRuleCount; k++)
2045 OTF_ChainRule *rule = set->ChainRule + k;
2046 for (l = 0; l < rule->LookupCount; l++)
2049 = (otf->gsub->LookupList.Lookup
2050 + rule->LookupRecord[l].LookupListIndex);
2051 if (iterate_feature (otf, feature, callback, lkup)
2058 else if (subtable->Format == 2)
2060 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
2062 for (j = 0; j < context2->ChainClassSetCnt; j++)
2064 OTF_ChainClassSet *set = context2->ChainClassSet + j;
2065 for (k = 0; k < set->ChainClassRuleCnt; j++)
2067 OTF_ChainClassRule *rule = set->ChainClassRule + k;
2069 for (l = 0; l < rule->LookupCount; l++)
2072 = (otf->gsub->LookupList.Lookup
2073 + rule->LookupRecord[k].LookupListIndex);
2074 if (iterate_feature (otf, feature, callback, lkup)
2083 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
2084 for (j = 0; j < context3->LookupCount; j++)
2087 = (otf->gsub->LookupList.Lookup
2088 + context3->LookupRecord[j].LookupListIndex);
2089 if (iterate_feature (otf, feature, callback, lkup) < 0)
2099 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2100 const char *script, const char *language,
2101 const char *feature)
2103 char *errfmt = "GSUB iterate feature%s";
2108 OTF_LangSys *langsys;
2109 USHORT *lookup_flags;
2111 if (OTF_get_table (otf, "GSUB") < 0)
2114 if (gsub->FeatureList.FeatureCount == 0
2115 || gsub->LookupList.LookupCount == 0)
2117 langsys = get_langsys (&gsub->ScriptList, script, language);
2120 lookup_flags = alloca (sizeof (USHORT) * gsub->LookupList.LookupCount);
2122 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2123 feature, lookup_flags) < 0)
2124 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2126 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2127 if (lookup_flags[i])
2128 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)