1 /* otfdrive.c -- OpenType font driver.
3 Copyright (C) 2003, 2004
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA. */
32 extern int debug_flag;
34 /* Return nonzero (-1 if ID is zero, 1 otherwise) if OTF_Glyph *G
35 should be ignored according to LookupFlag FLAG. */
36 #define IGNORED_GLYPH(g, flag) \
37 ((g)->glyph_id == 0 ? -1 \
38 : (((flag) & (1 << (g)->GlyphClass)) \
39 || (((flag) & OTF_MarkAttachmentType) \
40 && (g)->GlyphClass == OTF_GlyphClassMark \
41 && ((flag) >> 8) != (g)->MarkAttachClass)))
43 #define GSTRING_DELETE(gstring, from, len) \
45 memmove (gstring->glyphs + from, gstring->glyphs + from + len, \
46 sizeof (OTF_Glyph) * (gstring->used - from - len)); \
47 gstring->used -= len; \
51 #define GSTRING_INSERT(gstring, pos, len) \
53 if (gstring->used + len > gstring->size) \
55 char *errfmt = "GSTRING%s"; \
57 gstring->size = gstring->used + len; \
59 = (OTF_Glyph *) realloc (gstring->glyphs, \
60 sizeof (OTF_Glyph) * gstring->size); \
61 if (! gstring->glyphs) \
62 OTF_ERROR (OTF_ERROR_MEMORY, ""); \
64 memmove (gstring->glyphs + pos + len, gstring->glyphs + pos, \
65 sizeof (OTF_Glyph) * (gstring->used - pos)); \
66 gstring->used += len; \
70 static unsigned get_class_def (OTF_ClassDef *, OTF_GlyphID);
73 gstring_subst (OTF *otf, OTF_GlyphString *gstring, int from, int to, int flag,
74 OTF_GlyphID *ids, int num)
79 int from_idx = gstring->glyphs[from].f.index.from;
80 int to_idx = gstring->glyphs[to - 1].f.index.to;
83 for (i = non_ignored_idx = to - 1; i >= from; i--)
85 OTF_Glyph *g = gstring->glyphs + i;
87 if (IGNORED_GLYPH (g, flag) == 1)
89 /* Move this glyph to the next of the current target of
93 memmove (g, g + 1, sizeof (OTF_Glyph) * (non_ignored_idx - i));
94 temp.f.index.from = from_idx;
95 temp.f.index.to = to_idx;
96 gstring->glyphs[non_ignored_idx--] = temp;
102 GSTRING_INSERT (gstring, from, (num - len));
104 GSTRING_DELETE (gstring, from, (len - num));
105 for (i = 0; i < num; i++)
107 if (gstring->glyphs[from + i].glyph_id != ids[i])
109 gstring->glyphs[from + i].c = 0;
111 gstring->glyphs[from + i].GlyphClass
112 = get_class_def (&otf->gdef->glyph_class_def, ids[i]);
114 gstring->glyphs[from + i].GlyphClass = 0;
116 gstring->glyphs[from + i].glyph_id = ids[i];
117 gstring->glyphs[from + i].positioning_type = 0;
118 gstring->glyphs[from + i].f.index.from = from_idx;
119 gstring->glyphs[from + i].f.index.to = to_idx;
126 get_coverage_index (OTF_Coverage *coverage, OTF_GlyphID id)
130 if (coverage->CoverageFormat == 1)
132 for (i = 0; i < coverage->Count; i++)
133 if (coverage->table.GlyphArray[i] == id)
138 for (i = 0; i < coverage->Count; i++)
139 if (coverage->table.RangeRecord[i].Start <= id
140 && coverage->table.RangeRecord[i].End >= id)
141 return (coverage->table.RangeRecord[i].StartCoverageIndex
142 + (id - coverage->table.RangeRecord[i].Start));
148 get_class_def (OTF_ClassDef *class_def, OTF_GlyphID glyph_id)
150 if (class_def->ClassFormat == 1)
152 int idx = (int) glyph_id - (int) class_def->f.f1.StartGlyph;
154 if (idx >= 0 && idx < class_def->f.f1.GlyphCount)
155 return class_def->f.f1.ClassValueArray[idx];
161 for (i = 0; i < class_def->f.f2.ClassRangeCount; i++)
162 if (glyph_id >= class_def->f.f2.ClassRangeRecord[i].Start
163 && glyph_id <= class_def->f.f2.ClassRangeRecord[i].End)
164 return class_def->f.f2.ClassRangeRecord[i].Class;
170 get_langsys (OTF_ScriptList *script_list,
171 const char *script, const char *language)
174 OTF_Tag script_tag = OTF_tag (script);
175 OTF_Tag langsys_tag = OTF_tag (language);
177 OTF_Tag dflt_tag = OTF_tag ("DFLT");
178 OTF_Script *dflt = NULL;
180 for (i = 0; i < script_list->ScriptCount; i++)
182 OTF_Script *script = script_list->Script + i;
184 if (script_list->Script[i].ScriptTag == dflt_tag)
186 if (script_list->Script[i].ScriptTag == script_tag)
189 return &script->DefaultLangSys;
190 for (j = 0; j < script->LangSysCount; j++)
191 if (script->LangSysRecord[j].LangSysTag == langsys_tag)
192 return script->LangSys + j;
193 return &script->DefaultLangSys;
198 dflt = script_list->Script;
200 return &dflt->DefaultLangSys;
201 for (j = 0; j < dflt->LangSysCount; j++)
202 if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
203 return dflt->LangSys + j;
204 return &dflt->DefaultLangSys;
208 setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
209 OTF_LangSys *LangSys,
210 const char *features, char *lookup_flags)
213 OTF_Feature *feature;
214 int *feature_table = alloca (sizeof (int) * FeatureList->FeatureCount);
218 for (i = 0; i < FeatureList->FeatureCount; i++)
219 feature_table[i] = 0;
220 memset (lookup_flags, 0, LookupList->LookupCount);
228 if (*features == '*')
230 /* Consume all remaining features. */
231 for (i = 0; i < LangSys->FeatureCount; i++)
233 int index = LangSys->FeatureIndex[i];
235 if (! feature_table[index])
237 feature = FeatureList->Feature + index;
238 for (j = 0; j < feature->LookupCount; j++)
239 lookup_flags[feature->LookupListIndex[j]] = 1;
245 if (*features == '~')
246 use_it = -1, features++;
247 for (i = 0; *features && *features != ','; i++, features++)
248 tagname[i] = *features;
254 tag = OTF_tag (tagname);
255 for (i = 0; i < LangSys->FeatureCount; i++)
257 feature = FeatureList->Feature + LangSys->FeatureIndex[i];
258 if (tag == feature->FeatureTag)
260 if (feature_table[i])
263 for (j = 0; j < feature->LookupCount; j++)
264 lookup_flags[feature->LookupListIndex[j]] = 1;
265 feature_table[i] = use_it;
274 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
275 int count, OTF_GlyphID *ids)
277 OTF_Glyph *gbeg = gstring->glyphs + gidx;
278 OTF_Glyph *gend = gstring->glyphs + gstring->used;
282 for (g = gbeg, i = 0; g < gend && i < count; g++)
283 if (! IGNORED_GLYPH (g, flag) && g->glyph_id != ids[i++])
285 return (i < count ? -1 : g - gbeg);
289 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
292 int i = rule->BacktrackGlyphCount;
299 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
300 if (! IGNORED_GLYPH (g, flag) && --i == 0)
304 if (match_ids (gstring, j, flag,
305 rule->BacktrackGlyphCount, rule->Backtrack)
310 i = match_ids (gstring, gidx, flag,
311 rule->InputGlyphCount - 1, rule->Input);
315 i = match_ids (gstring, gidx, flag,
316 rule->LookaheadGlyphCount, rule->LookAhead);
323 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
324 int flag, int count, unsigned *classes)
326 OTF_Glyph *gbeg = gstring->glyphs + gidx;
327 OTF_Glyph *gend = gstring->glyphs + gstring->used;
331 for (g = gbeg, i = 0; g < gend && i < count; g++)
332 if (! IGNORED_GLYPH (g, flag)
333 && get_class_def (class_def, g->glyph_id) != classes[i++])
335 return (i < count ? -1 : g - gbeg);
339 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
340 OTF_ClassDef *BacktrackClassDef,
341 OTF_ClassDef *InputClassDef,
342 OTF_ClassDef *LookaheadClassDef,
343 OTF_ChainClassRule *rule)
345 int i = rule->BacktrackGlyphCount;
352 for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
353 if (! IGNORED_GLYPH (g, flag) && i-- == 0)
357 if (match_classes (BacktrackClassDef, gstring, j, flag,
358 rule->BacktrackGlyphCount, rule->Backtrack) < 0);
362 i = match_classes (InputClassDef, gstring, gidx, flag,
363 rule->InputGlyphCount - 1, rule->Input);
367 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
368 rule->LookaheadGlyphCount, rule->LookAhead);
376 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
377 OTF_Coverage *coverages)
379 OTF_Glyph *gbeg = gstring->glyphs + gidx;
380 OTF_Glyph *gend = gstring->glyphs + gstring->used;
384 for (g = gbeg, i = 0; g < gend && i < count; g++)
385 if (! IGNORED_GLYPH (g, flag)
386 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
388 return (i < count ? -1 : g - gbeg);
392 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
393 OTF_GSUB_ChainContext3 *context3)
395 int i = context3->BacktrackGlyphCount;
402 for (j = gidx - 1, g= gstring->glyphs +j; j >= 0; j--, g--)
403 if (! IGNORED_GLYPH (g, flag) && --i == 0)
407 if (match_coverages (gstring, j, flag, context3->BacktrackGlyphCount,
408 context3->Backtrack) < 0)
412 if (context3->InputGlyphCount > 1)
414 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
415 context3->Input + 1);
420 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
421 context3->LookAhead) < 0)
427 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
428 OTF_GlyphString *gstring, int gidx, int alternate_subst)
430 char *errfmt = "GSUB Looking up%s";
432 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
433 unsigned int flag = (lookup->LookupFlag
434 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
435 int orig_gidx = gidx;
436 OTF_Glyph *g = gstring->glyphs + gidx;
439 if (IGNORED_GLYPH (g, flag))
442 /* Try all subtables until one of them handles the current glyph. */
443 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
445 unsigned lookup_type = lookup->LookupType;
446 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
449 if (lookup_type == 7)
451 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
453 lookup_type = extension1->ExtensionLookupType;
454 subtable = extension1->ExtensionSubtable;
458 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
459 : (lookup_type == 3))
462 if (subtable->Coverage.offset)
464 coverage_idx = get_coverage_index (&subtable->Coverage,
466 if (coverage_idx < 0)
473 if (subtable->Format == 1)
474 g->glyph_id += subtable->u.single1.DeltaGlyphID;
476 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
481 if (subtable->Format == 1)
483 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
484 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
486 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
487 seq->Substitute, seq->GlyphCount);
488 gidx += seq->GlyphCount;
491 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
495 if (subtable->Format == 1)
497 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
498 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
500 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
501 altset->Alternate, altset->GlyphCount);
502 gidx += altset->GlyphCount;;
505 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
509 if (subtable->Format == 1)
511 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
512 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
516 for (j = 0; j < ligset->LigatureCount; j++)
520 lig = ligset->Ligature + j;
521 n = match_ids (gstring, gidx + 1, flag,
522 lig->CompCount - 1, lig->Component);
525 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
532 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
536 if (subtable->Format == 1)
538 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
539 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
544 for (j = 0; j < set->RuleCount; j++)
546 rule = set->Rule + j;
547 if (match_ids (gstring, gidx + 1, flag,
548 rule->GlyphCount - 1, rule->Input) < 0)
550 orig_used = gstring->used;
551 for (k = 0; k < rule->LookupCount; k++)
552 lookup_gsub (otf, lookup_list,
553 rule->LookupRecord[k].LookupListIndex,
555 gidx + rule->LookupRecord[k].SequenceIndex,
557 gidx += rule->GlyphCount + (gstring->used - orig_used);
561 else if (subtable->Format == 2)
563 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
570 class = get_class_def (&context2->ClassDef, g->glyph_id);
571 set = context2->ClassSet + class;
573 for (j = 0; j < set->ClassRuleCnt; j++)
575 rule = set->ClassRule + j;
576 if (match_classes (&context2->ClassDef,
577 gstring, gidx + 1, flag,
578 rule->GlyphCount - 1, rule->Class)
581 orig_used = gstring->used;
582 for (k = 0; k < rule->LookupCount; k++)
583 lookup_gsub (otf, lookup_list,
584 rule->LookupRecord[k].LookupListIndex,
586 gidx + rule->LookupRecord[k].SequenceIndex,
588 gidx += rule->GlyphCount + (gstring->used - orig_used);
592 else /* subtable->Format == 3 */
594 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
598 if (match_coverages (gstring, gidx + 1, flag,
599 context3->GlyphCount - 1,
600 context3->Coverage + 1) < 0)
602 orig_used = gstring->used;
603 for (j = 0; j < context3->LookupCount; j++)
604 lookup_gsub (otf, lookup_list,
605 context3->LookupRecord[j].LookupListIndex,
607 gidx + context3->LookupRecord[j].SequenceIndex,
609 gidx += context3->GlyphCount + (gstring->used - orig_used);
614 if (subtable->Format == 1)
616 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
617 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
621 for (j = 0; j < set->ChainRuleCount; j++)
623 OTF_ChainRule *rule = set->ChainRule + j;
625 if (gidx < rule->BacktrackGlyphCount
626 || (gidx + rule->InputGlyphCount
627 + rule->LookaheadGlyphCount) > gstring->used)
629 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
631 orig_used = gstring->used;
632 for (k = 0; k < rule->LookupCount; k++)
633 lookup_gsub (otf, lookup_list,
634 rule->LookupRecord[k].LookupListIndex,
636 gidx + rule->LookupRecord[k].SequenceIndex,
638 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
642 else if (subtable->Format == 2)
644 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
645 OTF_ChainClassSet *set;
650 class = get_class_def (&context2->InputClassDef, g->glyph_id);
651 set = context2->ChainClassSet + class;
652 for (j = 0; j < set->ChainClassRuleCnt; j++)
654 OTF_ChainClassRule *rule = set->ChainClassRule + j;
657 if (gidx < rule->BacktrackGlyphCount
658 || (gidx + rule->InputGlyphCount
659 + rule->LookaheadGlyphCount) > gstring->used)
661 if (match_chain_classes (gstring, gidx, flag,
662 &context2->BacktrackClassDef,
663 &context2->InputClassDef,
664 &context2->LookaheadClassDef,
667 orig_used = gstring->used;
668 for (k = 0; k < rule->LookupCount; k++)
669 lookup_gsub (otf, lookup_list,
670 rule->LookupRecord[k].LookupListIndex,
672 gidx + rule->LookupRecord[k].SequenceIndex,
674 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
680 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
684 if (gidx < context3->BacktrackGlyphCount
685 || (gidx + context3->InputGlyphCount
686 + context3->LookaheadGlyphCount) > gstring->used)
688 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
690 orig_used = gstring->used;
691 for (j = 0; j < context3->LookupCount; j++)
692 lookup_gsub (otf, lookup_list,
693 context3->LookupRecord[j].LookupListIndex,
695 gidx + context3->LookupRecord[j].SequenceIndex,
697 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
703 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
704 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
705 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
708 if (back_gidx > gstring->used || ahead_gidx < 0)
711 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
712 if (get_coverage_index (reverse->Backtrack + j,
713 gstring->glyphs[gidx + 1 + j].glyph_id)
716 if (j < reverse->BacktrackGlyphCount)
718 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
719 if (get_coverage_index (reverse->LookAhead + j,
720 gstring->glyphs[gidx - 1 - j].glyph_id)
723 if (j < reverse->LookaheadGlyphCount)
725 g->glyph_id = reverse->Substitute[coverage_idx];
733 if (gidx == orig_gidx)
742 get_anchor (OTF_Anchor *anchor, OTF_ValueRecord *rec)
744 unsigned value_format = OTF_XPlacement | OTF_YPlacement;
746 rec->XPlacement = anchor->XCoordinate;
747 rec->YPlacement = anchor->YCoordinate;
748 if (anchor->AnchorFormat == 1)
751 else if (anchor->AnchorFormat == 2)
752 /* Not yet implemented */
754 else if (anchor->AnchorFormat == 3)
755 /* Not yet implemented */
761 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
764 int orig_gidx = gidx++;
766 while (gidx < gstring->used
767 && ! gstring->glyphs[gidx].glyph_id
768 && gstring->glyphs[gidx].positioning_type)
770 GSTRING_INSERT (gstring, gidx, 1);
771 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
772 gstring->glyphs[gidx].glyph_id = 0;
777 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
778 OTF_GlyphString *gstring, int gidx, int accumulate)
780 char *errfmt = "GPOS Looking up%s";
782 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
783 unsigned int flag = (lookup->LookupFlag
784 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
785 int orig_gidx = gidx;
786 OTF_Glyph *g = gstring->glyphs + gidx;
790 fprintf (stderr, "[GPOS] glyph:%X lookup(%d)",
791 g->glyph_id, lookup_list_index);
792 if (IGNORED_GLYPH (g, flag))
795 fprintf (stderr, " ignored glyph\n");
799 /* Try all subtables until one of them handles the current glyph. */
800 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
802 unsigned lookup_type = lookup->LookupType;
803 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
805 int positioning_type;
806 enum OTF_ValueFormat format;
807 OTF_ValueRecord *value;
808 OTF_Anchor *anchor1, *anchor2;
810 if (lookup_type == 9)
812 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
814 lookup_type = extension1->ExtensionLookupType;
815 subtable = extension1->ExtensionSubtable;
819 fprintf (stderr, " type(%d)", lookup_type);
820 if (subtable->Coverage.offset)
822 coverage_idx = get_coverage_index (&subtable->Coverage,
824 if (coverage_idx < 0)
831 positioning_type = lookup_type;
832 if (subtable->Format == 1)
834 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
836 format = single1->ValueFormat;
837 value = &single1->Value;
839 else if (subtable->Format == 2)
841 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
843 format = single2->ValueFormat;
844 value = single2->Value + coverage_idx;
846 if (accumulate && g->positioning_type)
848 gidx = gstring_insert_for_gpos (gstring, gidx);
849 g = gstring->glyphs + gidx;
851 g->positioning_type = positioning_type;
852 g->f.f1.format = format;
853 g->f.f1.value = value;
862 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
863 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
864 next_gidx++, nextg++);
866 if (next_gidx >= gstring->used)
868 if (subtable->Format == 1)
870 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
871 OTF_PairSet *set = pair1->PairSet + coverage_idx;
874 for (j = 0; j < set->PairValueCount; j++)
875 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
877 if (pair1->ValueFormat1)
879 if (accumulate && g->positioning_type)
881 gidx = gstring_insert_for_gpos (gstring, gidx);
882 g = gstring->glyphs + gidx;
883 next_gidx += gidx - orig_gidx;
884 nextg = gstring->glyphs + next_gidx;
886 g->positioning_type = lookup_type;
887 g->f.f2.format = pair1->ValueFormat1;
888 g->f.f2.value = &set->PairValueRecord[j].Value1;
892 if (pair1->ValueFormat2)
894 if (accumulate && g->positioning_type)
896 gidx = gstring_insert_for_gpos (gstring, gidx);
897 g = gstring->glyphs + gidx;
899 g->positioning_type = lookup_type;
900 g->f.f2.format = pair1->ValueFormat2;
901 g->f.f2.value = &set->PairValueRecord[j].Value2;
907 else if (subtable->Format == 2)
909 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
910 unsigned class1, class2;
912 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
913 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
914 if (pair2->ValueFormat1)
916 if (accumulate && g->positioning_type)
918 gidx = gstring_insert_for_gpos (gstring, gidx);
919 g = gstring->glyphs + gidx;
920 next_gidx += gidx - orig_gidx;
921 nextg = gstring->glyphs + next_gidx;
923 g->positioning_type = lookup_type;
924 g->f.f2.format = pair2->ValueFormat1;
926 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
930 if (pair2->ValueFormat2)
932 if (accumulate && g->positioning_type)
934 gidx = gstring_insert_for_gpos (gstring, gidx);
935 g = gstring->glyphs + gidx;
937 g->positioning_type = lookup_type;
938 g->f.f2.format = pair2->ValueFormat2;
940 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
949 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
951 if (accumulate && g->positioning_type)
953 gidx = gstring_insert_for_gpos (gstring, gidx);
954 g = gstring->glyphs + gidx;
956 g->positioning_type = lookup_type;
958 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
960 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
968 if (subtable->Format == 1)
970 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
971 OTF_MarkRecord *mark_record;
972 OTF_AnchorRecord *base_record;
974 int coverage_idx_base;
975 unsigned int this_flag = flag | OTF_IgnoreMarks;
978 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
980 if (baseg < gstring->glyphs)
983 = get_coverage_index (&mark_base1->BaseCoverage,
985 if (coverage_idx_base < 0)
987 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
989 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
990 if (accumulate && g->positioning_type)
992 gidx = gstring_insert_for_gpos (gstring, gidx);
993 g = gstring->glyphs + gidx;
995 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
997 = &base_record->Anchor[mark_record->Class];
998 g->positioning_type = lookup_type;
1006 if (subtable->Format == 1)
1008 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1010 int coverage_idx_lig;
1011 OTF_MarkRecord *mark_record;
1012 OTF_LigatureAttach *attach;
1013 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1016 for (j = 0; j < mark_lig1->ClassCount; j++)
1020 (ligg >= gstring->glyphs
1021 && (IGNORED_GLYPH (ligg, flag)
1022 || ligg->GlyphClass > OTF_GlyphClassLigature));
1024 if (ligg->positioning_type == 5
1025 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1026 num_class[ligg->MarkAttachClass]++;
1027 if (ligg < gstring->glyphs)
1030 = get_coverage_index (&mark_lig1->LigatureCoverage,
1032 if (coverage_idx_lig < 0)
1034 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1035 g->MarkAttachClass = mark_record->Class;
1036 attach = (mark_lig1->LigatureArray.LigatureAttach
1037 + coverage_idx_lig);
1038 for (j = 0; j < attach->ComponentCount; j++)
1040 OTF_Anchor *lig_anchor
1041 = attach->ComponentRecord[j].LigatureAnchor;
1043 if (lig_anchor[mark_record->Class].AnchorFormat
1044 && num_class[mark_record->Class]-- == 0)
1046 if (accumulate && g->positioning_type)
1048 gidx = gstring_insert_for_gpos (gstring, gidx);
1049 g = gstring->glyphs + gidx;
1051 g->positioning_type = lookup_type;
1052 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1053 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1064 if (subtable->Format == 1)
1066 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1067 OTF_MarkRecord *mark1_record;
1068 OTF_AnchorRecord *mark2_record;
1070 int coverage_idx_base;
1073 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1075 if (prevg < gstring->glyphs)
1078 = get_coverage_index (&mark_mark1->Mark2Coverage,
1080 if (coverage_idx_base < 0)
1082 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1084 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1085 if (accumulate && g->positioning_type)
1087 gidx = gstring_insert_for_gpos (gstring, gidx);
1088 g = gstring->glyphs + gidx;
1090 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1091 g->f.f6.mark2_anchor
1092 = &mark2_record->Anchor[mark1_record->Class];
1093 g->positioning_type = lookup_type;
1100 if (subtable->Format == 1)
1102 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1103 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1108 for (j = 0; j < set->RuleCount; j++)
1110 rule = set->Rule + j;
1111 if (match_ids (gstring, gidx + 1, flag,
1112 rule->GlyphCount - 1, rule->Input) < 0)
1114 orig_used = gstring->used;
1115 for (k = 0; k < rule->LookupCount; k++)
1116 lookup_gpos (lookup_list,
1117 rule->LookupRecord[k].LookupListIndex,
1119 gidx + rule->LookupRecord[k].SequenceIndex,
1121 gidx += rule->GlyphCount + (gstring->used - orig_used);
1125 else if (subtable->Format == 2)
1127 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1129 OTF_ClassRule *rule;
1134 class = get_class_def (&context2->ClassDef, g->glyph_id);
1135 set = context2->ClassSet + class;
1137 for (j = 0; j < set->ClassRuleCnt; j++)
1139 rule = set->ClassRule + j;
1140 if (match_classes (&context2->ClassDef,
1141 gstring, gidx + 1, flag,
1142 rule->GlyphCount - 1, rule->Class)
1145 orig_used = gstring->used;
1146 for (k = 0; k < rule->LookupCount; k++)
1147 lookup_gpos (lookup_list,
1148 rule->LookupRecord[k].LookupListIndex,
1150 gidx + rule->LookupRecord[k].SequenceIndex,
1152 gidx += rule->GlyphCount + (gstring->used - orig_used);
1156 else /* subtable->Format == 3 */
1158 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1162 if (match_coverages (gstring, gidx + 1, flag,
1163 context3->GlyphCount - 1,
1164 context3->Coverage + 1) < 0)
1166 orig_used = gstring->used;
1167 for (j = 0; j < context3->LookupCount; j++)
1168 lookup_gpos (lookup_list,
1169 context3->LookupRecord[j].LookupListIndex,
1171 gidx + context3->LookupRecord[j].SequenceIndex,
1173 gidx += context3->GlyphCount + (gstring->used - orig_used);
1178 if (subtable->Format == 1)
1180 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1181 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1185 for (j = 0; j < set->ChainRuleCount; j++)
1187 OTF_ChainRule *rule = set->ChainRule + j;
1189 if (gidx < rule->BacktrackGlyphCount
1190 || (gidx + rule->InputGlyphCount
1191 + rule->LookaheadGlyphCount) > gstring->used)
1193 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1195 orig_used = gstring->used;
1196 for (k = 0; k < rule->LookupCount; k++)
1197 lookup_gpos (lookup_list,
1198 rule->LookupRecord[k].LookupListIndex,
1200 gidx + rule->LookupRecord[k].SequenceIndex,
1202 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1206 else if (subtable->Format == 2)
1208 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1209 OTF_ChainClassSet *set;
1214 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1215 set = context2->ChainClassSet + class;
1216 for (j = 0; j < set->ChainClassRuleCnt; j++)
1218 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1221 if (gidx < rule->BacktrackGlyphCount
1222 || (gidx + rule->InputGlyphCount
1223 + rule->LookaheadGlyphCount) > gstring->used)
1225 if (match_chain_classes (gstring, gidx, flag,
1226 &context2->BacktrackClassDef,
1227 &context2->InputClassDef,
1228 &context2->LookaheadClassDef,
1231 orig_used = gstring->used;
1232 for (k = 0; k < rule->LookupCount; k++)
1233 lookup_gpos (lookup_list,
1234 rule->LookupRecord[k].LookupListIndex,
1236 gidx + rule->LookupRecord[k].SequenceIndex,
1238 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1242 else if (subtable->Format == 3)
1244 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1248 if (gidx < context3->BacktrackGlyphCount
1249 || (gidx + context3->InputGlyphCount
1250 + context3->LookaheadGlyphCount) > gstring->used)
1252 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1254 orig_used = gstring->used;
1255 for (j = 0; j < context3->LookupCount; j++)
1256 lookup_gpos (lookup_list,
1257 context3->LookupRecord[j].LookupListIndex,
1259 gidx + context3->LookupRecord[j].SequenceIndex,
1261 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1264 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1271 if (gidx == orig_gidx)
1274 fprintf (stderr, " no match\n");
1277 else if (debug_flag)
1278 fprintf (stderr, " match %d glyphs\n", gidx - orig_gidx);
1283 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1285 return ((c < 0 || c >= 256)
1287 : sub->f.f0->glyphIdArray[c]);
1291 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1297 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1300 OTF_EncodingSubtable4 *sub4;
1305 segCount = sub4->segCountX2 / 2;
1306 for (i = 0; i < segCount; i++)
1308 OTF_cmapSegment *seg = sub4->segments + i;
1310 if (c >= seg->startCount && c <= seg->endCount)
1312 if (seg->idRangeOffset == 0xFFFF)
1313 return c + seg->idDelta;
1315 return sub4->glyphIdArray[seg->idRangeOffset
1316 + (c - seg->startCount)];
1323 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1329 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1335 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1341 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1343 OTF_EncodingSubtable12 *sub12;
1344 OTF_cmapGroup *g, *gend;
1350 gend = sub12->Groups + sub12->nGroups;
1353 if (g->startCharCode <= c && c <= g->endCharCode)
1354 return (g->startGlyphID + (c - g->startCharCode));
1360 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1362 static lookup_cmap_func lookup_cmap_func_table[] =
1364 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1365 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1369 get_GlyphID (OTF_cmap *cmap, int c)
1371 OTF_EncodingSubtable *sub;
1372 lookup_cmap_func lookupper;
1374 if (c < 0x10000 && cmap->unicode_table)
1375 return cmap->unicode_table[c];
1376 if (cmap->table_index < 0)
1378 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1379 lookupper = lookup_cmap_func_table[sub->format / 2];
1380 return lookupper (c, sub);
1384 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1386 unsigned nRecords = sub14->nRecords;
1387 OTF_VariationSelectorRecord *record;
1390 for (i = 0; i < nRecords; i++)
1392 record = &sub14->Records[i];
1393 if (record->varSelector == c2)
1395 if (record->defaultUVSOffset)
1397 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1398 unsigned numUVRs = record->numUnicodeValueRanges;
1399 unsigned top = numUVRs, bottom = 0, middle;
1401 if (uVRs[0].startUnicodeValue <= c1)
1403 unsigned additionalCount, startUnicodeValue;
1407 middle = (top + bottom) / 2;
1408 if (c1 < uVRs[middle].startUnicodeValue)
1410 else if (bottom == middle)
1415 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1416 additionalCount = uVRs[bottom].additionalCount;
1417 if (c1 <= startUnicodeValue + additionalCount)
1418 return get_GlyphID (cmap, c1);
1421 if (record->nonDefaultUVSOffset)
1423 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1424 unsigned numUVSMs = record->numUVSMappings;
1425 unsigned top = numUVSMs, bottom = 0, middle;
1427 if (uvsMappings[0].unicodeValue <= c1)
1431 middle = (top + bottom) / 2;
1432 if (c1 < uvsMappings[middle].unicodeValue)
1434 else if (bottom == middle)
1439 if (uvsMappings[bottom].unicodeValue == c1)
1440 return uvsMappings[bottom].glyphID;
1450 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1452 OTF_EncodingSubtable14 *sub14;
1453 int c1 = gstring->glyphs[idx - 1].c;
1454 int c2 = gstring->glyphs[idx].c;
1458 gstring->glyphs[idx].glyph_id = 0;
1459 for (i = 0; i < cmap->numTables; i++)
1460 if (cmap->EncodingRecord[i].subtable.format == 14)
1462 if (i == cmap->numTables)
1464 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1467 gstring->glyphs[idx - 1].glyph_id = code;
1468 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1470 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1471 sizeof (OTF_Glyph) * (gstring->used - idx));
1477 /* Table of GlyphClass and MarkAttackClass.
1479 For the Nth element CHAR, CHAR and the succeeding characters
1480 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1482 This table is generated from the General Category (GC) property of
1483 characters defined in the Unicode Character Database. */
1485 static int glyph_class_table[] =
1486 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1487 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1488 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1489 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1490 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1491 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1492 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1493 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1494 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1495 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1496 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1497 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1498 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1499 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1500 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1501 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1502 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1503 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1504 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1505 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1506 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1507 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1508 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1509 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1510 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1511 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1512 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1513 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1514 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1516 int get_class_def_auto (int c)
1518 static int table_size
1519 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1522 if (c >= glyph_class_table[table_size - 1])
1525 high = table_size - 1;
1528 mid = (low + high) / 2;
1529 if (c < glyph_class_table[mid])
1531 else if (c >= glyph_class_table[mid + 1])
1536 return ((mid % 2) ? 3 : 1);
1544 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1547 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1551 OTF_EncodingSubtable *sub;
1552 lookup_cmap_func lookupper;
1555 && OTF_get_table (otf, "cmap") < 0)
1559 if (cmap->table_index < 0)
1563 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1564 lookupper = lookup_cmap_func_table[sub->format / 2];
1566 for (i = 0; i < gstring->used; i++)
1567 if (! gstring->glyphs[i].glyph_id)
1569 int c = gstring->glyphs[i].c;
1570 if (c < 32 || ! cmap->unicode_table)
1571 gstring->glyphs[i].glyph_id = 0;
1572 else if (UVS_P (c) && i > 0)
1573 check_cmap_uvs (cmap, gstring, i);
1574 else if (c < 0x10000)
1575 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1577 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1584 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1585 int platform_id, int encoding_id)
1589 char *errfmt = "CMAP Looking up%s";
1591 OTF_EncodingRecord *enc;
1592 lookup_cmap_func lookupper;
1595 && OTF_get_table (otf, "cmap") < 0)
1599 for (i = 0; i < cmap->numTables; i++)
1600 if (cmap->EncodingRecord[i].platformID == platform_id
1601 && cmap->EncodingRecord[i].encodingID == encoding_id)
1603 if (i == cmap->numTables)
1604 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1605 enc = cmap->EncodingRecord + i;
1606 if (enc->subtable.format > 12)
1607 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1608 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1610 for (i = 0; i < gstring->used; i++)
1611 if (! gstring->glyphs[i].glyph_id)
1613 int c = gstring->glyphs[i].c;
1614 if (c < 32 || ! cmap->unicode_table)
1615 gstring->glyphs[i].glyph_id = 0;
1616 else if (UVS_P (c) && i > 0)
1617 check_cmap_uvs (cmap, gstring, i);
1618 else if (c < 0x10000)
1619 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1621 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1627 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1630 && OTF_get_table (otf, "cmap") < 0)
1633 || code > otf->cmap->max_glyph_id
1634 || ! otf->cmap->decode_table)
1636 return otf->cmap->decode_table[code];
1640 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1644 OTF_EncodingSubtable14 *sub14;
1646 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1648 && OTF_get_table (otf, "cmap") < 0)
1651 for (i = 0; i < cmap->numTables; i++)
1652 if (cmap->EncodingRecord[i].subtable.format == 14)
1654 if (i == cmap->numTables)
1656 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1657 for (i = 0, n = 0; i < 256; i++)
1659 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1661 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1669 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1675 && OTF_get_table (otf, "GDEF") < 0)
1679 if (gdef->glyph_class_def.offset)
1680 for (i = 0; i < gstring->used; i++)
1681 gstring->glyphs[i].GlyphClass
1682 = get_class_def (&gdef->glyph_class_def,
1683 gstring->glyphs[i].glyph_id);
1685 for (i = 0; i < gstring->used; i++)
1686 gstring->glyphs[i].GlyphClass
1687 = get_class_def_auto (gstring->glyphs[i].c);
1689 if (gdef->mark_attach_class_def.offset)
1690 for (i = 0; i < gstring->used; i++)
1691 gstring->glyphs[i].MarkAttachClass
1692 = get_class_def (&gdef->mark_attach_class_def,
1693 gstring->glyphs[i].glyph_id);
1699 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1700 const char *script, const char *language,
1701 const char *features,
1702 int alternate_subst)
1704 char *errfmt = "GSUB driving%s";
1707 OTF_LangSys *LangSys;
1711 for (i = 0; i < gstring->used; i++)
1713 gstring->glyphs[i].positioning_type = 0;
1714 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1717 if (OTF_get_table (otf, "GSUB") < 0)
1720 if (gsub->FeatureList.FeatureCount == 0
1721 || gsub->LookupList.LookupCount == 0)
1724 LangSys = get_langsys (&gsub->ScriptList, script, language);
1728 lookup_flags = alloca (gsub->LookupList.LookupCount);
1730 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1731 features, lookup_flags) < 0)
1732 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1734 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1738 if (! lookup_flags[i]) continue;
1740 if (gsub->LookupList.Lookup[i].LookupType != 8)
1743 while (gidx < gstring->used)
1745 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1753 gidx = gstring->used - 1;
1756 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1768 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1769 const char *script, const char *language, const char *features)
1772 OTF_get_table (otf, "cmap");
1773 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
1777 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1778 const char *script, const char *language,
1779 const char *features,
1782 char *errfmt = "GPOS driving%s";
1785 OTF_LangSys *LangSys;
1789 for (i = 0; i < gstring->used; i++)
1790 gstring->glyphs[i].positioning_type = 0;
1792 if (OTF_get_table (otf, "GPOS") < 0)
1795 if (gpos->FeatureList.FeatureCount == 0
1796 || gpos->LookupList.LookupCount == 0)
1799 LangSys = get_langsys (&gpos->ScriptList, script, language);
1803 lookup_flags = alloca (gpos->LookupList.LookupCount);
1805 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1806 features, lookup_flags) < 0)
1807 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1809 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1813 if (! lookup_flags[i]) continue;
1815 while (gidx < gstring->used)
1817 gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
1827 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1828 const char *script, const char *language, const char *features)
1831 OTF_get_table (otf, "cmap");
1832 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
1836 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1837 const char *script, const char *language, const char *features)
1840 OTF_get_table (otf, "cmap");
1841 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
1845 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1846 const char *script, const char *language,
1847 const char *gsub_features, const char *gpos_features)
1849 if (OTF_drive_cmap (otf, gstring) < 0)
1851 if (OTF_drive_gdef (otf, gstring) < 0)
1854 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1857 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1863 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1864 const char *script, const char *language,
1865 const char *features)
1867 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
1871 iterate_coverage (OTF *otf, const char *feature,
1872 OTF_Feature_Callback callback,
1873 OTF_Coverage *coverage)
1877 if (coverage->CoverageFormat == 1)
1879 for (i = 0; i < coverage->Count; i++)
1880 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1885 for (i = 0; i < coverage->Count; i++)
1887 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1889 for (id = range->Start; id <= range->End; id++)
1890 if (callback (otf, feature, id) < 0)
1898 iterate_feature (OTF *otf, const char *feature,
1899 OTF_Feature_Callback callback,
1904 for (i = 0; i < lookup->SubTableCount; i++)
1906 unsigned lookup_type = lookup->LookupType;
1907 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1909 if (lookup_type == 7)
1911 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
1913 lookup_type = extension1->ExtensionLookupType;
1914 subtable = extension1->ExtensionSubtable;
1917 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
1919 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1923 else if (lookup_type == 4)
1925 OTF_GSUB_Ligature1 *lig1;
1927 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1930 lig1 = &subtable->u.ligature1;
1931 for (j = 0; j < lig1->LigSetCount; j++)
1933 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
1935 for (k = 0; k < ligset->LigatureCount; k++)
1937 OTF_Ligature *lig = ligset->Ligature + k;
1938 for (l = 0; l < lig->CompCount - 1; l++)
1939 if (callback (otf, feature, lig->Component[l]) < 0)
1944 else if (lookup_type == 6)
1946 if (subtable->Format == 1)
1948 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
1949 for (j = 0; j < context1->ChainRuleSetCount; j++)
1951 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
1952 for (k = 0; k < set->ChainRuleCount; k++)
1954 OTF_ChainRule *rule = set->ChainRule + k;
1955 for (l = 0; l < rule->LookupCount; l++)
1958 = (otf->gsub->LookupList.Lookup
1959 + rule->LookupRecord[l].LookupListIndex);
1960 if (iterate_feature (otf, feature, callback, lkup)
1967 else if (subtable->Format == 2)
1969 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
1971 for (j = 0; j < context2->ChainClassSetCnt; j++)
1973 OTF_ChainClassSet *set = context2->ChainClassSet + j;
1974 for (k = 0; k < set->ChainClassRuleCnt; j++)
1976 OTF_ChainClassRule *rule = set->ChainClassRule + k;
1978 for (l = 0; l < rule->LookupCount; l++)
1981 = (otf->gsub->LookupList.Lookup
1982 + rule->LookupRecord[k].LookupListIndex);
1983 if (iterate_feature (otf, feature, callback, lkup)
1992 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
1993 for (j = 0; j < context3->LookupCount; j++)
1996 = (otf->gsub->LookupList.Lookup
1997 + context3->LookupRecord[j].LookupListIndex);
1998 if (iterate_feature (otf, feature, callback, lkup) < 0)
2008 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2009 const char *script, const char *language,
2010 const char *feature)
2012 char *errfmt = "GSUB iterate feature%s";
2017 OTF_LangSys *langsys;
2020 if (OTF_get_table (otf, "GSUB") < 0)
2023 if (gsub->FeatureList.FeatureCount == 0
2024 || gsub->LookupList.LookupCount == 0)
2026 langsys = get_langsys (&gsub->ScriptList, script, language);
2029 lookup_flags = alloca (gsub->LookupList.LookupCount);
2031 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2032 feature, lookup_flags) < 0)
2033 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2035 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2036 if (lookup_flags[i])
2037 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)