1 /* otfdrive.c -- OpenType font driver.
3 Copyright (C) 2003, 2004
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA. */
32 extern int debug_flag;
34 /* Return nonzero (-1 if ID is zero, 1 otherwise) if OTF_Glyph *G
35 should be ignored according to LookupFlag FLAG. */
36 #define IGNORED_GLYPH(g, flag) \
37 ((g)->glyph_id == 0 ? -1 \
38 : (((flag) & (1 << (g)->GlyphClass)) \
39 || (((flag) & OTF_MarkAttachmentType) \
40 && (g)->GlyphClass == OTF_GlyphClassMark \
41 && ((flag) >> 8) != (g)->MarkAttachClass)))
43 #define GSTRING_DELETE(gstring, from, len) \
45 memmove (gstring->glyphs + from, gstring->glyphs + from + len, \
46 sizeof (OTF_Glyph) * (gstring->used - from - len)); \
47 gstring->used -= len; \
51 #define GSTRING_INSERT(gstring, pos, len) \
53 if (gstring->used + len > gstring->size) \
55 char *errfmt = "GSTRING%s"; \
57 gstring->size = gstring->used + len; \
59 = (OTF_Glyph *) realloc (gstring->glyphs, \
60 sizeof (OTF_Glyph) * gstring->size); \
61 if (! gstring->glyphs) \
62 OTF_ERROR (OTF_ERROR_MEMORY, ""); \
64 memmove (gstring->glyphs + pos + len, gstring->glyphs + pos, \
65 sizeof (OTF_Glyph) * (gstring->used - pos)); \
66 gstring->used += len; \
70 static unsigned get_class_def (OTF_ClassDef *, OTF_GlyphID);
73 gstring_subst (OTF *otf, OTF_GlyphString *gstring, int from, int to, int flag,
74 OTF_GlyphID *ids, int num)
79 int from_idx = gstring->glyphs[from].f.index.from;
80 int to_idx = gstring->glyphs[to - 1].f.index.to;
83 for (i = non_ignored_idx = to - 1; i >= from; i--)
85 OTF_Glyph *g = gstring->glyphs + i;
87 if (IGNORED_GLYPH (g, flag) == 1)
89 /* Move this glyph to the next of the current target of
93 memmove (g, g + 1, sizeof (OTF_Glyph) * (non_ignored_idx - i));
94 temp.f.index.from = from_idx;
95 temp.f.index.to = to_idx;
96 gstring->glyphs[non_ignored_idx--] = temp;
102 GSTRING_INSERT (gstring, from, (num - len));
104 GSTRING_DELETE (gstring, from, (len - num));
105 for (i = 0; i < num; i++)
107 if (gstring->glyphs[from + i].glyph_id != ids[i])
109 gstring->glyphs[from + i].c = 0;
111 gstring->glyphs[from + i].GlyphClass
112 = get_class_def (&otf->gdef->glyph_class_def, ids[i]);
114 gstring->glyphs[from + i].GlyphClass = 0;
116 gstring->glyphs[from + i].glyph_id = ids[i];
117 gstring->glyphs[from + i].positioning_type = 0;
118 gstring->glyphs[from + i].f.index.from = from_idx;
119 gstring->glyphs[from + i].f.index.to = to_idx;
126 get_coverage_index (OTF_Coverage *coverage, OTF_GlyphID id)
130 if (coverage->CoverageFormat == 1)
132 for (i = 0; i < coverage->Count; i++)
133 if (coverage->table.GlyphArray[i] == id)
138 for (i = 0; i < coverage->Count; i++)
139 if (coverage->table.RangeRecord[i].Start <= id
140 && coverage->table.RangeRecord[i].End >= id)
141 return (coverage->table.RangeRecord[i].StartCoverageIndex
142 + (id - coverage->table.RangeRecord[i].Start));
148 get_class_def (OTF_ClassDef *class_def, OTF_GlyphID glyph_id)
150 if (class_def->ClassFormat == 1)
152 int idx = (int) glyph_id - (int) class_def->f.f1.StartGlyph;
154 if (idx >= 0 && idx < class_def->f.f1.GlyphCount)
155 return class_def->f.f1.ClassValueArray[idx];
161 for (i = 0; i < class_def->f.f2.ClassRangeCount; i++)
162 if (glyph_id >= class_def->f.f2.ClassRangeRecord[i].Start
163 && glyph_id <= class_def->f.f2.ClassRangeRecord[i].End)
164 return class_def->f.f2.ClassRangeRecord[i].Class;
170 get_langsys (OTF_ScriptList *script_list,
171 const char *script, const char *language)
174 OTF_Tag script_tag = OTF_tag (script);
175 OTF_Tag langsys_tag = OTF_tag (language);
177 OTF_Tag dflt_tag = OTF_tag ("DFLT");
178 OTF_Script *dflt = NULL;
180 for (i = 0; i < script_list->ScriptCount; i++)
182 OTF_Script *script = script_list->Script + i;
184 if (script_list->Script[i].ScriptTag == dflt_tag)
186 if (script_list->Script[i].ScriptTag == script_tag)
189 return &script->DefaultLangSys;
190 for (j = 0; j < script->LangSysCount; j++)
191 if (script->LangSysRecord[j].LangSysTag == langsys_tag)
192 return script->LangSys + j;
193 return &script->DefaultLangSys;
198 dflt = script_list->Script;
200 return &dflt->DefaultLangSys;
201 for (j = 0; j < dflt->LangSysCount; j++)
202 if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
203 return dflt->LangSys + j;
204 return &dflt->DefaultLangSys;
208 setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
209 OTF_LangSys *LangSys,
210 const char *features, char *lookup_flags)
213 OTF_Feature *feature;
214 int *feature_table = alloca (sizeof (int) * FeatureList->FeatureCount);
218 for (i = 0; i < FeatureList->FeatureCount; i++)
219 feature_table[i] = 0;
220 memset (lookup_flags, 0, LookupList->LookupCount);
228 if (*features == '*')
230 /* Consume all remaining features. */
231 for (i = 0; i < LangSys->FeatureCount; i++)
233 int index = LangSys->FeatureIndex[i];
235 if (! feature_table[index])
237 feature = FeatureList->Feature + index;
238 for (j = 0; j < feature->LookupCount; j++)
239 lookup_flags[feature->LookupListIndex[j]] = 1;
245 if (*features == '~')
246 use_it = -1, features++;
247 for (i = 0; *features && *features != ','; i++, features++)
248 tagname[i] = *features;
254 tag = OTF_tag (tagname);
255 for (i = 0; i < LangSys->FeatureCount; i++)
257 feature = FeatureList->Feature + LangSys->FeatureIndex[i];
258 if (tag == feature->FeatureTag)
260 if (feature_table[i])
263 for (j = 0; j < feature->LookupCount; j++)
264 lookup_flags[feature->LookupListIndex[j]] = 1;
265 feature_table[i] = use_it;
274 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
275 int count, OTF_GlyphID *ids)
277 OTF_Glyph *gbeg = gstring->glyphs + gidx;
278 OTF_Glyph *gend = gstring->glyphs + gstring->used;
282 for (g = gbeg, i = 0; g < gend && i < count; g++)
283 if (! IGNORED_GLYPH (g, flag) && g->glyph_id != ids[i++])
285 return (i < count ? -1 : g - gbeg);
289 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
292 int i = rule->BacktrackGlyphCount;
299 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
300 if (! IGNORED_GLYPH (g, flag) && --i == 0)
304 if (match_ids (gstring, j, flag,
305 rule->BacktrackGlyphCount, rule->Backtrack)
310 i = match_ids (gstring, gidx, flag,
311 rule->InputGlyphCount - 1, rule->Input);
315 i = match_ids (gstring, gidx, flag,
316 rule->LookaheadGlyphCount, rule->LookAhead);
323 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
324 int flag, int count, unsigned *classes)
326 OTF_Glyph *gbeg = gstring->glyphs + gidx;
327 OTF_Glyph *gend = gstring->glyphs + gstring->used;
331 for (g = gbeg, i = 0; g < gend && i < count; g++)
332 if (! IGNORED_GLYPH (g, flag)
333 && get_class_def (class_def, g->glyph_id) != classes[i++])
335 return (i < count ? -1 : g - gbeg);
339 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
340 OTF_ClassDef *BacktrackClassDef,
341 OTF_ClassDef *InputClassDef,
342 OTF_ClassDef *LookaheadClassDef,
343 OTF_ChainClassRule *rule)
345 int i = rule->BacktrackGlyphCount;
352 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
353 if (! IGNORED_GLYPH (g, flag) && i-- == 0)
357 if (match_classes (BacktrackClassDef, gstring, j, flag,
358 rule->BacktrackGlyphCount, rule->Backtrack) < 0);
362 i = match_classes (InputClassDef, gstring, gidx, flag,
363 rule->InputGlyphCount - 1, rule->Input);
367 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
368 rule->LookaheadGlyphCount, rule->LookAhead);
376 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
377 OTF_Coverage *coverages)
379 OTF_Glyph *gbeg = gstring->glyphs + gidx;
380 OTF_Glyph *gend = gstring->glyphs + gstring->used;
384 for (g = gbeg, i = 0; g < gend && i < count; g++)
385 if (! IGNORED_GLYPH (g, flag)
386 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
388 return (i < count ? -1 : g - gbeg);
392 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
393 OTF_GSUB_ChainContext3 *context3)
395 int i = context3->BacktrackGlyphCount;
402 for (j = gidx - 1, g= gstring->glyphs +j; j >= 0; j--, g--)
403 if (! IGNORED_GLYPH (g, flag) && --i == 0)
407 if (match_coverages (gstring, j, flag, context3->BacktrackGlyphCount,
408 context3->Backtrack) < 0)
412 if (context3->InputGlyphCount > 1)
414 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
415 context3->Input + 1);
420 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
421 context3->LookAhead) < 0)
427 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
428 OTF_GlyphString *gstring, int gidx, int alternate_subst)
430 char *errfmt = "GSUB Looking up%s";
432 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
433 unsigned int flag = (lookup->LookupFlag
434 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
435 int orig_gidx = gidx;
436 OTF_Glyph *g = gstring->glyphs + gidx;
439 if (IGNORED_GLYPH (g, flag))
442 /* Try all subtables until one of them handles the current glyph. */
443 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
445 unsigned lookup_type = lookup->LookupType;
446 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
449 if (lookup_type == 7)
451 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
453 lookup_type = extension1->ExtensionLookupType;
454 subtable = extension1->ExtensionSubtable;
458 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
459 : (lookup_type == 3))
462 if (subtable->Coverage.offset)
464 coverage_idx = get_coverage_index (&subtable->Coverage,
466 if (coverage_idx < 0)
473 if (subtable->Format == 1)
474 g->glyph_id += subtable->u.single1.DeltaGlyphID;
476 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
481 if (subtable->Format == 1)
483 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
484 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
486 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
487 seq->Substitute, seq->GlyphCount);
488 gidx += seq->GlyphCount;
491 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
495 if (subtable->Format == 1)
497 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
498 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
500 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
501 altset->Alternate, altset->GlyphCount);
502 gidx += altset->GlyphCount;;
505 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
509 if (subtable->Format == 1)
511 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
512 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
516 for (j = 0; j < ligset->LigatureCount; j++)
520 lig = ligset->Ligature + j;
521 n = match_ids (gstring, gidx + 1, flag,
522 lig->CompCount - 1, lig->Component);
525 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
532 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
536 if (subtable->Format == 1)
538 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
539 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
544 for (j = 0; j < set->RuleCount; j++)
546 rule = set->Rule + j;
547 if (match_ids (gstring, gidx + 1, flag,
548 rule->GlyphCount - 1, rule->Input) < 0)
550 orig_used = gstring->used;
551 for (k = 0; k < rule->LookupCount; k++)
552 lookup_gsub (otf, lookup_list,
553 rule->LookupRecord[k].LookupListIndex,
555 gidx + rule->LookupRecord[k].SequenceIndex,
557 gidx += rule->GlyphCount + (gstring->used - orig_used);
561 else if (subtable->Format == 2)
563 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
570 class = get_class_def (&context2->ClassDef, g->glyph_id);
571 set = context2->ClassSet + class;
573 for (j = 0; j < set->ClassRuleCnt; j++)
575 rule = set->ClassRule + j;
576 if (match_classes (&context2->ClassDef,
577 gstring, gidx + 1, flag,
578 rule->GlyphCount - 1, rule->Class)
581 orig_used = gstring->used;
582 for (k = 0; k < rule->LookupCount; k++)
583 lookup_gsub (otf, lookup_list,
584 rule->LookupRecord[k].LookupListIndex,
586 gidx + rule->LookupRecord[k].SequenceIndex,
588 gidx += rule->GlyphCount + (gstring->used - orig_used);
592 else /* subtable->Format == 3 */
594 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
598 if (match_coverages (gstring, gidx + 1, flag,
599 context3->GlyphCount - 1,
600 context3->Coverage + 1) < 0)
602 orig_used = gstring->used;
603 for (j = 0; j < context3->LookupCount; j++)
604 lookup_gsub (otf, lookup_list,
605 context3->LookupRecord[j].LookupListIndex,
607 gidx + context3->LookupRecord[j].SequenceIndex,
609 gidx += context3->GlyphCount + (gstring->used - orig_used);
614 if (subtable->Format == 1)
616 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
617 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
621 for (j = 0; j < set->ChainRuleCount; j++)
623 OTF_ChainRule *rule = set->ChainRule + j;
625 if (gidx < rule->BacktrackGlyphCount
626 || (gidx + rule->InputGlyphCount
627 + rule->LookaheadGlyphCount) > gstring->used)
629 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
631 orig_used = gstring->used;
632 for (k = 0; k < rule->LookupCount; k++)
633 lookup_gsub (otf, lookup_list,
634 rule->LookupRecord[k].LookupListIndex,
636 gidx + rule->LookupRecord[k].SequenceIndex,
638 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
642 else if (subtable->Format == 2)
644 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
645 OTF_ChainClassSet *set;
650 class = get_class_def (&context2->InputClassDef, g->glyph_id);
651 set = context2->ChainClassSet + class;
652 for (j = 0; j < set->ChainClassRuleCnt; j++)
654 OTF_ChainClassRule *rule = set->ChainClassRule + j;
657 if (gidx < rule->BacktrackGlyphCount
658 || (gidx + rule->InputGlyphCount
659 + rule->LookaheadGlyphCount) > gstring->used)
661 if (match_chain_classes (gstring, gidx, flag,
662 &context2->BacktrackClassDef,
663 &context2->InputClassDef,
664 &context2->LookaheadClassDef,
667 orig_used = gstring->used;
668 for (k = 0; k < rule->LookupCount; k++)
669 lookup_gsub (otf, lookup_list,
670 rule->LookupRecord[k].LookupListIndex,
672 gidx + rule->LookupRecord[k].SequenceIndex,
674 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
680 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
684 if (gidx < context3->BacktrackGlyphCount
685 || (gidx + context3->InputGlyphCount
686 + context3->LookaheadGlyphCount) > gstring->used)
688 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
690 orig_used = gstring->used;
691 for (j = 0; j < context3->LookupCount; j++)
692 lookup_gsub (otf, lookup_list,
693 context3->LookupRecord[j].LookupListIndex,
695 gidx + context3->LookupRecord[j].SequenceIndex,
697 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
703 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
704 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
705 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
708 if (back_gidx > gstring->used || ahead_gidx < 0)
711 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
712 if (get_coverage_index (reverse->Backtrack + j,
713 gstring->glyphs[gidx + 1 + j].glyph_id)
716 if (j < reverse->BacktrackGlyphCount)
718 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
719 if (get_coverage_index (reverse->LookAhead + j,
720 gstring->glyphs[gidx - 1 - j].glyph_id)
723 if (j < reverse->LookaheadGlyphCount)
725 g->glyph_id = reverse->Substitute[coverage_idx];
733 if (gidx == orig_gidx)
743 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
746 int orig_gidx = gidx++;
748 while (gidx < gstring->used
749 && ! gstring->glyphs[gidx].glyph_id
750 && gstring->glyphs[gidx].positioning_type)
752 GSTRING_INSERT (gstring, gidx, 1);
753 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
754 gstring->glyphs[gidx].glyph_id = 0;
759 print_anchor (char *head, OTF_Anchor *anchor)
761 if (anchor->AnchorFormat == 1)
762 fprintf (stderr, " %s(X:%d Y:%d)", head,
763 anchor->XCoordinate, anchor->YCoordinate);
764 else if (anchor->AnchorFormat == 2)
765 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
766 anchor->XCoordinate, anchor->YCoordinate,
767 anchor->f.f1.AnchorPoint);
769 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
770 anchor->XCoordinate, anchor->YCoordinate);
774 print_glyph_positioning (OTF_Glyph *g, int type)
777 fprintf (stderr, " %0X=", g->glyph_id);
778 switch (g->positioning_type)
782 int format = g->f.f1.format;
784 if (format & OTF_XPlacement)
785 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
786 if (format & OTF_XPlaDevice)
787 fprintf (stderr, "+alpha");
788 if (format & OTF_YPlacement)
789 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
790 if (format & OTF_YPlaDevice)
791 fprintf (stderr, "+alpha");
792 if (format & OTF_XAdvance)
793 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
794 if (format & OTF_XAdvDevice)
795 fprintf (stderr, "+alpha");
799 print_anchor ("entry", g->f.f3.entry_anchor);
800 print_anchor ("exit", g->f.f3.entry_anchor);
803 print_anchor ("mark", g->f.f4.mark_anchor);
804 print_anchor ("base", g->f.f4.base_anchor);
807 print_anchor ("mark", g->f.f5.mark_anchor);
808 print_anchor ("lig", g->f.f5.ligature_anchor);
811 print_anchor ("mark1", g->f.f6.mark1_anchor);
812 print_anchor ("mark2", g->f.f6.mark2_anchor);
818 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
819 OTF_GlyphString *gstring, int gidx, int accumulate)
821 char *errfmt = "GPOS Looking up%s";
823 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
824 unsigned int flag = (lookup->LookupFlag
825 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
826 int orig_gidx = gidx;
827 OTF_Glyph *g = gstring->glyphs + gidx;
831 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
832 g->glyph_id, lookup_list_index);
833 if (IGNORED_GLYPH (g, flag))
836 fprintf (stderr, " glyph ignored\n");
840 /* Try all subtables until one of them handles the current glyph. */
841 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
843 unsigned lookup_type = lookup->LookupType;
844 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
846 int positioning_type;
847 enum OTF_ValueFormat format;
848 OTF_ValueRecord *value;
849 OTF_Anchor *anchor1, *anchor2;
851 if (lookup_type == 9)
853 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
855 lookup_type = extension1->ExtensionLookupType;
856 subtable = extension1->ExtensionSubtable;
860 fprintf (stderr, "/%d", lookup_type);
861 if (subtable->Coverage.offset)
863 coverage_idx = get_coverage_index (&subtable->Coverage,
865 if (coverage_idx < 0)
872 positioning_type = lookup_type;
873 if (subtable->Format == 1)
875 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
877 format = single1->ValueFormat;
878 value = &single1->Value;
880 else if (subtable->Format == 2)
882 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
884 format = single2->ValueFormat;
885 value = single2->Value + coverage_idx;
887 if (accumulate && g->positioning_type)
889 gidx = gstring_insert_for_gpos (gstring, gidx);
890 g = gstring->glyphs + gidx;
892 g->positioning_type = positioning_type;
893 g->f.f1.format = format;
894 g->f.f1.value = value;
896 print_glyph_positioning (g, 0);
905 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
906 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
907 next_gidx++, nextg++);
909 if (next_gidx >= gstring->used)
911 if (subtable->Format == 1)
913 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
914 OTF_PairSet *set = pair1->PairSet + coverage_idx;
917 for (j = 0; j < set->PairValueCount; j++)
918 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
920 if (pair1->ValueFormat1)
922 if (accumulate && g->positioning_type)
924 gidx = gstring_insert_for_gpos (gstring, gidx);
925 g = gstring->glyphs + gidx;
926 next_gidx += gidx - orig_gidx;
927 nextg = gstring->glyphs + next_gidx;
929 g->positioning_type = lookup_type;
930 g->f.f2.format = pair1->ValueFormat1;
931 g->f.f2.value = &set->PairValueRecord[j].Value1;
933 print_glyph_positioning (g, 1);
937 if (pair1->ValueFormat2)
939 if (accumulate && g->positioning_type)
941 gidx = gstring_insert_for_gpos (gstring, gidx);
942 g = gstring->glyphs + gidx;
944 g->positioning_type = lookup_type;
945 g->f.f2.format = pair1->ValueFormat2;
946 g->f.f2.value = &set->PairValueRecord[j].Value2;
948 print_glyph_positioning (g, 2);
953 else if (subtable->Format == 2)
955 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
956 unsigned class1, class2;
958 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
959 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
960 if (pair2->ValueFormat1)
962 if (accumulate && g->positioning_type)
964 gidx = gstring_insert_for_gpos (gstring, gidx);
965 g = gstring->glyphs + gidx;
966 next_gidx += gidx - orig_gidx;
967 nextg = gstring->glyphs + next_gidx;
969 g->positioning_type = lookup_type;
970 g->f.f2.format = pair2->ValueFormat1;
972 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
974 print_glyph_positioning (g, 1);
978 if (pair2->ValueFormat2)
980 if (accumulate && g->positioning_type)
982 gidx = gstring_insert_for_gpos (gstring, gidx);
983 g = gstring->glyphs + gidx;
985 g->positioning_type = lookup_type;
986 g->f.f2.format = pair2->ValueFormat2;
988 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
990 print_glyph_positioning (g, 2);
998 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
1000 g->positioning_type = lookup_type;
1001 g->f.f3.entry_anchor
1002 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
1004 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
1006 print_glyph_positioning (g, 0);
1014 if (subtable->Format == 1)
1016 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
1017 OTF_MarkRecord *mark_record;
1018 OTF_AnchorRecord *base_record;
1020 int coverage_idx_base;
1021 unsigned int this_flag = flag | OTF_IgnoreMarks;
1024 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
1026 if (baseg < gstring->glyphs)
1029 = get_coverage_index (&mark_base1->BaseCoverage,
1031 if (coverage_idx_base < 0)
1033 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1035 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1036 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1038 = &base_record->Anchor[mark_record->Class];
1039 g->positioning_type = lookup_type;
1041 print_glyph_positioning (g, 0);
1049 if (subtable->Format == 1)
1051 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1053 int coverage_idx_lig;
1054 OTF_MarkRecord *mark_record;
1055 OTF_LigatureAttach *attach;
1056 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1059 for (j = 0; j < mark_lig1->ClassCount; j++)
1063 (ligg >= gstring->glyphs
1064 && (IGNORED_GLYPH (ligg, flag)
1065 || ligg->GlyphClass > OTF_GlyphClassLigature));
1067 if (ligg->positioning_type == 5
1068 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1069 num_class[ligg->MarkAttachClass]++;
1070 if (ligg < gstring->glyphs)
1073 = get_coverage_index (&mark_lig1->LigatureCoverage,
1075 if (coverage_idx_lig < 0)
1077 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1078 g->MarkAttachClass = mark_record->Class;
1079 attach = (mark_lig1->LigatureArray.LigatureAttach
1080 + coverage_idx_lig);
1081 for (j = 0; j < attach->ComponentCount; j++)
1083 OTF_Anchor *lig_anchor
1084 = attach->ComponentRecord[j].LigatureAnchor;
1086 if (lig_anchor[mark_record->Class].AnchorFormat
1087 && num_class[mark_record->Class]-- == 0)
1089 g->positioning_type = lookup_type;
1090 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1091 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1093 print_glyph_positioning (g, 0);
1104 if (subtable->Format == 1)
1106 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1107 OTF_MarkRecord *mark1_record;
1108 OTF_AnchorRecord *mark2_record;
1110 int coverage_idx_base;
1113 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1115 if (prevg < gstring->glyphs)
1118 = get_coverage_index (&mark_mark1->Mark2Coverage,
1120 if (coverage_idx_base < 0)
1122 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1124 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1125 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1126 g->f.f6.mark2_anchor
1127 = &mark2_record->Anchor[mark1_record->Class];
1128 g->positioning_type = lookup_type;
1130 print_glyph_positioning (g, 0);
1137 if (subtable->Format == 1)
1139 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1140 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1145 for (j = 0; j < set->RuleCount; j++)
1147 rule = set->Rule + j;
1148 if (match_ids (gstring, gidx + 1, flag,
1149 rule->GlyphCount - 1, rule->Input) < 0)
1151 orig_used = gstring->used;
1152 for (k = 0; k < rule->LookupCount; k++)
1153 lookup_gpos (lookup_list,
1154 rule->LookupRecord[k].LookupListIndex,
1156 gidx + rule->LookupRecord[k].SequenceIndex,
1158 gidx += rule->GlyphCount + (gstring->used - orig_used);
1162 else if (subtable->Format == 2)
1164 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1166 OTF_ClassRule *rule;
1171 class = get_class_def (&context2->ClassDef, g->glyph_id);
1172 set = context2->ClassSet + class;
1174 for (j = 0; j < set->ClassRuleCnt; j++)
1176 rule = set->ClassRule + j;
1177 if (match_classes (&context2->ClassDef,
1178 gstring, gidx + 1, flag,
1179 rule->GlyphCount - 1, rule->Class)
1182 orig_used = gstring->used;
1183 for (k = 0; k < rule->LookupCount; k++)
1184 lookup_gpos (lookup_list,
1185 rule->LookupRecord[k].LookupListIndex,
1187 gidx + rule->LookupRecord[k].SequenceIndex,
1189 gidx += rule->GlyphCount + (gstring->used - orig_used);
1193 else /* subtable->Format == 3 */
1195 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1199 if (match_coverages (gstring, gidx + 1, flag,
1200 context3->GlyphCount - 1,
1201 context3->Coverage + 1) < 0)
1203 orig_used = gstring->used;
1204 for (j = 0; j < context3->LookupCount; j++)
1205 lookup_gpos (lookup_list,
1206 context3->LookupRecord[j].LookupListIndex,
1208 gidx + context3->LookupRecord[j].SequenceIndex,
1210 gidx += context3->GlyphCount + (gstring->used - orig_used);
1215 if (subtable->Format == 1)
1217 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1218 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1222 for (j = 0; j < set->ChainRuleCount; j++)
1224 OTF_ChainRule *rule = set->ChainRule + j;
1226 if (gidx < rule->BacktrackGlyphCount
1227 || (gidx + rule->InputGlyphCount
1228 + rule->LookaheadGlyphCount) > gstring->used)
1230 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1232 orig_used = gstring->used;
1233 for (k = 0; k < rule->LookupCount; k++)
1234 lookup_gpos (lookup_list,
1235 rule->LookupRecord[k].LookupListIndex,
1237 gidx + rule->LookupRecord[k].SequenceIndex,
1239 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1243 else if (subtable->Format == 2)
1245 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1246 OTF_ChainClassSet *set;
1251 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1252 set = context2->ChainClassSet + class;
1253 for (j = 0; j < set->ChainClassRuleCnt; j++)
1255 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1258 if (gidx < rule->BacktrackGlyphCount
1259 || (gidx + rule->InputGlyphCount
1260 + rule->LookaheadGlyphCount) > gstring->used)
1262 if (match_chain_classes (gstring, gidx, flag,
1263 &context2->BacktrackClassDef,
1264 &context2->InputClassDef,
1265 &context2->LookaheadClassDef,
1268 orig_used = gstring->used;
1269 for (k = 0; k < rule->LookupCount; k++)
1270 lookup_gpos (lookup_list,
1271 rule->LookupRecord[k].LookupListIndex,
1273 gidx + rule->LookupRecord[k].SequenceIndex,
1275 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1279 else if (subtable->Format == 3)
1281 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1285 if (gidx < context3->BacktrackGlyphCount
1286 || (gidx + context3->InputGlyphCount
1287 + context3->LookaheadGlyphCount) > gstring->used)
1289 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1291 orig_used = gstring->used;
1292 for (j = 0; j < context3->LookupCount; j++)
1293 lookup_gpos (lookup_list,
1294 context3->LookupRecord[j].LookupListIndex,
1296 gidx + context3->LookupRecord[j].SequenceIndex,
1298 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1301 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1308 if (gidx == orig_gidx)
1311 fprintf (stderr, " no match\n");
1314 else if (debug_flag)
1315 fprintf (stderr, "\n");
1320 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1322 return ((c < 0 || c >= 256)
1324 : sub->f.f0->glyphIdArray[c]);
1328 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1334 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1337 OTF_EncodingSubtable4 *sub4;
1342 segCount = sub4->segCountX2 / 2;
1343 for (i = 0; i < segCount; i++)
1345 OTF_cmapSegment *seg = sub4->segments + i;
1347 if (c >= seg->startCount && c <= seg->endCount)
1349 if (seg->idRangeOffset == 0xFFFF)
1350 return c + seg->idDelta;
1352 return sub4->glyphIdArray[seg->idRangeOffset
1353 + (c - seg->startCount)];
1360 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1366 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1372 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1378 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1380 OTF_EncodingSubtable12 *sub12;
1381 OTF_cmapGroup *g, *gend;
1387 gend = sub12->Groups + sub12->nGroups;
1390 if (g->startCharCode <= c && c <= g->endCharCode)
1391 return (g->startGlyphID + (c - g->startCharCode));
1397 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1399 static lookup_cmap_func lookup_cmap_func_table[] =
1401 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1402 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1406 get_GlyphID (OTF_cmap *cmap, int c)
1408 OTF_EncodingSubtable *sub;
1409 lookup_cmap_func lookupper;
1411 if (c < 0x10000 && cmap->unicode_table)
1412 return cmap->unicode_table[c];
1413 if (cmap->table_index < 0)
1415 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1416 lookupper = lookup_cmap_func_table[sub->format / 2];
1417 return lookupper (c, sub);
1421 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1423 unsigned nRecords = sub14->nRecords;
1424 OTF_VariationSelectorRecord *record;
1427 for (i = 0; i < nRecords; i++)
1429 record = &sub14->Records[i];
1430 if (record->varSelector == c2)
1432 if (record->defaultUVSOffset)
1434 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1435 unsigned numUVRs = record->numUnicodeValueRanges;
1436 unsigned top = numUVRs, bottom = 0, middle;
1438 if (uVRs[0].startUnicodeValue <= c1)
1440 unsigned additionalCount, startUnicodeValue;
1444 middle = (top + bottom) / 2;
1445 if (c1 < uVRs[middle].startUnicodeValue)
1447 else if (bottom == middle)
1452 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1453 additionalCount = uVRs[bottom].additionalCount;
1454 if (c1 <= startUnicodeValue + additionalCount)
1455 return get_GlyphID (cmap, c1);
1458 if (record->nonDefaultUVSOffset)
1460 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1461 unsigned numUVSMs = record->numUVSMappings;
1462 unsigned top = numUVSMs, bottom = 0, middle;
1464 if (uvsMappings[0].unicodeValue <= c1)
1468 middle = (top + bottom) / 2;
1469 if (c1 < uvsMappings[middle].unicodeValue)
1471 else if (bottom == middle)
1476 if (uvsMappings[bottom].unicodeValue == c1)
1477 return uvsMappings[bottom].glyphID;
1487 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1489 OTF_EncodingSubtable14 *sub14;
1490 int c1 = gstring->glyphs[idx - 1].c;
1491 int c2 = gstring->glyphs[idx].c;
1495 gstring->glyphs[idx].glyph_id = 0;
1496 for (i = 0; i < cmap->numTables; i++)
1497 if (cmap->EncodingRecord[i].subtable.format == 14)
1499 if (i == cmap->numTables)
1501 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1504 gstring->glyphs[idx - 1].glyph_id = code;
1505 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1507 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1508 sizeof (OTF_Glyph) * (gstring->used - idx));
1514 /* Table of GlyphClass and MarkAttackClass.
1516 For the Nth element CHAR, CHAR and the succeeding characters
1517 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1519 This table is generated from the General Category (GC) property of
1520 characters defined in the Unicode Character Database. */
1522 static int glyph_class_table[] =
1523 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1524 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1525 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1526 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1527 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1528 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1529 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1530 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1531 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1532 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1533 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1534 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1535 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1536 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1537 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1538 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1539 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1540 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1541 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1542 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1543 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1544 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1545 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1546 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1547 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1548 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1549 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1550 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1551 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1553 static int get_class_def_auto (int c)
1555 static int table_size
1556 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1559 if (c >= glyph_class_table[table_size - 1])
1562 high = table_size - 1;
1565 mid = (low + high) / 2;
1566 if (c < glyph_class_table[mid])
1568 else if (c >= glyph_class_table[mid + 1])
1573 return ((mid % 2) ? 3 : 1);
1581 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1584 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1588 OTF_EncodingSubtable *sub;
1589 lookup_cmap_func lookupper;
1592 && OTF_get_table (otf, "cmap") < 0)
1596 if (cmap->table_index < 0)
1600 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1601 lookupper = lookup_cmap_func_table[sub->format / 2];
1603 for (i = 0; i < gstring->used; i++)
1604 if (! gstring->glyphs[i].glyph_id)
1606 int c = gstring->glyphs[i].c;
1607 if (c < 32 || ! cmap->unicode_table)
1608 gstring->glyphs[i].glyph_id = 0;
1609 else if (UVS_P (c) && i > 0)
1610 check_cmap_uvs (cmap, gstring, i);
1611 else if (c < 0x10000)
1612 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1614 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1621 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1622 int platform_id, int encoding_id)
1626 char *errfmt = "CMAP Looking up%s";
1628 OTF_EncodingRecord *enc;
1629 lookup_cmap_func lookupper;
1632 && OTF_get_table (otf, "cmap") < 0)
1636 for (i = 0; i < cmap->numTables; i++)
1637 if (cmap->EncodingRecord[i].platformID == platform_id
1638 && cmap->EncodingRecord[i].encodingID == encoding_id)
1640 if (i == cmap->numTables)
1641 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1642 enc = cmap->EncodingRecord + i;
1643 if (enc->subtable.format > 12)
1644 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1645 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1647 for (i = 0; i < gstring->used; i++)
1648 if (! gstring->glyphs[i].glyph_id)
1650 int c = gstring->glyphs[i].c;
1651 if (c < 32 || ! cmap->unicode_table)
1652 gstring->glyphs[i].glyph_id = 0;
1653 else if (UVS_P (c) && i > 0)
1654 check_cmap_uvs (cmap, gstring, i);
1655 else if (c < 0x10000)
1656 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1658 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1664 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1667 && OTF_get_table (otf, "cmap") < 0)
1670 || code > otf->cmap->max_glyph_id
1671 || ! otf->cmap->decode_table)
1673 return otf->cmap->decode_table[code];
1677 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1681 OTF_EncodingSubtable14 *sub14;
1683 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1685 && OTF_get_table (otf, "cmap") < 0)
1688 for (i = 0; i < cmap->numTables; i++)
1689 if (cmap->EncodingRecord[i].subtable.format == 14)
1691 if (i == cmap->numTables)
1693 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1694 for (i = 0, n = 0; i < 256; i++)
1696 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1698 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1706 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1712 && OTF_get_table (otf, "GDEF") < 0)
1716 if (gdef->glyph_class_def.offset)
1717 for (i = 0; i < gstring->used; i++)
1718 gstring->glyphs[i].GlyphClass
1719 = get_class_def (&gdef->glyph_class_def,
1720 gstring->glyphs[i].glyph_id);
1722 for (i = 0; i < gstring->used; i++)
1723 gstring->glyphs[i].GlyphClass
1724 = get_class_def_auto (gstring->glyphs[i].c);
1726 if (gdef->mark_attach_class_def.offset)
1727 for (i = 0; i < gstring->used; i++)
1728 gstring->glyphs[i].MarkAttachClass
1729 = get_class_def (&gdef->mark_attach_class_def,
1730 gstring->glyphs[i].glyph_id);
1736 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1737 const char *script, const char *language,
1738 const char *features,
1739 int alternate_subst)
1741 char *errfmt = "GSUB driving%s";
1744 OTF_LangSys *LangSys;
1748 for (i = 0; i < gstring->used; i++)
1750 gstring->glyphs[i].positioning_type = 0;
1751 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1754 if (OTF_get_table (otf, "GSUB") < 0)
1757 if (gsub->FeatureList.FeatureCount == 0
1758 || gsub->LookupList.LookupCount == 0)
1761 LangSys = get_langsys (&gsub->ScriptList, script, language);
1765 lookup_flags = alloca (gsub->LookupList.LookupCount);
1767 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1768 features, lookup_flags) < 0)
1769 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1771 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1775 if (! lookup_flags[i]) continue;
1777 if (gsub->LookupList.Lookup[i].LookupType != 8)
1780 while (gidx < gstring->used)
1782 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1790 gidx = gstring->used - 1;
1793 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1805 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1806 const char *script, const char *language, const char *features)
1809 OTF_get_table (otf, "cmap");
1810 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
1814 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1815 const char *script, const char *language,
1816 const char *features,
1819 char *errfmt = "GPOS driving%s";
1822 OTF_LangSys *LangSys;
1826 for (i = 0; i < gstring->used; i++)
1827 gstring->glyphs[i].positioning_type = 0;
1829 if (OTF_get_table (otf, "GPOS") < 0)
1832 if (gpos->FeatureList.FeatureCount == 0
1833 || gpos->LookupList.LookupCount == 0)
1836 LangSys = get_langsys (&gpos->ScriptList, script, language);
1840 lookup_flags = alloca (gpos->LookupList.LookupCount);
1842 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1843 features, lookup_flags) < 0)
1844 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1846 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1850 if (! lookup_flags[i]) continue;
1852 while (gidx < gstring->used)
1854 gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
1864 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1865 const char *script, const char *language, const char *features)
1868 OTF_get_table (otf, "cmap");
1869 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
1873 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1874 const char *script, const char *language, const char *features)
1877 OTF_get_table (otf, "cmap");
1878 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
1882 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1883 const char *script, const char *language,
1884 const char *gsub_features, const char *gpos_features)
1886 if (OTF_drive_cmap (otf, gstring) < 0)
1888 if (OTF_drive_gdef (otf, gstring) < 0)
1891 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1894 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1900 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1901 const char *script, const char *language,
1902 const char *features)
1904 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
1908 iterate_coverage (OTF *otf, const char *feature,
1909 OTF_Feature_Callback callback,
1910 OTF_Coverage *coverage)
1914 if (coverage->CoverageFormat == 1)
1916 for (i = 0; i < coverage->Count; i++)
1917 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1922 for (i = 0; i < coverage->Count; i++)
1924 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1926 for (id = range->Start; id <= range->End; id++)
1927 if (callback (otf, feature, id) < 0)
1935 iterate_feature (OTF *otf, const char *feature,
1936 OTF_Feature_Callback callback,
1941 for (i = 0; i < lookup->SubTableCount; i++)
1943 unsigned lookup_type = lookup->LookupType;
1944 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1946 if (lookup_type == 7)
1948 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
1950 lookup_type = extension1->ExtensionLookupType;
1951 subtable = extension1->ExtensionSubtable;
1954 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
1956 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1960 else if (lookup_type == 4)
1962 OTF_GSUB_Ligature1 *lig1;
1964 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1967 lig1 = &subtable->u.ligature1;
1968 for (j = 0; j < lig1->LigSetCount; j++)
1970 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
1972 for (k = 0; k < ligset->LigatureCount; k++)
1974 OTF_Ligature *lig = ligset->Ligature + k;
1975 for (l = 0; l < lig->CompCount - 1; l++)
1976 if (callback (otf, feature, lig->Component[l]) < 0)
1981 else if (lookup_type == 6)
1983 if (subtable->Format == 1)
1985 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
1986 for (j = 0; j < context1->ChainRuleSetCount; j++)
1988 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
1989 for (k = 0; k < set->ChainRuleCount; k++)
1991 OTF_ChainRule *rule = set->ChainRule + k;
1992 for (l = 0; l < rule->LookupCount; l++)
1995 = (otf->gsub->LookupList.Lookup
1996 + rule->LookupRecord[l].LookupListIndex);
1997 if (iterate_feature (otf, feature, callback, lkup)
2004 else if (subtable->Format == 2)
2006 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
2008 for (j = 0; j < context2->ChainClassSetCnt; j++)
2010 OTF_ChainClassSet *set = context2->ChainClassSet + j;
2011 for (k = 0; k < set->ChainClassRuleCnt; j++)
2013 OTF_ChainClassRule *rule = set->ChainClassRule + k;
2015 for (l = 0; l < rule->LookupCount; l++)
2018 = (otf->gsub->LookupList.Lookup
2019 + rule->LookupRecord[k].LookupListIndex);
2020 if (iterate_feature (otf, feature, callback, lkup)
2029 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
2030 for (j = 0; j < context3->LookupCount; j++)
2033 = (otf->gsub->LookupList.Lookup
2034 + context3->LookupRecord[j].LookupListIndex);
2035 if (iterate_feature (otf, feature, callback, lkup) < 0)
2045 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2046 const char *script, const char *language,
2047 const char *feature)
2049 char *errfmt = "GSUB iterate feature%s";
2054 OTF_LangSys *langsys;
2057 if (OTF_get_table (otf, "GSUB") < 0)
2060 if (gsub->FeatureList.FeatureCount == 0
2061 || gsub->LookupList.LookupCount == 0)
2063 langsys = get_langsys (&gsub->ScriptList, script, language);
2066 lookup_flags = alloca (gsub->LookupList.LookupCount);
2068 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2069 feature, lookup_flags) < 0)
2070 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2072 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2073 if (lookup_flags[i])
2074 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)