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;
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_ids_backward (OTF_GlyphString *gstring, int gidx, int flag,
290 int count, OTF_GlyphID *ids)
292 OTF_Glyph *gbeg = gstring->glyphs + gidx;
293 OTF_Glyph *gend = gstring->glyphs;
297 for (g = gbeg, i = 0; g >= gend && i < count; g--)
298 if (! IGNORED_GLYPH (g, flag) && g->glyph_id != ids[i++])
300 return (i < count ? -1 : gbeg - g);
304 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
307 int i = rule->BacktrackGlyphCount;
314 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
315 if (! IGNORED_GLYPH (g, flag) && --i == 0)
319 if (match_ids_backward (gstring, j, flag,
320 rule->BacktrackGlyphCount, rule->Backtrack)
325 i = match_ids (gstring, gidx, flag,
326 rule->InputGlyphCount - 1, rule->Input);
330 i = match_ids (gstring, gidx, flag,
331 rule->LookaheadGlyphCount, rule->LookAhead);
338 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
339 int flag, int count, unsigned *classes)
341 OTF_Glyph *gbeg = gstring->glyphs + gidx;
342 OTF_Glyph *gend = gstring->glyphs + gstring->used;
346 for (g = gbeg, i = 0; g < gend && i < count; g++)
347 if (! IGNORED_GLYPH (g, flag)
348 && get_class_def (class_def, g->glyph_id) != classes[i++])
350 return (i < count ? -1 : g - gbeg);
354 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
355 OTF_ClassDef *BacktrackClassDef,
356 OTF_ClassDef *InputClassDef,
357 OTF_ClassDef *LookaheadClassDef,
358 OTF_ChainClassRule *rule)
360 int i = rule->BacktrackGlyphCount;
367 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
368 if (! IGNORED_GLYPH (g, flag) && i-- == 0)
372 if (match_classes (BacktrackClassDef, gstring, j, flag,
373 rule->BacktrackGlyphCount, rule->Backtrack) < 0);
377 i = match_classes (InputClassDef, gstring, gidx, flag,
378 rule->InputGlyphCount - 1, rule->Input);
382 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
383 rule->LookaheadGlyphCount, rule->LookAhead);
391 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
392 OTF_Coverage *coverages)
394 OTF_Glyph *gbeg = gstring->glyphs + gidx;
395 OTF_Glyph *gend = gstring->glyphs + gstring->used;
399 for (g = gbeg, i = 0; g < gend && i < count; g++)
400 if (! IGNORED_GLYPH (g, flag)
401 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
403 return (i < count ? -1 : g - gbeg);
407 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
408 OTF_GSUB_ChainContext3 *context3)
410 int i = context3->BacktrackGlyphCount;
417 for (j = gidx - 1, g= gstring->glyphs +j; j >= 0; j--, g--)
418 if (! IGNORED_GLYPH (g, flag) && --i == 0)
422 if (match_coverages (gstring, j, flag, context3->BacktrackGlyphCount,
423 context3->Backtrack) < 0)
427 if (context3->InputGlyphCount > 1)
429 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
430 context3->Input + 1);
435 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
436 context3->LookAhead) < 0)
442 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
443 OTF_GlyphString *gstring, int gidx, int alternate_subst)
445 char *errfmt = "GSUB Looking up%s";
447 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
448 unsigned int flag = (lookup->LookupFlag
449 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
450 int orig_gidx = gidx;
451 OTF_Glyph *g = gstring->glyphs + gidx;
454 if (IGNORED_GLYPH (g, flag))
457 /* Try all subtables until one of them handles the current glyph. */
458 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
460 unsigned lookup_type = lookup->LookupType;
461 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
464 if (lookup_type == 7)
466 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
468 lookup_type = extension1->ExtensionLookupType;
469 subtable = extension1->ExtensionSubtable;
473 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
474 : (lookup_type == 3))
477 if (subtable->Coverage.offset)
479 coverage_idx = get_coverage_index (&subtable->Coverage,
481 if (coverage_idx < 0)
488 if (subtable->Format == 1)
489 g->glyph_id += subtable->u.single1.DeltaGlyphID;
491 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
496 if (subtable->Format == 1)
498 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
499 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
501 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
502 seq->Substitute, seq->GlyphCount);
503 gidx += seq->GlyphCount;
506 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
510 if (subtable->Format == 1)
512 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
513 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
515 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
516 altset->Alternate, altset->GlyphCount);
517 gidx += altset->GlyphCount;;
520 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
524 if (subtable->Format == 1)
526 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
527 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
531 for (j = 0; j < ligset->LigatureCount; j++)
535 lig = ligset->Ligature + j;
536 n = match_ids (gstring, gidx + 1, flag,
537 lig->CompCount - 1, lig->Component);
540 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
547 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
551 if (subtable->Format == 1)
553 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
554 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
559 for (j = 0; j < set->RuleCount; j++)
561 rule = set->Rule + j;
562 if (match_ids (gstring, gidx + 1, flag,
563 rule->GlyphCount - 1, rule->Input) < 0)
565 orig_used = gstring->used;
566 for (k = 0; k < rule->LookupCount; k++)
567 lookup_gsub (otf, lookup_list,
568 rule->LookupRecord[k].LookupListIndex,
570 gidx + rule->LookupRecord[k].SequenceIndex,
572 gidx += rule->GlyphCount + (gstring->used - orig_used);
576 else if (subtable->Format == 2)
578 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
585 class = get_class_def (&context2->ClassDef, g->glyph_id);
586 set = context2->ClassSet + class;
588 for (j = 0; j < set->ClassRuleCnt; j++)
590 rule = set->ClassRule + j;
591 if (match_classes (&context2->ClassDef,
592 gstring, gidx + 1, flag,
593 rule->GlyphCount - 1, rule->Class)
596 orig_used = gstring->used;
597 for (k = 0; k < rule->LookupCount; k++)
598 lookup_gsub (otf, lookup_list,
599 rule->LookupRecord[k].LookupListIndex,
601 gidx + rule->LookupRecord[k].SequenceIndex,
603 gidx += rule->GlyphCount + (gstring->used - orig_used);
607 else /* subtable->Format == 3 */
609 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
613 if (match_coverages (gstring, gidx + 1, flag,
614 context3->GlyphCount - 1,
615 context3->Coverage + 1) < 0)
617 orig_used = gstring->used;
618 for (j = 0; j < context3->LookupCount; j++)
619 lookup_gsub (otf, lookup_list,
620 context3->LookupRecord[j].LookupListIndex,
622 gidx + context3->LookupRecord[j].SequenceIndex,
624 gidx += context3->GlyphCount + (gstring->used - orig_used);
629 if (subtable->Format == 1)
631 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
632 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
636 for (j = 0; j < set->ChainRuleCount; j++)
638 OTF_ChainRule *rule = set->ChainRule + j;
640 if (gidx < rule->BacktrackGlyphCount
641 || (gidx + rule->InputGlyphCount
642 + rule->LookaheadGlyphCount) > gstring->used)
644 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
646 orig_used = gstring->used;
647 for (k = 0; k < rule->LookupCount; k++)
648 lookup_gsub (otf, lookup_list,
649 rule->LookupRecord[k].LookupListIndex,
651 gidx + rule->LookupRecord[k].SequenceIndex,
653 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
657 else if (subtable->Format == 2)
659 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
660 OTF_ChainClassSet *set;
665 class = get_class_def (&context2->InputClassDef, g->glyph_id);
666 set = context2->ChainClassSet + class;
667 for (j = 0; j < set->ChainClassRuleCnt; j++)
669 OTF_ChainClassRule *rule = set->ChainClassRule + j;
672 if (gidx < rule->BacktrackGlyphCount
673 || (gidx + rule->InputGlyphCount
674 + rule->LookaheadGlyphCount) > gstring->used)
676 if (match_chain_classes (gstring, gidx, flag,
677 &context2->BacktrackClassDef,
678 &context2->InputClassDef,
679 &context2->LookaheadClassDef,
682 orig_used = gstring->used;
683 for (k = 0; k < rule->LookupCount; k++)
684 lookup_gsub (otf, lookup_list,
685 rule->LookupRecord[k].LookupListIndex,
687 gidx + rule->LookupRecord[k].SequenceIndex,
689 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
695 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
699 if (gidx < context3->BacktrackGlyphCount
700 || (gidx + context3->InputGlyphCount
701 + context3->LookaheadGlyphCount) > gstring->used)
703 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
705 orig_used = gstring->used;
706 for (j = 0; j < context3->LookupCount; j++)
707 lookup_gsub (otf, lookup_list,
708 context3->LookupRecord[j].LookupListIndex,
710 gidx + context3->LookupRecord[j].SequenceIndex,
712 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
718 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
719 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
720 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
723 if (back_gidx > gstring->used || ahead_gidx < 0)
726 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
727 if (get_coverage_index (reverse->Backtrack + j,
728 gstring->glyphs[gidx + 1 + j].glyph_id)
731 if (j < reverse->BacktrackGlyphCount)
733 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
734 if (get_coverage_index (reverse->LookAhead + j,
735 gstring->glyphs[gidx - 1 - j].glyph_id)
738 if (j < reverse->LookaheadGlyphCount)
740 g->glyph_id = reverse->Substitute[coverage_idx];
748 if (gidx == orig_gidx)
758 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
761 int orig_gidx = gidx++;
763 while (gidx < gstring->used
764 && ! gstring->glyphs[gidx].glyph_id
765 && gstring->glyphs[gidx].positioning_type)
767 GSTRING_INSERT (gstring, gidx, 1);
768 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
769 gstring->glyphs[gidx].glyph_id = 0;
774 print_anchor (char *head, OTF_Anchor *anchor)
776 if (anchor->AnchorFormat == 1)
777 fprintf (stderr, " %s(X:%d Y:%d)", head,
778 anchor->XCoordinate, anchor->YCoordinate);
779 else if (anchor->AnchorFormat == 2)
780 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
781 anchor->XCoordinate, anchor->YCoordinate,
782 anchor->f.f1.AnchorPoint);
784 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
785 anchor->XCoordinate, anchor->YCoordinate);
789 print_glyph_positioning (OTF_Glyph *g, int type)
792 fprintf (stderr, " %0X=", g->glyph_id);
793 switch (g->positioning_type)
797 int format = g->f.f1.format;
799 if (format & OTF_XPlacement)
800 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
801 if (format & OTF_XPlaDevice)
802 fprintf (stderr, "+alpha");
803 if (format & OTF_YPlacement)
804 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
805 if (format & OTF_YPlaDevice)
806 fprintf (stderr, "+alpha");
807 if (format & OTF_XAdvance)
808 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
809 if (format & OTF_XAdvDevice)
810 fprintf (stderr, "+alpha");
814 print_anchor ("entry", g->f.f3.entry_anchor);
815 print_anchor ("exit", g->f.f3.entry_anchor);
818 print_anchor ("mark", g->f.f4.mark_anchor);
819 print_anchor ("base", g->f.f4.base_anchor);
822 print_anchor ("mark", g->f.f5.mark_anchor);
823 print_anchor ("lig", g->f.f5.ligature_anchor);
826 print_anchor ("mark1", g->f.f6.mark1_anchor);
827 print_anchor ("mark2", g->f.f6.mark2_anchor);
833 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
834 OTF_GlyphString *gstring, int gidx, int accumulate)
836 char *errfmt = "GPOS Looking up%s";
838 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
839 unsigned int flag = (lookup->LookupFlag
840 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
841 int orig_gidx = gidx;
842 OTF_Glyph *g = gstring->glyphs + gidx;
846 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
847 g->glyph_id, lookup_list_index);
848 if (IGNORED_GLYPH (g, flag))
851 fprintf (stderr, " glyph ignored\n");
855 /* Try all subtables until one of them handles the current glyph. */
856 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
858 unsigned lookup_type = lookup->LookupType;
859 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
861 int positioning_type;
862 enum OTF_ValueFormat format;
863 OTF_ValueRecord *value;
864 OTF_Anchor *anchor1, *anchor2;
866 if (lookup_type == 9)
868 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
870 lookup_type = extension1->ExtensionLookupType;
871 subtable = extension1->ExtensionSubtable;
875 fprintf (stderr, "/%d", lookup_type);
876 if (subtable->Coverage.offset)
878 coverage_idx = get_coverage_index (&subtable->Coverage,
880 if (coverage_idx < 0)
887 positioning_type = lookup_type;
888 if (subtable->Format == 1)
890 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
892 format = single1->ValueFormat;
893 value = &single1->Value;
895 else if (subtable->Format == 2)
897 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
899 format = single2->ValueFormat;
900 value = single2->Value + coverage_idx;
902 if (accumulate && g->positioning_type)
904 gidx = gstring_insert_for_gpos (gstring, gidx);
905 g = gstring->glyphs + gidx;
907 g->positioning_type = positioning_type;
908 g->f.f1.format = format;
909 g->f.f1.value = value;
911 print_glyph_positioning (g, 0);
920 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
921 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
922 next_gidx++, nextg++);
924 if (next_gidx >= gstring->used)
926 if (subtable->Format == 1)
928 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
929 OTF_PairSet *set = pair1->PairSet + coverage_idx;
932 for (j = 0; j < set->PairValueCount; j++)
933 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
935 if (pair1->ValueFormat1)
937 if (accumulate && g->positioning_type)
939 gidx = gstring_insert_for_gpos (gstring, gidx);
940 g = gstring->glyphs + gidx;
941 next_gidx += gidx - orig_gidx;
942 nextg = gstring->glyphs + next_gidx;
944 g->positioning_type = lookup_type;
945 g->f.f2.format = pair1->ValueFormat1;
946 g->f.f2.value = &set->PairValueRecord[j].Value1;
948 print_glyph_positioning (g, 1);
952 if (pair1->ValueFormat2)
954 if (accumulate && g->positioning_type)
956 gidx = gstring_insert_for_gpos (gstring, gidx);
957 g = gstring->glyphs + gidx;
959 g->positioning_type = lookup_type;
960 g->f.f2.format = pair1->ValueFormat2;
961 g->f.f2.value = &set->PairValueRecord[j].Value2;
963 print_glyph_positioning (g, 2);
968 else if (subtable->Format == 2)
970 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
971 unsigned class1, class2;
973 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
974 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
975 if (pair2->ValueFormat1)
977 if (accumulate && g->positioning_type)
979 gidx = gstring_insert_for_gpos (gstring, gidx);
980 g = gstring->glyphs + gidx;
981 next_gidx += gidx - orig_gidx;
982 nextg = gstring->glyphs + next_gidx;
984 g->positioning_type = lookup_type;
985 g->f.f2.format = pair2->ValueFormat1;
987 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
989 print_glyph_positioning (g, 1);
993 if (pair2->ValueFormat2)
995 if (accumulate && g->positioning_type)
997 gidx = gstring_insert_for_gpos (gstring, gidx);
998 g = gstring->glyphs + gidx;
1000 g->positioning_type = lookup_type;
1001 g->f.f2.format = pair2->ValueFormat2;
1003 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
1005 print_glyph_positioning (g, 2);
1013 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
1015 g->positioning_type = lookup_type;
1016 g->f.f3.entry_anchor
1017 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
1019 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
1021 print_glyph_positioning (g, 0);
1029 if (subtable->Format == 1)
1031 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
1032 OTF_MarkRecord *mark_record;
1033 OTF_AnchorRecord *base_record;
1035 int coverage_idx_base;
1036 unsigned int this_flag = flag | OTF_IgnoreMarks;
1039 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
1041 if (baseg < gstring->glyphs)
1044 = get_coverage_index (&mark_base1->BaseCoverage,
1046 if (coverage_idx_base < 0)
1048 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1050 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1051 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1053 = &base_record->Anchor[mark_record->Class];
1054 g->positioning_type = lookup_type;
1056 print_glyph_positioning (g, 0);
1064 if (subtable->Format == 1)
1066 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1068 int coverage_idx_lig;
1069 OTF_MarkRecord *mark_record;
1070 OTF_LigatureAttach *attach;
1071 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1074 for (j = 0; j < mark_lig1->ClassCount; j++)
1078 (ligg >= gstring->glyphs
1079 && (IGNORED_GLYPH (ligg, flag)
1080 || ligg->GlyphClass > OTF_GlyphClassLigature));
1082 if (ligg->positioning_type == 5
1083 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1084 num_class[ligg->MarkAttachClass]++;
1085 if (ligg < gstring->glyphs)
1088 = get_coverage_index (&mark_lig1->LigatureCoverage,
1090 if (coverage_idx_lig < 0)
1092 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1093 g->MarkAttachClass = mark_record->Class;
1094 attach = (mark_lig1->LigatureArray.LigatureAttach
1095 + coverage_idx_lig);
1096 for (j = 0; j < attach->ComponentCount; j++)
1098 OTF_Anchor *lig_anchor
1099 = attach->ComponentRecord[j].LigatureAnchor;
1101 if (lig_anchor[mark_record->Class].AnchorFormat
1102 && num_class[mark_record->Class]-- == 0)
1104 g->positioning_type = lookup_type;
1105 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1106 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1108 print_glyph_positioning (g, 0);
1119 if (subtable->Format == 1)
1121 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1122 OTF_MarkRecord *mark1_record;
1123 OTF_AnchorRecord *mark2_record;
1125 int coverage_idx_base;
1128 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1130 if (prevg < gstring->glyphs)
1133 = get_coverage_index (&mark_mark1->Mark2Coverage,
1135 if (coverage_idx_base < 0)
1137 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1139 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1140 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1141 g->f.f6.mark2_anchor
1142 = &mark2_record->Anchor[mark1_record->Class];
1143 g->positioning_type = lookup_type;
1145 print_glyph_positioning (g, 0);
1152 if (subtable->Format == 1)
1154 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1155 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1160 for (j = 0; j < set->RuleCount; j++)
1162 rule = set->Rule + j;
1163 if (match_ids (gstring, gidx + 1, flag,
1164 rule->GlyphCount - 1, rule->Input) < 0)
1166 orig_used = gstring->used;
1167 for (k = 0; k < rule->LookupCount; k++)
1168 lookup_gpos (lookup_list,
1169 rule->LookupRecord[k].LookupListIndex,
1171 gidx + rule->LookupRecord[k].SequenceIndex,
1173 gidx += rule->GlyphCount + (gstring->used - orig_used);
1177 else if (subtable->Format == 2)
1179 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1181 OTF_ClassRule *rule;
1186 class = get_class_def (&context2->ClassDef, g->glyph_id);
1187 set = context2->ClassSet + class;
1189 for (j = 0; j < set->ClassRuleCnt; j++)
1191 rule = set->ClassRule + j;
1192 if (match_classes (&context2->ClassDef,
1193 gstring, gidx + 1, flag,
1194 rule->GlyphCount - 1, rule->Class)
1197 orig_used = gstring->used;
1198 for (k = 0; k < rule->LookupCount; k++)
1199 lookup_gpos (lookup_list,
1200 rule->LookupRecord[k].LookupListIndex,
1202 gidx + rule->LookupRecord[k].SequenceIndex,
1204 gidx += rule->GlyphCount + (gstring->used - orig_used);
1208 else /* subtable->Format == 3 */
1210 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1214 if (match_coverages (gstring, gidx + 1, flag,
1215 context3->GlyphCount - 1,
1216 context3->Coverage + 1) < 0)
1218 orig_used = gstring->used;
1219 for (j = 0; j < context3->LookupCount; j++)
1220 lookup_gpos (lookup_list,
1221 context3->LookupRecord[j].LookupListIndex,
1223 gidx + context3->LookupRecord[j].SequenceIndex,
1225 gidx += context3->GlyphCount + (gstring->used - orig_used);
1230 if (subtable->Format == 1)
1232 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1233 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1237 for (j = 0; j < set->ChainRuleCount; j++)
1239 OTF_ChainRule *rule = set->ChainRule + j;
1241 if (gidx < rule->BacktrackGlyphCount
1242 || (gidx + rule->InputGlyphCount
1243 + rule->LookaheadGlyphCount) > gstring->used)
1245 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1247 orig_used = gstring->used;
1248 for (k = 0; k < rule->LookupCount; k++)
1249 lookup_gpos (lookup_list,
1250 rule->LookupRecord[k].LookupListIndex,
1252 gidx + rule->LookupRecord[k].SequenceIndex,
1254 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1258 else if (subtable->Format == 2)
1260 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1261 OTF_ChainClassSet *set;
1266 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1267 set = context2->ChainClassSet + class;
1268 for (j = 0; j < set->ChainClassRuleCnt; j++)
1270 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1273 if (gidx < rule->BacktrackGlyphCount
1274 || (gidx + rule->InputGlyphCount
1275 + rule->LookaheadGlyphCount) > gstring->used)
1277 if (match_chain_classes (gstring, gidx, flag,
1278 &context2->BacktrackClassDef,
1279 &context2->InputClassDef,
1280 &context2->LookaheadClassDef,
1283 orig_used = gstring->used;
1284 for (k = 0; k < rule->LookupCount; k++)
1285 lookup_gpos (lookup_list,
1286 rule->LookupRecord[k].LookupListIndex,
1288 gidx + rule->LookupRecord[k].SequenceIndex,
1290 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1294 else if (subtable->Format == 3)
1296 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1300 if (gidx < context3->BacktrackGlyphCount
1301 || (gidx + context3->InputGlyphCount
1302 + context3->LookaheadGlyphCount) > gstring->used)
1304 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1306 orig_used = gstring->used;
1307 for (j = 0; j < context3->LookupCount; j++)
1308 lookup_gpos (lookup_list,
1309 context3->LookupRecord[j].LookupListIndex,
1311 gidx + context3->LookupRecord[j].SequenceIndex,
1313 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1316 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1323 if (gidx == orig_gidx)
1326 fprintf (stderr, " no match\n");
1329 else if (debug_flag)
1330 fprintf (stderr, "\n");
1335 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1337 return ((c < 0 || c >= 256)
1339 : sub->f.f0->glyphIdArray[c]);
1343 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1349 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1352 OTF_EncodingSubtable4 *sub4;
1357 segCount = sub4->segCountX2 / 2;
1358 for (i = 0; i < segCount; i++)
1360 OTF_cmapSegment *seg = sub4->segments + i;
1362 if (c >= seg->startCount && c <= seg->endCount)
1364 if (seg->idRangeOffset == 0xFFFF)
1365 return c + seg->idDelta;
1367 return sub4->glyphIdArray[seg->idRangeOffset
1368 + (c - seg->startCount)];
1375 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1381 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1387 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1393 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1395 OTF_EncodingSubtable12 *sub12;
1396 OTF_cmapGroup *g, *gend;
1402 gend = sub12->Groups + sub12->nGroups;
1405 if (g->startCharCode <= c && c <= g->endCharCode)
1406 return (g->startGlyphID + (c - g->startCharCode));
1412 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1414 static lookup_cmap_func lookup_cmap_func_table[] =
1416 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1417 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1421 get_GlyphID (OTF_cmap *cmap, int c)
1423 OTF_EncodingSubtable *sub;
1424 lookup_cmap_func lookupper;
1426 if (c < 0x10000 && cmap->unicode_table)
1427 return cmap->unicode_table[c];
1428 if (cmap->table_index < 0)
1430 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1431 lookupper = lookup_cmap_func_table[sub->format / 2];
1432 return lookupper (c, sub);
1436 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1438 unsigned nRecords = sub14->nRecords;
1439 OTF_VariationSelectorRecord *record;
1442 for (i = 0; i < nRecords; i++)
1444 record = &sub14->Records[i];
1445 if (record->varSelector == c2)
1447 if (record->defaultUVSOffset)
1449 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1450 unsigned numUVRs = record->numUnicodeValueRanges;
1451 unsigned top = numUVRs, bottom = 0, middle;
1453 if (uVRs[0].startUnicodeValue <= c1)
1455 unsigned additionalCount, startUnicodeValue;
1459 middle = (top + bottom) / 2;
1460 if (c1 < uVRs[middle].startUnicodeValue)
1462 else if (bottom == middle)
1467 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1468 additionalCount = uVRs[bottom].additionalCount;
1469 if (c1 <= startUnicodeValue + additionalCount)
1470 return get_GlyphID (cmap, c1);
1473 if (record->nonDefaultUVSOffset)
1475 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1476 unsigned numUVSMs = record->numUVSMappings;
1477 unsigned top = numUVSMs, bottom = 0, middle;
1479 if (uvsMappings[0].unicodeValue <= c1)
1483 middle = (top + bottom) / 2;
1484 if (c1 < uvsMappings[middle].unicodeValue)
1486 else if (bottom == middle)
1491 if (uvsMappings[bottom].unicodeValue == c1)
1492 return uvsMappings[bottom].glyphID;
1502 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1504 OTF_EncodingSubtable14 *sub14;
1505 int c1 = gstring->glyphs[idx - 1].c;
1506 int c2 = gstring->glyphs[idx].c;
1510 gstring->glyphs[idx].glyph_id = 0;
1511 for (i = 0; i < cmap->numTables; i++)
1512 if (cmap->EncodingRecord[i].subtable.format == 14)
1514 if (i == cmap->numTables)
1516 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1519 gstring->glyphs[idx - 1].glyph_id = code;
1520 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1522 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1523 sizeof (OTF_Glyph) * (gstring->used - idx));
1529 /* Table of GlyphClass and MarkAttackClass.
1531 For the Nth element CHAR, CHAR and the succeeding characters
1532 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1534 This table is generated from the General Category (GC) property of
1535 characters defined in the Unicode Character Database. */
1537 static int glyph_class_table[] =
1538 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1539 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1540 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1541 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1542 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1543 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1544 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1545 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1546 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1547 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1548 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1549 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1550 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1551 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1552 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1553 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1554 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1555 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1556 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1557 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1558 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1559 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1560 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1561 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1562 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1563 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1564 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1565 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1566 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1568 static int get_class_def_auto (int c)
1570 static int table_size
1571 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1574 if (c >= glyph_class_table[table_size - 1])
1577 high = table_size - 1;
1580 mid = (low + high) / 2;
1581 if (c < glyph_class_table[mid])
1583 else if (c >= glyph_class_table[mid + 1])
1588 return ((mid % 2) ? 3 : 1);
1596 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1599 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1603 OTF_EncodingSubtable *sub;
1604 lookup_cmap_func lookupper;
1607 && OTF_get_table (otf, "cmap") < 0)
1611 if (cmap->table_index < 0)
1615 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1616 lookupper = lookup_cmap_func_table[sub->format / 2];
1618 for (i = 0; i < gstring->used; i++)
1619 if (! gstring->glyphs[i].glyph_id)
1621 int c = gstring->glyphs[i].c;
1622 if (c < 32 || ! cmap->unicode_table)
1623 gstring->glyphs[i].glyph_id = 0;
1624 else if (UVS_P (c) && i > 0)
1625 check_cmap_uvs (cmap, gstring, i);
1626 else if (c < 0x10000)
1627 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1629 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1636 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1637 int platform_id, int encoding_id)
1641 char *errfmt = "CMAP Looking up%s";
1643 OTF_EncodingRecord *enc;
1644 lookup_cmap_func lookupper;
1647 && OTF_get_table (otf, "cmap") < 0)
1651 for (i = 0; i < cmap->numTables; i++)
1652 if (cmap->EncodingRecord[i].platformID == platform_id
1653 && cmap->EncodingRecord[i].encodingID == encoding_id)
1655 if (i == cmap->numTables)
1656 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1657 enc = cmap->EncodingRecord + i;
1658 if (enc->subtable.format > 12)
1659 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1660 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1662 for (i = 0; i < gstring->used; i++)
1663 if (! gstring->glyphs[i].glyph_id)
1665 int c = gstring->glyphs[i].c;
1666 if (c < 32 || ! cmap->unicode_table)
1667 gstring->glyphs[i].glyph_id = 0;
1668 else if (UVS_P (c) && i > 0)
1669 check_cmap_uvs (cmap, gstring, i);
1670 else if (c < 0x10000)
1671 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1673 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1679 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1682 && OTF_get_table (otf, "cmap") < 0)
1685 || code > otf->cmap->max_glyph_id
1686 || ! otf->cmap->decode_table)
1688 return otf->cmap->decode_table[code];
1692 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1696 OTF_EncodingSubtable14 *sub14;
1698 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1700 && OTF_get_table (otf, "cmap") < 0)
1703 for (i = 0; i < cmap->numTables; i++)
1704 if (cmap->EncodingRecord[i].subtable.format == 14)
1706 if (i == cmap->numTables)
1708 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1709 for (i = 0, n = 0; i < 256; i++)
1711 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1713 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1721 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1727 && OTF_get_table (otf, "GDEF") < 0)
1731 if (gdef->glyph_class_def.offset)
1732 for (i = 0; i < gstring->used; i++)
1733 gstring->glyphs[i].GlyphClass
1734 = get_class_def (&gdef->glyph_class_def,
1735 gstring->glyphs[i].glyph_id);
1737 for (i = 0; i < gstring->used; i++)
1738 gstring->glyphs[i].GlyphClass
1739 = get_class_def_auto (gstring->glyphs[i].c);
1741 if (gdef->mark_attach_class_def.offset)
1742 for (i = 0; i < gstring->used; i++)
1743 gstring->glyphs[i].MarkAttachClass
1744 = get_class_def (&gdef->mark_attach_class_def,
1745 gstring->glyphs[i].glyph_id);
1751 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1752 const char *script, const char *language,
1753 const char *features,
1754 int alternate_subst)
1756 char *errfmt = "GSUB driving%s";
1759 OTF_LangSys *LangSys;
1763 for (i = 0; i < gstring->used; i++)
1765 gstring->glyphs[i].positioning_type = 0;
1766 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1769 if (OTF_get_table (otf, "GSUB") < 0)
1772 if (gsub->FeatureList.FeatureCount == 0
1773 || gsub->LookupList.LookupCount == 0)
1776 LangSys = get_langsys (&gsub->ScriptList, script, language);
1780 lookup_flags = alloca (gsub->LookupList.LookupCount);
1782 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1783 features, lookup_flags) < 0)
1784 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1786 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1790 if (! lookup_flags[i]) continue;
1792 if (gsub->LookupList.Lookup[i].LookupType != 8)
1795 while (gidx < gstring->used)
1797 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1805 gidx = gstring->used - 1;
1808 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1820 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1821 const char *script, const char *language, const char *features)
1824 OTF_get_table (otf, "cmap");
1825 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
1829 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1830 const char *script, const char *language,
1831 const char *features,
1834 char *errfmt = "GPOS driving%s";
1837 OTF_LangSys *LangSys;
1841 for (i = 0; i < gstring->used; i++)
1842 gstring->glyphs[i].positioning_type = 0;
1844 if (OTF_get_table (otf, "GPOS") < 0)
1847 if (gpos->FeatureList.FeatureCount == 0
1848 || gpos->LookupList.LookupCount == 0)
1851 LangSys = get_langsys (&gpos->ScriptList, script, language);
1855 lookup_flags = alloca (gpos->LookupList.LookupCount);
1857 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1858 features, lookup_flags) < 0)
1859 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1861 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1865 if (! lookup_flags[i]) continue;
1867 while (gidx < gstring->used)
1869 gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
1879 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1880 const char *script, const char *language, const char *features)
1883 OTF_get_table (otf, "cmap");
1884 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
1888 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1889 const char *script, const char *language, const char *features)
1892 OTF_get_table (otf, "cmap");
1893 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
1897 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1898 const char *script, const char *language,
1899 const char *gsub_features, const char *gpos_features)
1901 if (OTF_drive_cmap (otf, gstring) < 0)
1903 if (OTF_drive_gdef (otf, gstring) < 0)
1906 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1909 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1915 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1916 const char *script, const char *language,
1917 const char *features)
1919 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
1923 iterate_coverage (OTF *otf, const char *feature,
1924 OTF_Feature_Callback callback,
1925 OTF_Coverage *coverage)
1929 if (coverage->CoverageFormat == 1)
1931 for (i = 0; i < coverage->Count; i++)
1932 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1937 for (i = 0; i < coverage->Count; i++)
1939 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1941 for (id = range->Start; id <= range->End; id++)
1942 if (callback (otf, feature, id) < 0)
1950 iterate_feature (OTF *otf, const char *feature,
1951 OTF_Feature_Callback callback,
1956 for (i = 0; i < lookup->SubTableCount; i++)
1958 unsigned lookup_type = lookup->LookupType;
1959 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1961 if (lookup_type == 7)
1963 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
1965 lookup_type = extension1->ExtensionLookupType;
1966 subtable = extension1->ExtensionSubtable;
1969 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
1971 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1975 else if (lookup_type == 4)
1977 OTF_GSUB_Ligature1 *lig1;
1979 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1982 lig1 = &subtable->u.ligature1;
1983 for (j = 0; j < lig1->LigSetCount; j++)
1985 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
1987 for (k = 0; k < ligset->LigatureCount; k++)
1989 OTF_Ligature *lig = ligset->Ligature + k;
1990 for (l = 0; l < lig->CompCount - 1; l++)
1991 if (callback (otf, feature, lig->Component[l]) < 0)
1996 else if (lookup_type == 6)
1998 if (subtable->Format == 1)
2000 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
2001 for (j = 0; j < context1->ChainRuleSetCount; j++)
2003 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
2004 for (k = 0; k < set->ChainRuleCount; k++)
2006 OTF_ChainRule *rule = set->ChainRule + k;
2007 for (l = 0; l < rule->LookupCount; l++)
2010 = (otf->gsub->LookupList.Lookup
2011 + rule->LookupRecord[l].LookupListIndex);
2012 if (iterate_feature (otf, feature, callback, lkup)
2019 else if (subtable->Format == 2)
2021 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
2023 for (j = 0; j < context2->ChainClassSetCnt; j++)
2025 OTF_ChainClassSet *set = context2->ChainClassSet + j;
2026 for (k = 0; k < set->ChainClassRuleCnt; j++)
2028 OTF_ChainClassRule *rule = set->ChainClassRule + k;
2030 for (l = 0; l < rule->LookupCount; l++)
2033 = (otf->gsub->LookupList.Lookup
2034 + rule->LookupRecord[k].LookupListIndex);
2035 if (iterate_feature (otf, feature, callback, lkup)
2044 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
2045 for (j = 0; j < context3->LookupCount; j++)
2048 = (otf->gsub->LookupList.Lookup
2049 + context3->LookupRecord[j].LookupListIndex);
2050 if (iterate_feature (otf, feature, callback, lkup) < 0)
2060 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2061 const char *script, const char *language,
2062 const char *feature)
2064 char *errfmt = "GSUB iterate feature%s";
2069 OTF_LangSys *langsys;
2072 if (OTF_get_table (otf, "GSUB") < 0)
2075 if (gsub->FeatureList.FeatureCount == 0
2076 || gsub->LookupList.LookupCount == 0)
2078 langsys = get_langsys (&gsub->ScriptList, script, language);
2081 lookup_flags = alloca (gsub->LookupList.LookupCount);
2083 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2084 feature, lookup_flags) < 0)
2085 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2087 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2088 if (lookup_flags[i])
2089 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)