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, int direction)
277 OTF_Glyph *g = gstring->glyphs + gidx;
278 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
281 for (i = j = 0; i < count && g != gend; g += direction)
282 if (! IGNORED_GLYPH (g, flag)
283 && g->glyph_id != ids[i++])
285 return (i < count ? -1 : j);
289 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
292 int i = rule->BacktrackGlyphCount;
296 || match_ids (gstring, gidx - 1, flag, i, rule->Backtrack, -1) < 0))
299 i = match_ids (gstring, gidx, flag,
300 rule->InputGlyphCount - 1, rule->Input, 1);
304 i = match_ids (gstring, gidx, flag,
305 rule->LookaheadGlyphCount, rule->LookAhead, 1);
312 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
313 int flag, int count, unsigned *classes, int direction)
315 OTF_Glyph *g = gstring->glyphs + gidx;
316 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
319 for (i = j = 0; i < count && g != gend; g += direction)
320 if (! IGNORED_GLYPH (g, flag)
321 && get_class_def (class_def, g->glyph_id) != classes[i++])
323 return (i < count ? -1 : j);
327 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
328 OTF_ClassDef *BacktrackClassDef,
329 OTF_ClassDef *InputClassDef,
330 OTF_ClassDef *LookaheadClassDef,
331 OTF_ChainClassRule *rule)
333 int i = rule->BacktrackGlyphCount;
337 || match_classes (BacktrackClassDef, gstring, gidx - 1, flag, i,
338 rule->Backtrack, -1) < 0))
341 i = match_classes (InputClassDef, gstring, gidx, flag,
342 rule->InputGlyphCount - 1, rule->Input, 1);
346 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
347 rule->LookaheadGlyphCount, rule->LookAhead, 1);
355 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
356 OTF_Coverage *coverages, int direction)
358 OTF_Glyph *g = gstring->glyphs + gidx;
359 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : - 1);
362 for (i = j = 0; i < count && g != gend; g += direction, j++)
363 if (! IGNORED_GLYPH (g, flag)
364 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
366 return (i < count ? -1 : j);
370 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
371 OTF_GSUB_ChainContext3 *context3)
373 int i = context3->BacktrackGlyphCount;
377 || match_coverages (gstring, gidx - 1, flag, i,
378 context3->Backtrack, -1) < 0))
381 if (context3->InputGlyphCount > 1)
383 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
384 context3->Input + 1, 1);
389 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
390 context3->LookAhead, 1) < 0)
396 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
397 OTF_GlyphString *gstring, int gidx, int alternate_subst)
399 char *errfmt = "GSUB Looking up%s";
401 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
402 unsigned int flag = (lookup->LookupFlag
403 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
404 int orig_gidx = gidx;
405 OTF_Glyph *g = gstring->glyphs + gidx;
408 if (IGNORED_GLYPH (g, flag))
411 /* Try all subtables until one of them handles the current glyph. */
412 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
414 unsigned lookup_type = lookup->LookupType;
415 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
418 if (lookup_type == 7)
420 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
422 lookup_type = extension1->ExtensionLookupType;
423 subtable = extension1->ExtensionSubtable;
427 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
428 : (lookup_type == 3))
431 if (subtable->Coverage.offset)
433 coverage_idx = get_coverage_index (&subtable->Coverage,
435 if (coverage_idx < 0)
442 if (subtable->Format == 1)
443 g->glyph_id += subtable->u.single1.DeltaGlyphID;
445 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
450 if (subtable->Format == 1)
452 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
453 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
455 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
456 seq->Substitute, seq->GlyphCount);
457 gidx += seq->GlyphCount;
460 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
464 if (subtable->Format == 1)
466 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
467 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
469 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
470 altset->Alternate, altset->GlyphCount);
471 gidx += altset->GlyphCount;;
474 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
478 if (subtable->Format == 1)
480 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
481 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
485 for (j = 0; j < ligset->LigatureCount; j++)
489 lig = ligset->Ligature + j;
490 n = match_ids (gstring, gidx + 1, flag,
491 lig->CompCount - 1, lig->Component, 1);
494 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
501 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
505 if (subtable->Format == 1)
507 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
508 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
513 for (j = 0; j < set->RuleCount; j++)
515 rule = set->Rule + j;
516 if (match_ids (gstring, gidx + 1, flag,
517 rule->GlyphCount - 1, rule->Input, 1) < 0)
519 orig_used = gstring->used;
520 for (k = 0; k < rule->LookupCount; k++)
521 lookup_gsub (otf, lookup_list,
522 rule->LookupRecord[k].LookupListIndex,
524 gidx + rule->LookupRecord[k].SequenceIndex,
526 gidx += rule->GlyphCount + (gstring->used - orig_used);
530 else if (subtable->Format == 2)
532 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
539 class = get_class_def (&context2->ClassDef, g->glyph_id);
540 set = context2->ClassSet + class;
542 for (j = 0; j < set->ClassRuleCnt; j++)
544 rule = set->ClassRule + j;
545 if (match_classes (&context2->ClassDef,
546 gstring, gidx + 1, flag,
547 rule->GlyphCount - 1, rule->Class, 1)
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 /* subtable->Format == 3 */
563 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
567 if (match_coverages (gstring, gidx + 1, flag,
568 context3->GlyphCount - 1,
569 context3->Coverage + 1, 1) < 0)
571 orig_used = gstring->used;
572 for (j = 0; j < context3->LookupCount; j++)
573 lookup_gsub (otf, lookup_list,
574 context3->LookupRecord[j].LookupListIndex,
576 gidx + context3->LookupRecord[j].SequenceIndex,
578 gidx += context3->GlyphCount + (gstring->used - orig_used);
583 if (subtable->Format == 1)
585 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
586 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
590 for (j = 0; j < set->ChainRuleCount; j++)
592 OTF_ChainRule *rule = set->ChainRule + j;
594 if (gidx < rule->BacktrackGlyphCount
595 || (gidx + rule->InputGlyphCount
596 + rule->LookaheadGlyphCount) > gstring->used)
598 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
600 orig_used = gstring->used;
601 for (k = 0; k < rule->LookupCount; k++)
602 lookup_gsub (otf, lookup_list,
603 rule->LookupRecord[k].LookupListIndex,
605 gidx + rule->LookupRecord[k].SequenceIndex,
607 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
611 else if (subtable->Format == 2)
613 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
614 OTF_ChainClassSet *set;
619 class = get_class_def (&context2->InputClassDef, g->glyph_id);
620 set = context2->ChainClassSet + class;
621 for (j = 0; j < set->ChainClassRuleCnt; j++)
623 OTF_ChainClassRule *rule = set->ChainClassRule + j;
626 if (gidx < rule->BacktrackGlyphCount
627 || (gidx + rule->InputGlyphCount
628 + rule->LookaheadGlyphCount) > gstring->used)
630 if (match_chain_classes (gstring, gidx, flag,
631 &context2->BacktrackClassDef,
632 &context2->InputClassDef,
633 &context2->LookaheadClassDef,
636 orig_used = gstring->used;
637 for (k = 0; k < rule->LookupCount; k++)
638 lookup_gsub (otf, lookup_list,
639 rule->LookupRecord[k].LookupListIndex,
641 gidx + rule->LookupRecord[k].SequenceIndex,
643 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
649 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
653 if (gidx < context3->BacktrackGlyphCount
654 || (gidx + context3->InputGlyphCount
655 + context3->LookaheadGlyphCount) > gstring->used)
657 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
659 orig_used = gstring->used;
660 for (j = 0; j < context3->LookupCount; j++)
661 lookup_gsub (otf, lookup_list,
662 context3->LookupRecord[j].LookupListIndex,
664 gidx + context3->LookupRecord[j].SequenceIndex,
666 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
672 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
673 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
674 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
677 if (back_gidx > gstring->used || ahead_gidx < 0)
680 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
681 if (get_coverage_index (reverse->Backtrack + j,
682 gstring->glyphs[gidx + 1 + j].glyph_id)
685 if (j < reverse->BacktrackGlyphCount)
687 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
688 if (get_coverage_index (reverse->LookAhead + j,
689 gstring->glyphs[gidx - 1 - j].glyph_id)
692 if (j < reverse->LookaheadGlyphCount)
694 g->glyph_id = reverse->Substitute[coverage_idx];
702 if (gidx == orig_gidx)
712 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
715 int orig_gidx = gidx++;
717 while (gidx < gstring->used
718 && ! gstring->glyphs[gidx].glyph_id
719 && gstring->glyphs[gidx].positioning_type)
721 GSTRING_INSERT (gstring, gidx, 1);
722 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
723 gstring->glyphs[gidx].glyph_id = 0;
728 print_anchor (char *head, OTF_Anchor *anchor)
730 if (anchor->AnchorFormat == 1)
731 fprintf (stderr, " %s(X:%d Y:%d)", head,
732 anchor->XCoordinate, anchor->YCoordinate);
733 else if (anchor->AnchorFormat == 2)
734 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
735 anchor->XCoordinate, anchor->YCoordinate,
736 anchor->f.f1.AnchorPoint);
738 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
739 anchor->XCoordinate, anchor->YCoordinate);
743 print_glyph_positioning (OTF_Glyph *g, int type)
746 fprintf (stderr, " %0X=", g->glyph_id);
747 switch (g->positioning_type)
751 int format = g->f.f1.format;
753 if (format & OTF_XPlacement)
754 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
755 if (format & OTF_XPlaDevice)
756 fprintf (stderr, "+alpha");
757 if (format & OTF_YPlacement)
758 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
759 if (format & OTF_YPlaDevice)
760 fprintf (stderr, "+alpha");
761 if (format & OTF_XAdvance)
762 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
763 if (format & OTF_XAdvDevice)
764 fprintf (stderr, "+alpha");
768 print_anchor ("entry", g->f.f3.entry_anchor);
769 print_anchor ("exit", g->f.f3.entry_anchor);
772 print_anchor ("mark", g->f.f4.mark_anchor);
773 print_anchor ("base", g->f.f4.base_anchor);
776 print_anchor ("mark", g->f.f5.mark_anchor);
777 print_anchor ("lig", g->f.f5.ligature_anchor);
780 print_anchor ("mark1", g->f.f6.mark1_anchor);
781 print_anchor ("mark2", g->f.f6.mark2_anchor);
787 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
788 OTF_GlyphString *gstring, int gidx, int accumulate)
790 char *errfmt = "GPOS Looking up%s";
792 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
793 unsigned int flag = (lookup->LookupFlag
794 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
795 int orig_gidx = gidx;
796 OTF_Glyph *g = gstring->glyphs + gidx;
800 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
801 g->glyph_id, lookup_list_index);
802 if (IGNORED_GLYPH (g, flag))
805 fprintf (stderr, " glyph ignored\n");
809 /* Try all subtables until one of them handles the current glyph. */
810 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
812 unsigned lookup_type = lookup->LookupType;
813 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
815 int positioning_type;
816 enum OTF_ValueFormat format;
817 OTF_ValueRecord *value;
818 OTF_Anchor *anchor1, *anchor2;
820 if (lookup_type == 9)
822 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
824 lookup_type = extension1->ExtensionLookupType;
825 subtable = extension1->ExtensionSubtable;
829 fprintf (stderr, "/%d", lookup_type);
830 if (subtable->Coverage.offset)
832 coverage_idx = get_coverage_index (&subtable->Coverage,
834 if (coverage_idx < 0)
841 positioning_type = lookup_type;
842 if (subtable->Format == 1)
844 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
846 format = single1->ValueFormat;
847 value = &single1->Value;
849 else if (subtable->Format == 2)
851 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
853 format = single2->ValueFormat;
854 value = single2->Value + coverage_idx;
856 if (accumulate && g->positioning_type)
858 gidx = gstring_insert_for_gpos (gstring, gidx);
859 g = gstring->glyphs + gidx;
861 g->positioning_type = positioning_type;
862 g->f.f1.format = format;
863 g->f.f1.value = value;
865 print_glyph_positioning (g, 0);
874 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
875 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
876 next_gidx++, nextg++);
878 if (next_gidx >= gstring->used)
880 if (subtable->Format == 1)
882 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
883 OTF_PairSet *set = pair1->PairSet + coverage_idx;
886 for (j = 0; j < set->PairValueCount; j++)
887 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
889 if (pair1->ValueFormat1)
891 if (accumulate && g->positioning_type)
893 gidx = gstring_insert_for_gpos (gstring, gidx);
894 g = gstring->glyphs + gidx;
895 next_gidx += gidx - orig_gidx;
896 nextg = gstring->glyphs + next_gidx;
898 g->positioning_type = lookup_type;
899 g->f.f2.format = pair1->ValueFormat1;
900 g->f.f2.value = &set->PairValueRecord[j].Value1;
902 print_glyph_positioning (g, 1);
906 if (pair1->ValueFormat2)
908 if (accumulate && g->positioning_type)
910 gidx = gstring_insert_for_gpos (gstring, gidx);
911 g = gstring->glyphs + gidx;
913 g->positioning_type = lookup_type;
914 g->f.f2.format = pair1->ValueFormat2;
915 g->f.f2.value = &set->PairValueRecord[j].Value2;
917 print_glyph_positioning (g, 2);
922 else if (subtable->Format == 2)
924 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
925 unsigned class1, class2;
927 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
928 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
929 if (pair2->ValueFormat1)
931 if (accumulate && g->positioning_type)
933 gidx = gstring_insert_for_gpos (gstring, gidx);
934 g = gstring->glyphs + gidx;
935 next_gidx += gidx - orig_gidx;
936 nextg = gstring->glyphs + next_gidx;
938 g->positioning_type = lookup_type;
939 g->f.f2.format = pair2->ValueFormat1;
941 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
943 print_glyph_positioning (g, 1);
947 if (pair2->ValueFormat2)
949 if (accumulate && g->positioning_type)
951 gidx = gstring_insert_for_gpos (gstring, gidx);
952 g = gstring->glyphs + gidx;
954 g->positioning_type = lookup_type;
955 g->f.f2.format = pair2->ValueFormat2;
957 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
959 print_glyph_positioning (g, 2);
967 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
969 g->positioning_type = lookup_type;
971 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
973 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
975 print_glyph_positioning (g, 0);
983 if (subtable->Format == 1)
985 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
986 OTF_MarkRecord *mark_record;
987 OTF_AnchorRecord *base_record;
989 int coverage_idx_base;
990 unsigned int this_flag = flag | OTF_IgnoreMarks;
993 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
995 if (baseg < gstring->glyphs)
998 = get_coverage_index (&mark_base1->BaseCoverage,
1000 if (coverage_idx_base < 0)
1002 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1004 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1005 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1007 = &base_record->Anchor[mark_record->Class];
1008 g->positioning_type = lookup_type;
1010 print_glyph_positioning (g, 0);
1018 if (subtable->Format == 1)
1020 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1022 int coverage_idx_lig;
1023 OTF_MarkRecord *mark_record;
1024 OTF_LigatureAttach *attach;
1025 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1028 for (j = 0; j < mark_lig1->ClassCount; j++)
1032 (ligg >= gstring->glyphs
1033 && (IGNORED_GLYPH (ligg, flag)
1034 || ligg->GlyphClass > OTF_GlyphClassLigature));
1036 if (ligg->positioning_type == 5
1037 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1038 num_class[ligg->MarkAttachClass]++;
1039 if (ligg < gstring->glyphs)
1042 = get_coverage_index (&mark_lig1->LigatureCoverage,
1044 if (coverage_idx_lig < 0)
1046 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1047 g->MarkAttachClass = mark_record->Class;
1048 attach = (mark_lig1->LigatureArray.LigatureAttach
1049 + coverage_idx_lig);
1050 for (j = 0; j < attach->ComponentCount; j++)
1052 OTF_Anchor *lig_anchor
1053 = attach->ComponentRecord[j].LigatureAnchor;
1055 if (lig_anchor[mark_record->Class].AnchorFormat
1056 && num_class[mark_record->Class]-- == 0)
1058 g->positioning_type = lookup_type;
1059 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1060 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1062 print_glyph_positioning (g, 0);
1073 if (subtable->Format == 1)
1075 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1076 OTF_MarkRecord *mark1_record;
1077 OTF_AnchorRecord *mark2_record;
1079 int coverage_idx_base;
1082 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1084 if (prevg < gstring->glyphs)
1087 = get_coverage_index (&mark_mark1->Mark2Coverage,
1089 if (coverage_idx_base < 0)
1091 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1093 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1094 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1095 g->f.f6.mark2_anchor
1096 = &mark2_record->Anchor[mark1_record->Class];
1097 g->positioning_type = lookup_type;
1099 print_glyph_positioning (g, 0);
1106 if (subtable->Format == 1)
1108 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1109 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1114 for (j = 0; j < set->RuleCount; j++)
1116 rule = set->Rule + j;
1117 if (match_ids (gstring, gidx + 1, flag,
1118 rule->GlyphCount - 1, rule->Input, 1) < 0)
1120 orig_used = gstring->used;
1121 for (k = 0; k < rule->LookupCount; k++)
1122 lookup_gpos (lookup_list,
1123 rule->LookupRecord[k].LookupListIndex,
1125 gidx + rule->LookupRecord[k].SequenceIndex,
1127 gidx += rule->GlyphCount + (gstring->used - orig_used);
1131 else if (subtable->Format == 2)
1133 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1135 OTF_ClassRule *rule;
1140 class = get_class_def (&context2->ClassDef, g->glyph_id);
1141 set = context2->ClassSet + class;
1143 for (j = 0; j < set->ClassRuleCnt; j++)
1145 rule = set->ClassRule + j;
1146 if (match_classes (&context2->ClassDef,
1147 gstring, gidx + 1, flag,
1148 rule->GlyphCount - 1, rule->Class, 1)
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 /* subtable->Format == 3 */
1164 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1168 if (match_coverages (gstring, gidx + 1, flag,
1169 context3->GlyphCount - 1,
1170 context3->Coverage + 1, 1) < 0)
1172 orig_used = gstring->used;
1173 for (j = 0; j < context3->LookupCount; j++)
1174 lookup_gpos (lookup_list,
1175 context3->LookupRecord[j].LookupListIndex,
1177 gidx + context3->LookupRecord[j].SequenceIndex,
1179 gidx += context3->GlyphCount + (gstring->used - orig_used);
1184 if (subtable->Format == 1)
1186 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1187 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1191 for (j = 0; j < set->ChainRuleCount; j++)
1193 OTF_ChainRule *rule = set->ChainRule + j;
1195 if (gidx < rule->BacktrackGlyphCount
1196 || (gidx + rule->InputGlyphCount
1197 + rule->LookaheadGlyphCount) > gstring->used)
1199 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1201 orig_used = gstring->used;
1202 for (k = 0; k < rule->LookupCount; k++)
1203 lookup_gpos (lookup_list,
1204 rule->LookupRecord[k].LookupListIndex,
1206 gidx + rule->LookupRecord[k].SequenceIndex,
1208 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1212 else if (subtable->Format == 2)
1214 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1215 OTF_ChainClassSet *set;
1220 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1221 set = context2->ChainClassSet + class;
1222 for (j = 0; j < set->ChainClassRuleCnt; j++)
1224 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1227 if (gidx < rule->BacktrackGlyphCount
1228 || (gidx + rule->InputGlyphCount
1229 + rule->LookaheadGlyphCount) > gstring->used)
1231 if (match_chain_classes (gstring, gidx, flag,
1232 &context2->BacktrackClassDef,
1233 &context2->InputClassDef,
1234 &context2->LookaheadClassDef,
1237 orig_used = gstring->used;
1238 for (k = 0; k < rule->LookupCount; k++)
1239 lookup_gpos (lookup_list,
1240 rule->LookupRecord[k].LookupListIndex,
1242 gidx + rule->LookupRecord[k].SequenceIndex,
1244 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1248 else if (subtable->Format == 3)
1250 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1254 if (gidx < context3->BacktrackGlyphCount
1255 || (gidx + context3->InputGlyphCount
1256 + context3->LookaheadGlyphCount) > gstring->used)
1258 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1260 orig_used = gstring->used;
1261 for (j = 0; j < context3->LookupCount; j++)
1262 lookup_gpos (lookup_list,
1263 context3->LookupRecord[j].LookupListIndex,
1265 gidx + context3->LookupRecord[j].SequenceIndex,
1267 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1270 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1277 if (gidx == orig_gidx)
1280 fprintf (stderr, " no match\n");
1283 else if (debug_flag)
1284 fprintf (stderr, "\n");
1289 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1291 return ((c < 0 || c >= 256)
1293 : sub->f.f0->glyphIdArray[c]);
1297 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1303 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1306 OTF_EncodingSubtable4 *sub4;
1311 segCount = sub4->segCountX2 / 2;
1312 for (i = 0; i < segCount; i++)
1314 OTF_cmapSegment *seg = sub4->segments + i;
1316 if (c >= seg->startCount && c <= seg->endCount)
1318 if (seg->idRangeOffset == 0xFFFF)
1319 return c + seg->idDelta;
1321 return sub4->glyphIdArray[seg->idRangeOffset
1322 + (c - seg->startCount)];
1329 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1335 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1341 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1347 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1349 OTF_EncodingSubtable12 *sub12;
1350 OTF_cmapGroup *g, *gend;
1356 gend = sub12->Groups + sub12->nGroups;
1359 if (g->startCharCode <= c && c <= g->endCharCode)
1360 return (g->startGlyphID + (c - g->startCharCode));
1366 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1368 static lookup_cmap_func lookup_cmap_func_table[] =
1370 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1371 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1375 get_GlyphID (OTF_cmap *cmap, int c)
1377 OTF_EncodingSubtable *sub;
1378 lookup_cmap_func lookupper;
1380 if (c < 0x10000 && cmap->unicode_table)
1381 return cmap->unicode_table[c];
1382 if (cmap->table_index < 0)
1384 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1385 lookupper = lookup_cmap_func_table[sub->format / 2];
1386 return lookupper (c, sub);
1390 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1392 unsigned nRecords = sub14->nRecords;
1393 OTF_VariationSelectorRecord *record;
1396 for (i = 0; i < nRecords; i++)
1398 record = &sub14->Records[i];
1399 if (record->varSelector == c2)
1401 if (record->defaultUVSOffset)
1403 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1404 unsigned numUVRs = record->numUnicodeValueRanges;
1405 unsigned top = numUVRs, bottom = 0, middle;
1407 if (uVRs[0].startUnicodeValue <= c1)
1409 unsigned additionalCount, startUnicodeValue;
1413 middle = (top + bottom) / 2;
1414 if (c1 < uVRs[middle].startUnicodeValue)
1416 else if (bottom == middle)
1421 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1422 additionalCount = uVRs[bottom].additionalCount;
1423 if (c1 <= startUnicodeValue + additionalCount)
1424 return get_GlyphID (cmap, c1);
1427 if (record->nonDefaultUVSOffset)
1429 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1430 unsigned numUVSMs = record->numUVSMappings;
1431 unsigned top = numUVSMs, bottom = 0, middle;
1433 if (uvsMappings[0].unicodeValue <= c1)
1437 middle = (top + bottom) / 2;
1438 if (c1 < uvsMappings[middle].unicodeValue)
1440 else if (bottom == middle)
1445 if (uvsMappings[bottom].unicodeValue == c1)
1446 return uvsMappings[bottom].glyphID;
1456 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1458 OTF_EncodingSubtable14 *sub14;
1459 int c1 = gstring->glyphs[idx - 1].c;
1460 int c2 = gstring->glyphs[idx].c;
1464 gstring->glyphs[idx].glyph_id = 0;
1465 for (i = 0; i < cmap->numTables; i++)
1466 if (cmap->EncodingRecord[i].subtable.format == 14)
1468 if (i == cmap->numTables)
1470 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1473 gstring->glyphs[idx - 1].glyph_id = code;
1474 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1476 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1477 sizeof (OTF_Glyph) * (gstring->used - idx));
1483 /* Table of GlyphClass and MarkAttackClass.
1485 For the Nth element CHAR, CHAR and the succeeding characters
1486 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1488 This table is generated from the General Category (GC) property of
1489 characters defined in the Unicode Character Database. */
1491 static int glyph_class_table[] =
1492 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1493 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1494 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1495 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1496 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1497 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1498 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1499 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1500 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1501 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1502 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1503 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1504 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1505 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1506 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1507 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1508 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1509 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1510 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1511 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1512 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1513 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1514 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1515 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1516 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1517 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1518 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1519 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1520 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1522 static int get_class_def_auto (int c)
1524 static int table_size
1525 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1528 if (c >= glyph_class_table[table_size - 1])
1531 high = table_size - 1;
1534 mid = (low + high) / 2;
1535 if (c < glyph_class_table[mid])
1537 else if (c >= glyph_class_table[mid + 1])
1542 return ((mid % 2) ? 3 : 1);
1550 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1553 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1557 OTF_EncodingSubtable *sub;
1558 lookup_cmap_func lookupper;
1561 && OTF_get_table (otf, "cmap") < 0)
1565 if (cmap->table_index < 0)
1569 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1570 lookupper = lookup_cmap_func_table[sub->format / 2];
1572 for (i = 0; i < gstring->used; i++)
1573 if (! gstring->glyphs[i].glyph_id)
1575 int c = gstring->glyphs[i].c;
1576 if (c < 32 || ! cmap->unicode_table)
1577 gstring->glyphs[i].glyph_id = 0;
1578 else if (UVS_P (c) && i > 0)
1579 check_cmap_uvs (cmap, gstring, i);
1580 else if (c < 0x10000)
1581 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1583 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1590 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1591 int platform_id, int encoding_id)
1595 char *errfmt = "CMAP Looking up%s";
1597 OTF_EncodingRecord *enc;
1598 lookup_cmap_func lookupper;
1601 && OTF_get_table (otf, "cmap") < 0)
1605 for (i = 0; i < cmap->numTables; i++)
1606 if (cmap->EncodingRecord[i].platformID == platform_id
1607 && cmap->EncodingRecord[i].encodingID == encoding_id)
1609 if (i == cmap->numTables)
1610 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1611 enc = cmap->EncodingRecord + i;
1612 if (enc->subtable.format > 12)
1613 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1614 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1616 for (i = 0; i < gstring->used; i++)
1617 if (! gstring->glyphs[i].glyph_id)
1619 int c = gstring->glyphs[i].c;
1620 if (c < 32 || ! cmap->unicode_table)
1621 gstring->glyphs[i].glyph_id = 0;
1622 else if (UVS_P (c) && i > 0)
1623 check_cmap_uvs (cmap, gstring, i);
1624 else if (c < 0x10000)
1625 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1627 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1633 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1636 && OTF_get_table (otf, "cmap") < 0)
1639 || code > otf->cmap->max_glyph_id
1640 || ! otf->cmap->decode_table)
1642 return otf->cmap->decode_table[code];
1646 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1650 OTF_EncodingSubtable14 *sub14;
1652 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1654 && OTF_get_table (otf, "cmap") < 0)
1657 for (i = 0; i < cmap->numTables; i++)
1658 if (cmap->EncodingRecord[i].subtable.format == 14)
1660 if (i == cmap->numTables)
1662 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1663 for (i = 0, n = 0; i < 256; i++)
1665 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1667 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1675 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1681 && OTF_get_table (otf, "GDEF") < 0)
1685 if (gdef->glyph_class_def.offset)
1686 for (i = 0; i < gstring->used; i++)
1687 gstring->glyphs[i].GlyphClass
1688 = get_class_def (&gdef->glyph_class_def,
1689 gstring->glyphs[i].glyph_id);
1691 for (i = 0; i < gstring->used; i++)
1692 gstring->glyphs[i].GlyphClass
1693 = get_class_def_auto (gstring->glyphs[i].c);
1695 if (gdef->mark_attach_class_def.offset)
1696 for (i = 0; i < gstring->used; i++)
1697 gstring->glyphs[i].MarkAttachClass
1698 = get_class_def (&gdef->mark_attach_class_def,
1699 gstring->glyphs[i].glyph_id);
1705 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1706 const char *script, const char *language,
1707 const char *features,
1708 int alternate_subst)
1710 char *errfmt = "GSUB driving%s";
1713 OTF_LangSys *LangSys;
1717 for (i = 0; i < gstring->used; i++)
1719 gstring->glyphs[i].positioning_type = 0;
1720 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1723 if (OTF_get_table (otf, "GSUB") < 0)
1726 if (gsub->FeatureList.FeatureCount == 0
1727 || gsub->LookupList.LookupCount == 0)
1730 LangSys = get_langsys (&gsub->ScriptList, script, language);
1734 lookup_flags = alloca (gsub->LookupList.LookupCount);
1736 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1737 features, lookup_flags) < 0)
1738 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1740 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1744 if (! lookup_flags[i]) continue;
1746 if (gsub->LookupList.Lookup[i].LookupType != 8)
1749 while (gidx < gstring->used)
1751 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1759 gidx = gstring->used - 1;
1762 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1774 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1775 const char *script, const char *language, const char *features)
1778 OTF_get_table (otf, "cmap");
1779 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
1783 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1784 const char *script, const char *language,
1785 const char *features,
1788 char *errfmt = "GPOS driving%s";
1791 OTF_LangSys *LangSys;
1795 for (i = 0; i < gstring->used; i++)
1796 gstring->glyphs[i].positioning_type = 0;
1798 if (OTF_get_table (otf, "GPOS") < 0)
1801 if (gpos->FeatureList.FeatureCount == 0
1802 || gpos->LookupList.LookupCount == 0)
1805 LangSys = get_langsys (&gpos->ScriptList, script, language);
1809 lookup_flags = alloca (gpos->LookupList.LookupCount);
1811 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1812 features, lookup_flags) < 0)
1813 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1815 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1819 if (! lookup_flags[i]) continue;
1821 while (gidx < gstring->used)
1823 gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
1833 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1834 const char *script, const char *language, const char *features)
1837 OTF_get_table (otf, "cmap");
1838 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
1842 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1843 const char *script, const char *language, const char *features)
1846 OTF_get_table (otf, "cmap");
1847 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
1851 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1852 const char *script, const char *language,
1853 const char *gsub_features, const char *gpos_features)
1855 if (OTF_drive_cmap (otf, gstring) < 0)
1857 if (OTF_drive_gdef (otf, gstring) < 0)
1860 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1863 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1869 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1870 const char *script, const char *language,
1871 const char *features)
1873 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
1877 iterate_coverage (OTF *otf, const char *feature,
1878 OTF_Feature_Callback callback,
1879 OTF_Coverage *coverage)
1883 if (coverage->CoverageFormat == 1)
1885 for (i = 0; i < coverage->Count; i++)
1886 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1891 for (i = 0; i < coverage->Count; i++)
1893 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1895 for (id = range->Start; id <= range->End; id++)
1896 if (callback (otf, feature, id) < 0)
1904 iterate_feature (OTF *otf, const char *feature,
1905 OTF_Feature_Callback callback,
1910 for (i = 0; i < lookup->SubTableCount; i++)
1912 unsigned lookup_type = lookup->LookupType;
1913 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1915 if (lookup_type == 7)
1917 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
1919 lookup_type = extension1->ExtensionLookupType;
1920 subtable = extension1->ExtensionSubtable;
1923 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
1925 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1929 else if (lookup_type == 4)
1931 OTF_GSUB_Ligature1 *lig1;
1933 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1936 lig1 = &subtable->u.ligature1;
1937 for (j = 0; j < lig1->LigSetCount; j++)
1939 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
1941 for (k = 0; k < ligset->LigatureCount; k++)
1943 OTF_Ligature *lig = ligset->Ligature + k;
1944 for (l = 0; l < lig->CompCount - 1; l++)
1945 if (callback (otf, feature, lig->Component[l]) < 0)
1950 else if (lookup_type == 6)
1952 if (subtable->Format == 1)
1954 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
1955 for (j = 0; j < context1->ChainRuleSetCount; j++)
1957 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
1958 for (k = 0; k < set->ChainRuleCount; k++)
1960 OTF_ChainRule *rule = set->ChainRule + k;
1961 for (l = 0; l < rule->LookupCount; l++)
1964 = (otf->gsub->LookupList.Lookup
1965 + rule->LookupRecord[l].LookupListIndex);
1966 if (iterate_feature (otf, feature, callback, lkup)
1973 else if (subtable->Format == 2)
1975 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
1977 for (j = 0; j < context2->ChainClassSetCnt; j++)
1979 OTF_ChainClassSet *set = context2->ChainClassSet + j;
1980 for (k = 0; k < set->ChainClassRuleCnt; j++)
1982 OTF_ChainClassRule *rule = set->ChainClassRule + k;
1984 for (l = 0; l < rule->LookupCount; l++)
1987 = (otf->gsub->LookupList.Lookup
1988 + rule->LookupRecord[k].LookupListIndex);
1989 if (iterate_feature (otf, feature, callback, lkup)
1998 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
1999 for (j = 0; j < context3->LookupCount; j++)
2002 = (otf->gsub->LookupList.Lookup
2003 + context3->LookupRecord[j].LookupListIndex);
2004 if (iterate_feature (otf, feature, callback, lkup) < 0)
2014 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2015 const char *script, const char *language,
2016 const char *feature)
2018 char *errfmt = "GSUB iterate feature%s";
2023 OTF_LangSys *langsys;
2026 if (OTF_get_table (otf, "GSUB") < 0)
2029 if (gsub->FeatureList.FeatureCount == 0
2030 || gsub->LookupList.LookupCount == 0)
2032 langsys = get_langsys (&gsub->ScriptList, script, language);
2035 lookup_flags = alloca (gsub->LookupList.LookupCount);
2037 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2038 feature, lookup_flags) < 0)
2039 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2041 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2042 if (lookup_flags[i])
2043 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)