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;
125 prepare_drive_log (OTF_DriveLog *log, int size)
127 if (size > log->allocated)
130 int allocated = log->allocated;
132 while (size > allocated)
134 tags = realloc (log->tags, sizeof (OTF_Tag) * log->allocated);
137 log->allocated = allocated;
147 get_coverage_index (OTF_Coverage *coverage, OTF_GlyphID id)
151 if (coverage->CoverageFormat == 1)
153 for (i = 0; i < coverage->Count; i++)
154 if (coverage->table.GlyphArray[i] == id)
159 for (i = 0; i < coverage->Count; i++)
160 if (coverage->table.RangeRecord[i].Start <= id
161 && coverage->table.RangeRecord[i].End >= id)
162 return (coverage->table.RangeRecord[i].StartCoverageIndex
163 + (id - coverage->table.RangeRecord[i].Start));
169 get_class_def (OTF_ClassDef *class_def, OTF_GlyphID glyph_id)
171 if (class_def->ClassFormat == 1)
173 int idx = (int) glyph_id - (int) class_def->f.f1.StartGlyph;
175 if (idx >= 0 && idx < class_def->f.f1.GlyphCount)
176 return class_def->f.f1.ClassValueArray[idx];
182 for (i = 0; i < class_def->f.f2.ClassRangeCount; i++)
183 if (glyph_id >= class_def->f.f2.ClassRangeRecord[i].Start
184 && glyph_id <= class_def->f.f2.ClassRangeRecord[i].End)
185 return class_def->f.f2.ClassRangeRecord[i].Class;
191 get_langsys (OTF_ScriptList *script_list,
192 const char *script, const char *language)
195 OTF_Tag script_tag = OTF_tag (script);
196 OTF_Tag langsys_tag = OTF_tag (language);
198 OTF_Tag dflt_tag = OTF_tag ("DFLT");
199 OTF_Script *dflt = NULL;
201 for (i = 0; i < script_list->ScriptCount; i++)
203 OTF_Script *script = script_list->Script + i;
205 if (script_list->Script[i].ScriptTag == dflt_tag)
207 if (script_list->Script[i].ScriptTag == script_tag)
210 return &script->DefaultLangSys;
211 for (j = 0; j < script->LangSysCount; j++)
212 if (script->LangSysRecord[j].LangSysTag == langsys_tag)
213 return script->LangSys + j;
214 return &script->DefaultLangSys;
219 dflt = script_list->Script;
221 return &dflt->DefaultLangSys;
222 for (j = 0; j < dflt->LangSysCount; j++)
223 if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
224 return dflt->LangSys + j;
225 return &dflt->DefaultLangSys;
229 setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
230 OTF_LangSys *LangSys,
231 const char *features, char *lookup_flags)
234 OTF_Feature *feature;
235 int *feature_table = alloca (sizeof (int) * FeatureList->FeatureCount);
239 for (i = 0; i < FeatureList->FeatureCount; i++)
240 feature_table[i] = 0;
241 memset (lookup_flags, 0, LookupList->LookupCount);
249 if (*features == '*')
251 /* Consume all remaining features. */
252 for (i = 0; i < LangSys->FeatureCount; i++)
254 int index = LangSys->FeatureIndex[i];
256 if (! feature_table[index])
258 feature = FeatureList->Feature + index;
259 for (j = 0; j < feature->LookupCount; j++)
260 lookup_flags[feature->LookupListIndex[j]] = 1;
266 if (*features == '~')
267 use_it = -1, features++;
268 for (i = 0; *features && *features != ','; i++, features++)
269 tagname[i] = *features;
275 tag = OTF_tag (tagname);
276 for (i = 0; i < LangSys->FeatureCount; i++)
278 feature = FeatureList->Feature + LangSys->FeatureIndex[i];
279 if (tag == feature->FeatureTag)
281 if (feature_table[i])
284 for (j = 0; j < feature->LookupCount; j++)
285 lookup_flags[feature->LookupListIndex[j]] = 1;
286 feature_table[i] = use_it;
295 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
296 int count, OTF_GlyphID *ids, int direction)
298 OTF_Glyph *g = gstring->glyphs + gidx;
299 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
302 for (i = j = 0; i < count && g != gend; j++, g += direction)
303 if (! IGNORED_GLYPH (g, flag)
304 && g->glyph_id != ids[i++])
306 return (i < count ? -1 : j);
310 match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
313 int i = rule->BacktrackGlyphCount;
317 || match_ids (gstring, gidx - 1, flag, i, rule->Backtrack, -1) < 0))
320 i = match_ids (gstring, gidx, flag,
321 rule->InputGlyphCount - 1, rule->Input, 1);
325 i = match_ids (gstring, gidx, flag,
326 rule->LookaheadGlyphCount, rule->LookAhead, 1);
333 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
334 int flag, int count, unsigned *classes, int direction)
336 OTF_Glyph *g = gstring->glyphs + gidx;
337 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
340 for (i = j = 0; i < count && g != gend; j++, g += direction)
341 if (! IGNORED_GLYPH (g, flag)
342 && get_class_def (class_def, g->glyph_id) != classes[i++])
344 return (i < count ? -1 : j);
348 match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
349 OTF_ClassDef *BacktrackClassDef,
350 OTF_ClassDef *InputClassDef,
351 OTF_ClassDef *LookaheadClassDef,
352 OTF_ChainClassRule *rule)
354 int i = rule->BacktrackGlyphCount;
358 || match_classes (BacktrackClassDef, gstring, gidx - 1, flag, i,
359 rule->Backtrack, -1) < 0))
362 i = match_classes (InputClassDef, gstring, gidx, flag,
363 rule->InputGlyphCount - 1, rule->Input, 1);
367 i = match_classes (LookaheadClassDef, gstring, gidx, flag,
368 rule->LookaheadGlyphCount, rule->LookAhead, 1);
376 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
377 OTF_Coverage *coverages, int direction)
379 OTF_Glyph *g = gstring->glyphs + gidx;
380 OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : - 1);
383 for (i = j = 0; i < count && g != gend; j++, g += direction)
384 if (! IGNORED_GLYPH (g, flag)
385 && get_coverage_index (coverages + i++, g->glyph_id) < 0)
387 return (i < count ? -1 : j);
391 match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
392 OTF_GSUB_ChainContext3 *context3)
394 int i = context3->BacktrackGlyphCount;
398 || match_coverages (gstring, gidx - 1, flag, i,
399 context3->Backtrack, -1) < 0))
402 if (context3->InputGlyphCount > 1)
404 i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
405 context3->Input + 1, 1);
410 if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
411 context3->LookAhead, 1) < 0)
417 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
418 OTF_GlyphString *gstring, int gidx, int alternate_subst)
420 char *errfmt = "GSUB Looking up%s";
422 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
423 unsigned int flag = (lookup->LookupFlag
424 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
425 int orig_gidx = gidx;
426 OTF_Glyph *g = gstring->glyphs + gidx;
429 if (IGNORED_GLYPH (g, flag))
432 /* Try all subtables until one of them handles the current glyph. */
433 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
435 unsigned lookup_type = lookup->LookupType;
436 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
439 if (lookup_type == 7)
441 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
443 lookup_type = extension1->ExtensionLookupType;
444 subtable = extension1->ExtensionSubtable;
448 ? (lookup_type != 3 && lookup_type != 5 && lookup_type != 6)
449 : (lookup_type == 3))
452 if (subtable->Coverage.offset)
454 coverage_idx = get_coverage_index (&subtable->Coverage,
456 if (coverage_idx < 0)
463 if (subtable->Format == 1)
464 g->glyph_id += subtable->u.single1.DeltaGlyphID;
466 g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
471 if (subtable->Format == 1)
473 OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
474 OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
476 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
477 seq->Substitute, seq->GlyphCount);
478 gidx += seq->GlyphCount;
481 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
485 if (subtable->Format == 1)
487 OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
488 OTF_AlternateSet *altset = alt1->AlternateSet + coverage_idx;
490 gstring_subst (otf, gstring, gidx, gidx + 1, flag,
491 altset->Alternate, altset->GlyphCount);
492 gidx += altset->GlyphCount;;
495 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
499 if (subtable->Format == 1)
501 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
502 OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
506 for (j = 0; j < ligset->LigatureCount; j++)
510 lig = ligset->Ligature + j;
511 n = match_ids (gstring, gidx + 1, flag,
512 lig->CompCount - 1, lig->Component, 1);
515 gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
522 OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
526 if (subtable->Format == 1)
528 OTF_GSUB_Context1 *context1 = &subtable->u.context1;
529 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
534 for (j = 0; j < set->RuleCount; j++)
536 rule = set->Rule + j;
537 if (match_ids (gstring, gidx + 1, flag,
538 rule->GlyphCount - 1, rule->Input, 1) < 0)
540 orig_used = gstring->used;
541 for (k = 0; k < rule->LookupCount; k++)
542 lookup_gsub (otf, lookup_list,
543 rule->LookupRecord[k].LookupListIndex,
545 gidx + rule->LookupRecord[k].SequenceIndex,
547 gidx += rule->GlyphCount + (gstring->used - orig_used);
551 else if (subtable->Format == 2)
553 OTF_GSUB_Context2 *context2 = &subtable->u.context2;
560 class = get_class_def (&context2->ClassDef, g->glyph_id);
561 set = context2->ClassSet + class;
563 for (j = 0; j < set->ClassRuleCnt; j++)
565 rule = set->ClassRule + j;
566 if (match_classes (&context2->ClassDef,
567 gstring, gidx + 1, flag,
568 rule->GlyphCount - 1, rule->Class, 1)
571 orig_used = gstring->used;
572 for (k = 0; k < rule->LookupCount; k++)
573 lookup_gsub (otf, lookup_list,
574 rule->LookupRecord[k].LookupListIndex,
576 gidx + rule->LookupRecord[k].SequenceIndex,
578 gidx += rule->GlyphCount + (gstring->used - orig_used);
582 else /* subtable->Format == 3 */
584 OTF_GSUB_Context3 *context3 = &subtable->u.context3;
588 if (match_coverages (gstring, gidx + 1, flag,
589 context3->GlyphCount - 1,
590 context3->Coverage + 1, 1) < 0)
592 orig_used = gstring->used;
593 for (j = 0; j < context3->LookupCount; j++)
594 lookup_gsub (otf, lookup_list,
595 context3->LookupRecord[j].LookupListIndex,
597 gidx + context3->LookupRecord[j].SequenceIndex,
599 gidx += context3->GlyphCount + (gstring->used - orig_used);
604 if (subtable->Format == 1)
606 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
607 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
611 for (j = 0; j < set->ChainRuleCount; j++)
613 OTF_ChainRule *rule = set->ChainRule + j;
615 if (gidx < rule->BacktrackGlyphCount
616 || (gidx + rule->InputGlyphCount
617 + rule->LookaheadGlyphCount) > gstring->used)
619 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
621 orig_used = gstring->used;
622 for (k = 0; k < rule->LookupCount; k++)
623 lookup_gsub (otf, lookup_list,
624 rule->LookupRecord[k].LookupListIndex,
626 gidx + rule->LookupRecord[k].SequenceIndex,
628 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
632 else if (subtable->Format == 2)
634 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
635 OTF_ChainClassSet *set;
640 class = get_class_def (&context2->InputClassDef, g->glyph_id);
641 set = context2->ChainClassSet + class;
642 for (j = 0; j < set->ChainClassRuleCnt; j++)
644 OTF_ChainClassRule *rule = set->ChainClassRule + j;
647 if (gidx < rule->BacktrackGlyphCount
648 || (gidx + rule->InputGlyphCount
649 + rule->LookaheadGlyphCount) > gstring->used)
651 if (match_chain_classes (gstring, gidx, flag,
652 &context2->BacktrackClassDef,
653 &context2->InputClassDef,
654 &context2->LookaheadClassDef,
657 orig_used = gstring->used;
658 for (k = 0; k < rule->LookupCount; k++)
659 lookup_gsub (otf, lookup_list,
660 rule->LookupRecord[k].LookupListIndex,
662 gidx + rule->LookupRecord[k].SequenceIndex,
664 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
670 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
674 if (gidx < context3->BacktrackGlyphCount
675 || (gidx + context3->InputGlyphCount
676 + context3->LookaheadGlyphCount) > gstring->used)
678 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
680 orig_used = gstring->used;
681 for (j = 0; j < context3->LookupCount; j++)
682 lookup_gsub (otf, lookup_list,
683 context3->LookupRecord[j].LookupListIndex,
685 gidx + context3->LookupRecord[j].SequenceIndex,
687 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
693 OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
694 int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
695 int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
698 if (back_gidx > gstring->used || ahead_gidx < 0)
701 for (j = 0; j < reverse->BacktrackGlyphCount; j++)
702 if (get_coverage_index (reverse->Backtrack + j,
703 gstring->glyphs[gidx + 1 + j].glyph_id)
706 if (j < reverse->BacktrackGlyphCount)
708 for (j = 0; j < reverse->LookaheadGlyphCount; j++)
709 if (get_coverage_index (reverse->LookAhead + j,
710 gstring->glyphs[gidx - 1 - j].glyph_id)
713 if (j < reverse->LookaheadGlyphCount)
715 g->glyph_id = reverse->Substitute[coverage_idx];
723 if (gidx == orig_gidx)
733 gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
736 int orig_gidx = gidx++;
738 while (gidx < gstring->used
739 && ! gstring->glyphs[gidx].glyph_id
740 && gstring->glyphs[gidx].positioning_type)
742 GSTRING_INSERT (gstring, gidx, 1);
743 gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
744 gstring->glyphs[gidx].glyph_id = 0;
749 print_anchor (char *head, OTF_Anchor *anchor)
751 if (anchor->AnchorFormat == 1)
752 fprintf (stderr, " %s(X:%d Y:%d)", head,
753 anchor->XCoordinate, anchor->YCoordinate);
754 else if (anchor->AnchorFormat == 2)
755 fprintf (stderr, " %s(X:%d Y:%d AP:%d)", head,
756 anchor->XCoordinate, anchor->YCoordinate,
757 anchor->f.f1.AnchorPoint);
759 fprintf (stderr, " %s(X:%d Y:%d +alpha)", head,
760 anchor->XCoordinate, anchor->YCoordinate);
764 print_glyph_positioning (OTF_Glyph *g, int type)
767 fprintf (stderr, " %0X=", g->glyph_id);
768 switch (g->positioning_type)
772 int format = g->f.f1.format;
774 if (format & OTF_XPlacement)
775 fprintf (stderr, "X:%d", g->f.f1.value->XPlacement);
776 if (format & OTF_XPlaDevice)
777 fprintf (stderr, "+alpha");
778 if (format & OTF_YPlacement)
779 fprintf (stderr, "Y:%d", g->f.f1.value->YPlacement);
780 if (format & OTF_YPlaDevice)
781 fprintf (stderr, "+alpha");
782 if (format & OTF_XAdvance)
783 fprintf (stderr, "X+:%d", g->f.f1.value->XAdvance);
784 if (format & OTF_XAdvDevice)
785 fprintf (stderr, "+alpha");
789 print_anchor ("entry", g->f.f3.entry_anchor);
790 print_anchor ("exit", g->f.f3.entry_anchor);
793 print_anchor ("mark", g->f.f4.mark_anchor);
794 print_anchor ("base", g->f.f4.base_anchor);
797 print_anchor ("mark", g->f.f5.mark_anchor);
798 print_anchor ("lig", g->f.f5.ligature_anchor);
801 print_anchor ("mark1", g->f.f6.mark1_anchor);
802 print_anchor ("mark2", g->f.f6.mark2_anchor);
808 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
809 OTF_GlyphString *gstring, int gidx, int accumulate)
811 char *errfmt = "GPOS Looking up%s";
813 OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
814 unsigned int flag = (lookup->LookupFlag
815 & (OTF_LookupFlagIgnoreMask | OTF_MarkAttachmentType));
816 int orig_gidx = gidx;
817 OTF_Glyph *g = gstring->glyphs + gidx;
821 fprintf (stderr, "[GPOS] glyph:%04X lookup:%02d",
822 g->glyph_id, lookup_list_index);
823 if (IGNORED_GLYPH (g, flag))
826 fprintf (stderr, " glyph ignored\n");
830 /* Try all subtables until one of them handles the current glyph. */
831 for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
833 unsigned lookup_type = lookup->LookupType;
834 OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
836 int positioning_type;
837 enum OTF_ValueFormat format;
838 OTF_ValueRecord *value;
839 OTF_Anchor *anchor1, *anchor2;
841 if (lookup_type == 9)
843 OTF_GPOS_Extension1 *extension1 = &subtable->u.extension1;
845 lookup_type = extension1->ExtensionLookupType;
846 subtable = extension1->ExtensionSubtable;
850 fprintf (stderr, "/%d", lookup_type);
851 if (subtable->Coverage.offset)
853 coverage_idx = get_coverage_index (&subtable->Coverage,
855 if (coverage_idx < 0)
862 positioning_type = lookup_type;
863 if (subtable->Format == 1)
865 OTF_GPOS_Single1 *single1 = &subtable->u.single1;
867 format = single1->ValueFormat;
868 value = &single1->Value;
870 else if (subtable->Format == 2)
872 OTF_GPOS_Single2 *single2 = &subtable->u.single2;
874 format = single2->ValueFormat;
875 value = single2->Value + coverage_idx;
877 if (accumulate && g->positioning_type)
879 gidx = gstring_insert_for_gpos (gstring, gidx);
880 g = gstring->glyphs + gidx;
882 g->positioning_type = positioning_type;
883 g->f.f1.format = format;
884 g->f.f1.value = value;
886 print_glyph_positioning (g, 0);
895 for (next_gidx = gidx + 1, nextg = gstring->glyphs + next_gidx;
896 next_gidx < gstring->used && IGNORED_GLYPH (nextg, flag);
897 next_gidx++, nextg++);
899 if (next_gidx >= gstring->used)
901 if (subtable->Format == 1)
903 OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
904 OTF_PairSet *set = pair1->PairSet + coverage_idx;
907 for (j = 0; j < set->PairValueCount; j++)
908 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
910 if (pair1->ValueFormat1)
912 if (accumulate && g->positioning_type)
914 gidx = gstring_insert_for_gpos (gstring, gidx);
915 g = gstring->glyphs + gidx;
916 next_gidx += gidx - orig_gidx;
917 nextg = gstring->glyphs + next_gidx;
919 g->positioning_type = lookup_type;
920 g->f.f2.format = pair1->ValueFormat1;
921 g->f.f2.value = &set->PairValueRecord[j].Value1;
923 print_glyph_positioning (g, 1);
927 if (pair1->ValueFormat2)
929 if (accumulate && g->positioning_type)
931 gidx = gstring_insert_for_gpos (gstring, gidx);
932 g = gstring->glyphs + gidx;
934 g->positioning_type = lookup_type;
935 g->f.f2.format = pair1->ValueFormat2;
936 g->f.f2.value = &set->PairValueRecord[j].Value2;
938 print_glyph_positioning (g, 2);
943 else if (subtable->Format == 2)
945 OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
946 unsigned class1, class2;
948 class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
949 class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
950 if (pair2->ValueFormat1)
952 if (accumulate && g->positioning_type)
954 gidx = gstring_insert_for_gpos (gstring, gidx);
955 g = gstring->glyphs + gidx;
956 next_gidx += gidx - orig_gidx;
957 nextg = gstring->glyphs + next_gidx;
959 g->positioning_type = lookup_type;
960 g->f.f2.format = pair2->ValueFormat1;
962 = &pair2->Class1Record[class1].Class2Record[class2].Value1;
964 print_glyph_positioning (g, 1);
968 if (pair2->ValueFormat2)
970 if (accumulate && g->positioning_type)
972 gidx = gstring_insert_for_gpos (gstring, gidx);
973 g = gstring->glyphs + gidx;
975 g->positioning_type = lookup_type;
976 g->f.f2.format = pair2->ValueFormat2;
978 = &pair2->Class1Record[class1].Class2Record[class2].Value2;
980 print_glyph_positioning (g, 2);
988 OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
990 g->positioning_type = lookup_type;
992 = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
994 = &cursive1->EntryExitRecord[coverage_idx].ExitAnchor;
996 print_glyph_positioning (g, 0);
1004 if (subtable->Format == 1)
1006 OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
1007 OTF_MarkRecord *mark_record;
1008 OTF_AnchorRecord *base_record;
1010 int coverage_idx_base;
1011 unsigned int this_flag = flag | OTF_IgnoreMarks;
1014 baseg >= gstring->glyphs && IGNORED_GLYPH (baseg, this_flag);
1016 if (baseg < gstring->glyphs)
1019 = get_coverage_index (&mark_base1->BaseCoverage,
1021 if (coverage_idx_base < 0)
1023 mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
1025 = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
1026 g->f.f4.mark_anchor = &mark_record->MarkAnchor;
1028 = &base_record->Anchor[mark_record->Class];
1029 g->positioning_type = lookup_type;
1031 print_glyph_positioning (g, 0);
1039 if (subtable->Format == 1)
1041 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1043 int coverage_idx_lig;
1044 OTF_MarkRecord *mark_record;
1045 OTF_LigatureAttach *attach;
1046 int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
1049 for (j = 0; j < mark_lig1->ClassCount; j++)
1053 (ligg >= gstring->glyphs
1054 && (IGNORED_GLYPH (ligg, flag)
1055 || ligg->GlyphClass > OTF_GlyphClassLigature));
1057 if (ligg->positioning_type == 5
1058 && ligg->MarkAttachClass < mark_lig1->ClassCount)
1059 num_class[ligg->MarkAttachClass]++;
1060 if (ligg < gstring->glyphs)
1063 = get_coverage_index (&mark_lig1->LigatureCoverage,
1065 if (coverage_idx_lig < 0)
1067 mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
1068 g->MarkAttachClass = mark_record->Class;
1069 attach = (mark_lig1->LigatureArray.LigatureAttach
1070 + coverage_idx_lig);
1071 for (j = 0; j < attach->ComponentCount; j++)
1073 OTF_Anchor *lig_anchor
1074 = attach->ComponentRecord[j].LigatureAnchor;
1076 if (lig_anchor[mark_record->Class].AnchorFormat
1077 && num_class[mark_record->Class]-- == 0)
1079 g->positioning_type = lookup_type;
1080 g->f.f5.mark_anchor = &mark_record->MarkAnchor;
1081 g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
1083 print_glyph_positioning (g, 0);
1094 if (subtable->Format == 1)
1096 OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
1097 OTF_MarkRecord *mark1_record;
1098 OTF_AnchorRecord *mark2_record;
1100 int coverage_idx_base;
1103 prevg >= gstring->glyphs && IGNORED_GLYPH (prevg, flag);
1105 if (prevg < gstring->glyphs)
1108 = get_coverage_index (&mark_mark1->Mark2Coverage,
1110 if (coverage_idx_base < 0)
1112 mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
1114 = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
1115 g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
1116 g->f.f6.mark2_anchor
1117 = &mark2_record->Anchor[mark1_record->Class];
1118 g->positioning_type = lookup_type;
1120 print_glyph_positioning (g, 0);
1127 if (subtable->Format == 1)
1129 OTF_GPOS_Context1 *context1 = &subtable->u.context1;
1130 OTF_RuleSet *set = context1->RuleSet + coverage_idx;
1135 for (j = 0; j < set->RuleCount; j++)
1137 rule = set->Rule + j;
1138 if (match_ids (gstring, gidx + 1, flag,
1139 rule->GlyphCount - 1, rule->Input, 1) < 0)
1141 orig_used = gstring->used;
1142 for (k = 0; k < rule->LookupCount; k++)
1143 lookup_gpos (lookup_list,
1144 rule->LookupRecord[k].LookupListIndex,
1146 gidx + rule->LookupRecord[k].SequenceIndex,
1148 gidx += rule->GlyphCount + (gstring->used - orig_used);
1152 else if (subtable->Format == 2)
1154 OTF_GPOS_Context2 *context2 = &subtable->u.context2;
1156 OTF_ClassRule *rule;
1161 class = get_class_def (&context2->ClassDef, g->glyph_id);
1162 set = context2->ClassSet + class;
1164 for (j = 0; j < set->ClassRuleCnt; j++)
1166 rule = set->ClassRule + j;
1167 if (match_classes (&context2->ClassDef,
1168 gstring, gidx + 1, flag,
1169 rule->GlyphCount - 1, rule->Class, 1)
1172 orig_used = gstring->used;
1173 for (k = 0; k < rule->LookupCount; k++)
1174 lookup_gpos (lookup_list,
1175 rule->LookupRecord[k].LookupListIndex,
1177 gidx + rule->LookupRecord[k].SequenceIndex,
1179 gidx += rule->GlyphCount + (gstring->used - orig_used);
1183 else /* subtable->Format == 3 */
1185 OTF_GPOS_Context3 *context3 = &subtable->u.context3;
1189 if (match_coverages (gstring, gidx + 1, flag,
1190 context3->GlyphCount - 1,
1191 context3->Coverage + 1, 1) < 0)
1193 orig_used = gstring->used;
1194 for (j = 0; j < context3->LookupCount; j++)
1195 lookup_gpos (lookup_list,
1196 context3->LookupRecord[j].LookupListIndex,
1198 gidx + context3->LookupRecord[j].SequenceIndex,
1200 gidx += context3->GlyphCount + (gstring->used - orig_used);
1205 if (subtable->Format == 1)
1207 OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
1208 OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
1212 for (j = 0; j < set->ChainRuleCount; j++)
1214 OTF_ChainRule *rule = set->ChainRule + j;
1216 if (gidx < rule->BacktrackGlyphCount
1217 || (gidx + rule->InputGlyphCount
1218 + rule->LookaheadGlyphCount) > gstring->used)
1220 if (match_chain_ids (gstring, gidx, flag, rule) < 0)
1222 orig_used = gstring->used;
1223 for (k = 0; k < rule->LookupCount; k++)
1224 lookup_gpos (lookup_list,
1225 rule->LookupRecord[k].LookupListIndex,
1227 gidx + rule->LookupRecord[k].SequenceIndex,
1229 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1233 else if (subtable->Format == 2)
1235 OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
1236 OTF_ChainClassSet *set;
1241 class = get_class_def (&context2->InputClassDef, g->glyph_id);
1242 set = context2->ChainClassSet + class;
1243 for (j = 0; j < set->ChainClassRuleCnt; j++)
1245 OTF_ChainClassRule *rule = set->ChainClassRule + j;
1248 if (gidx < rule->BacktrackGlyphCount
1249 || (gidx + rule->InputGlyphCount
1250 + rule->LookaheadGlyphCount) > gstring->used)
1252 if (match_chain_classes (gstring, gidx, flag,
1253 &context2->BacktrackClassDef,
1254 &context2->InputClassDef,
1255 &context2->LookaheadClassDef,
1258 orig_used = gstring->used;
1259 for (k = 0; k < rule->LookupCount; k++)
1260 lookup_gpos (lookup_list,
1261 rule->LookupRecord[k].LookupListIndex,
1263 gidx + rule->LookupRecord[k].SequenceIndex,
1265 gidx += rule->InputGlyphCount + (gstring->used - orig_used);
1269 else if (subtable->Format == 3)
1271 OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
1275 if (gidx < context3->BacktrackGlyphCount
1276 || (gidx + context3->InputGlyphCount
1277 + context3->LookaheadGlyphCount) > gstring->used)
1279 if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
1281 orig_used = gstring->used;
1282 for (j = 0; j < context3->LookupCount; j++)
1283 lookup_gpos (lookup_list,
1284 context3->LookupRecord[j].LookupListIndex,
1286 gidx + context3->LookupRecord[j].SequenceIndex,
1288 gidx += context3->InputGlyphCount + (gstring->used - orig_used);
1291 OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
1298 if (gidx == orig_gidx)
1301 fprintf (stderr, " no match\n");
1304 else if (debug_flag)
1305 fprintf (stderr, "\n");
1310 lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
1312 return ((c < 0 || c >= 256)
1314 : sub->f.f0->glyphIdArray[c]);
1318 lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
1324 lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
1327 OTF_EncodingSubtable4 *sub4;
1332 segCount = sub4->segCountX2 / 2;
1333 for (i = 0; i < segCount; i++)
1335 OTF_cmapSegment *seg = sub4->segments + i;
1337 if (c >= seg->startCount && c <= seg->endCount)
1339 if (seg->idRangeOffset == 0xFFFF)
1340 return c + seg->idDelta;
1342 return sub4->glyphIdArray[seg->idRangeOffset
1343 + (c - seg->startCount)];
1350 lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
1356 lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
1362 lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
1368 lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
1370 OTF_EncodingSubtable12 *sub12;
1371 OTF_cmapGroup *g, *gend;
1377 gend = sub12->Groups + sub12->nGroups;
1380 if (g->startCharCode <= c && c <= g->endCharCode)
1381 return (g->startGlyphID + (c - g->startCharCode));
1387 typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
1389 static lookup_cmap_func lookup_cmap_func_table[] =
1391 lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
1392 lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
1396 get_GlyphID (OTF_cmap *cmap, int c)
1398 OTF_EncodingSubtable *sub;
1399 lookup_cmap_func lookupper;
1401 if (c < 0x10000 && cmap->unicode_table)
1402 return cmap->unicode_table[c];
1403 if (cmap->table_index < 0)
1405 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1406 lookupper = lookup_cmap_func_table[sub->format / 2];
1407 return lookupper (c, sub);
1411 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
1413 unsigned nRecords = sub14->nRecords;
1414 OTF_VariationSelectorRecord *record;
1417 for (i = 0; i < nRecords; i++)
1419 record = &sub14->Records[i];
1420 if (record->varSelector == c2)
1422 if (record->defaultUVSOffset)
1424 OTF_UnicodeValueRange *uVRs = record->unicodeValueRanges;
1425 unsigned numUVRs = record->numUnicodeValueRanges;
1426 unsigned top = numUVRs, bottom = 0, middle;
1428 if (uVRs[0].startUnicodeValue <= c1)
1430 unsigned additionalCount, startUnicodeValue;
1434 middle = (top + bottom) / 2;
1435 if (c1 < uVRs[middle].startUnicodeValue)
1437 else if (bottom == middle)
1442 startUnicodeValue = uVRs[bottom].startUnicodeValue;
1443 additionalCount = uVRs[bottom].additionalCount;
1444 if (c1 <= startUnicodeValue + additionalCount)
1445 return get_GlyphID (cmap, c1);
1448 if (record->nonDefaultUVSOffset)
1450 OTF_UVSMapping *uvsMappings = record->uvsMappings;
1451 unsigned numUVSMs = record->numUVSMappings;
1452 unsigned top = numUVSMs, bottom = 0, middle;
1454 if (uvsMappings[0].unicodeValue <= c1)
1458 middle = (top + bottom) / 2;
1459 if (c1 < uvsMappings[middle].unicodeValue)
1461 else if (bottom == middle)
1466 if (uvsMappings[bottom].unicodeValue == c1)
1467 return uvsMappings[bottom].glyphID;
1477 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
1479 OTF_EncodingSubtable14 *sub14;
1480 int c1 = gstring->glyphs[idx - 1].c;
1481 int c2 = gstring->glyphs[idx].c;
1485 gstring->glyphs[idx].glyph_id = 0;
1486 for (i = 0; i < cmap->numTables; i++)
1487 if (cmap->EncodingRecord[i].subtable.format == 14)
1489 if (i == cmap->numTables)
1491 code = get_uvs_glyph (cmap, cmap->EncodingRecord[i].subtable.f.f14, c1, c2);
1494 gstring->glyphs[idx - 1].glyph_id = code;
1495 gstring->glyphs[idx - 1].f.index.to = gstring->glyphs[idx].f.index.to;
1497 memmove (gstring->glyphs + idx, gstring->glyphs + idx + 1,
1498 sizeof (OTF_Glyph) * (gstring->used - idx));
1504 /* Table of GlyphClass and MarkAttackClass.
1506 For the Nth element CHAR, CHAR and the succeeding characters
1507 (before CHAR of the next element) has GlyphClass C (= (N % 2) ? 3 : 1).
1509 This table is generated from the General Category (GC) property of
1510 characters defined in the Unicode Character Database. */
1512 static int glyph_class_table[] =
1513 { 0x00000, 0x00300, 0x00370, 0x00483, 0x00487, 0x00488, 0x0048A, 0x00591,
1514 0x005BE, 0x005BF, 0x005C0, 0x005C1, 0x005C3, 0x005C4, 0x005C6, 0x005C7,
1515 0x005C8, 0x00610, 0x00616, 0x0064B, 0x0065F, 0x00670, 0x00671, 0x006D6,
1516 0x006DD, 0x006DE, 0x006E5, 0x006E7, 0x006E9, 0x006EA, 0x006EE, 0x00711,
1517 0x00712, 0x00730, 0x0074B, 0x007A6, 0x007B1, 0x007EB, 0x007F4, 0x00901,
1518 0x00904, 0x0093C, 0x0093D, 0x0093E, 0x0094E, 0x00951, 0x00955, 0x00962,
1519 0x00964, 0x00981, 0x00984, 0x009BC, 0x009BD, 0x009BE, 0x009C5, 0x009C7,
1520 0x009CE, 0x009D7, 0x009D8, 0x009E2, 0x009E4, 0x00A01, 0x00A04, 0x00A3C,
1521 0x00A3D, 0x00A3E, 0x00A4E, 0x00A70, 0x00A72, 0x00A81, 0x00A84, 0x00ABC,
1522 0x00ABD, 0x00ABE, 0x00ACE, 0x00AE2, 0x00AE4, 0x00B01, 0x00B04, 0x00B3C,
1523 0x00B3D, 0x00B3E, 0x00B44, 0x00B47, 0x00B58, 0x00B82, 0x00B83, 0x00BBE,
1524 0x00BCE, 0x00BD7, 0x00BD8, 0x00C01, 0x00C04, 0x00C3E, 0x00C45, 0x00C46,
1525 0x00C57, 0x00C82, 0x00C84, 0x00CBC, 0x00CBD, 0x00CBE, 0x00CC5, 0x00CC6,
1526 0x00CCE, 0x00CD5, 0x00CD7, 0x00CE2, 0x00CE4, 0x00D02, 0x00D04, 0x00D3E,
1527 0x00D44, 0x00D46, 0x00D4E, 0x00D57, 0x00D58, 0x00D82, 0x00D84, 0x00DCA,
1528 0x00DCB, 0x00DCF, 0x00DD7, 0x00DD8, 0x00DF4, 0x00E31, 0x00E32, 0x00E34,
1529 0x00E3B, 0x00E47, 0x00E4F, 0x00EB1, 0x00EB2, 0x00EB4, 0x00EBD, 0x00EC8,
1530 0x00ECE, 0x00F18, 0x00F1A, 0x00F35, 0x00F36, 0x00F37, 0x00F38, 0x00F39,
1531 0x00F3A, 0x00F3E, 0x00F40, 0x00F71, 0x00F85, 0x00F86, 0x00F88, 0x00F90,
1532 0x00FBD, 0x00FC6, 0x00FC7, 0x0102C, 0x0103A, 0x01056, 0x0105A, 0x0135F,
1533 0x01360, 0x01712, 0x01715, 0x01732, 0x01735, 0x01752, 0x01754, 0x01772,
1534 0x01774, 0x017B6, 0x017D4, 0x017DD, 0x017DE, 0x0180B, 0x0180E, 0x018A9,
1535 0x018AA, 0x01920, 0x0193C, 0x019B0, 0x019C1, 0x019C8, 0x019CA, 0x01A17,
1536 0x01A1C, 0x01B00, 0x01B05, 0x01B34, 0x01B45, 0x01B6B, 0x01B74, 0x01DC0,
1537 0x01E00, 0x020D0, 0x020F0, 0x0302A, 0x03030, 0x03099, 0x0309B, 0x0A802,
1538 0x0A803, 0x0A806, 0x0A807, 0x0A80B, 0x0A80C, 0x0A823, 0x0A828, 0x0FB1E,
1539 0x0FB1F, 0x0FE00, 0x0FE10, 0x0FE20, 0x0FE24, 0x10A01, 0x10A10, 0x10A38,
1540 0x10A40, 0x1D165, 0x1D16A, 0x1D16D, 0x1D173, 0x1D17B, 0x1D183, 0x1D185,
1541 0x1D18C, 0x1D1AA, 0x1D1AE, 0x1D242, 0x1D245, 0xE0100, 0xE01F0 };
1543 static int get_class_def_auto (int c)
1545 static int table_size
1546 = sizeof glyph_class_table / sizeof glyph_class_table[0];
1549 if (c >= glyph_class_table[table_size - 1])
1552 high = table_size - 1;
1555 mid = (low + high) / 2;
1556 if (c < glyph_class_table[mid])
1558 else if (c >= glyph_class_table[mid + 1])
1563 return ((mid % 2) ? 3 : 1);
1571 (((C) >= 0xFE00 && (C) <= 0xFE0F) || ((C) >= 0xE0100 && (C) <= 0xE01EF))
1574 OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
1578 OTF_EncodingSubtable *sub;
1579 lookup_cmap_func lookupper;
1582 && OTF_get_table (otf, "cmap") < 0)
1586 if (cmap->table_index < 0)
1590 sub = &cmap->EncodingRecord[cmap->table_index].subtable;
1591 lookupper = lookup_cmap_func_table[sub->format / 2];
1593 for (i = 0; i < gstring->used; i++)
1594 if (! gstring->glyphs[i].glyph_id)
1596 int c = gstring->glyphs[i].c;
1597 if (c < 32 || ! cmap->unicode_table)
1598 gstring->glyphs[i].glyph_id = 0;
1599 else if (UVS_P (c) && i > 0)
1600 check_cmap_uvs (cmap, gstring, i);
1601 else if (c < 0x10000)
1602 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1604 gstring->glyphs[i].glyph_id = lookupper (c, sub);
1611 OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
1612 int platform_id, int encoding_id)
1616 char *errfmt = "CMAP Looking up%s";
1618 OTF_EncodingRecord *enc;
1619 lookup_cmap_func lookupper;
1622 && OTF_get_table (otf, "cmap") < 0)
1626 for (i = 0; i < cmap->numTables; i++)
1627 if (cmap->EncodingRecord[i].platformID == platform_id
1628 && cmap->EncodingRecord[i].encodingID == encoding_id)
1630 if (i == cmap->numTables)
1631 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
1632 enc = cmap->EncodingRecord + i;
1633 if (enc->subtable.format > 12)
1634 OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
1635 lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
1637 for (i = 0; i < gstring->used; i++)
1638 if (! gstring->glyphs[i].glyph_id)
1640 int c = gstring->glyphs[i].c;
1641 if (c < 32 || ! cmap->unicode_table)
1642 gstring->glyphs[i].glyph_id = 0;
1643 else if (UVS_P (c) && i > 0)
1644 check_cmap_uvs (cmap, gstring, i);
1645 else if (c < 0x10000)
1646 gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
1648 gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
1654 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
1657 && OTF_get_table (otf, "cmap") < 0)
1660 || code > otf->cmap->max_glyph_id
1661 || ! otf->cmap->decode_table)
1663 return otf->cmap->decode_table[code];
1667 OTF_get_variation_glyphs (OTF *otf, int c, OTF_GlyphID code[256])
1671 OTF_EncodingSubtable14 *sub14;
1673 memset (code, 0, sizeof (OTF_GlyphID) * 256);
1675 && OTF_get_table (otf, "cmap") < 0)
1678 for (i = 0; i < cmap->numTables; i++)
1679 if (cmap->EncodingRecord[i].subtable.format == 14)
1681 if (i == cmap->numTables)
1683 sub14 = cmap->EncodingRecord[i].subtable.f.f14;
1684 for (i = 0, n = 0; i < 256; i++)
1686 int uvs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
1688 if ((code[i] = get_uvs_glyph (cmap, sub14, c, uvs)))
1696 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
1702 && OTF_get_table (otf, "GDEF") < 0)
1706 if (gdef->glyph_class_def.offset)
1707 for (i = 0; i < gstring->used; i++)
1708 gstring->glyphs[i].GlyphClass
1709 = get_class_def (&gdef->glyph_class_def,
1710 gstring->glyphs[i].glyph_id);
1712 for (i = 0; i < gstring->used; i++)
1713 gstring->glyphs[i].GlyphClass
1714 = get_class_def_auto (gstring->glyphs[i].c);
1716 if (gdef->mark_attach_class_def.offset)
1717 for (i = 0; i < gstring->used; i++)
1718 gstring->glyphs[i].MarkAttachClass
1719 = get_class_def (&gdef->mark_attach_class_def,
1720 gstring->glyphs[i].glyph_id);
1726 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
1727 const char *script, const char *language,
1728 const char *features,
1729 int alternate_subst)
1731 char *errfmt = "GSUB driving%s";
1734 OTF_LangSys *LangSys;
1738 for (i = 0; i < gstring->used; i++)
1740 gstring->glyphs[i].positioning_type = 0;
1741 gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
1744 if (OTF_get_table (otf, "GSUB") < 0)
1747 if (gsub->FeatureList.FeatureCount == 0
1748 || gsub->LookupList.LookupCount == 0)
1751 LangSys = get_langsys (&gsub->ScriptList, script, language);
1755 lookup_flags = alloca (gsub->LookupList.LookupCount);
1757 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
1758 features, lookup_flags) < 0)
1759 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1761 for (i = 0; i < gsub->LookupList.LookupCount; i++)
1765 if (! lookup_flags[i]) continue;
1767 if (gsub->LookupList.Lookup[i].LookupType != 8)
1770 while (gidx < gstring->used)
1772 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1780 gidx = gstring->used - 1;
1783 gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
1795 OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
1796 const char *script, const char *language, const char *features)
1799 OTF_get_table (otf, "cmap");
1800 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
1804 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
1805 const char *script, const char *language,
1806 const char *features,
1809 char *errfmt = "GPOS driving%s";
1812 OTF_LangSys *LangSys;
1816 for (i = 0; i < gstring->used; i++)
1817 gstring->glyphs[i].positioning_type = 0;
1819 if (OTF_get_table (otf, "GPOS") < 0)
1822 if (gpos->FeatureList.FeatureCount == 0
1823 || gpos->LookupList.LookupCount == 0)
1826 LangSys = get_langsys (&gpos->ScriptList, script, language);
1830 lookup_flags = alloca (gpos->LookupList.LookupCount);
1832 || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
1833 features, lookup_flags) < 0)
1834 OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
1836 for (i = 0; i < gpos->LookupList.LookupCount; i++)
1840 if (! lookup_flags[i]) continue;
1842 while (gidx < gstring->used)
1844 gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
1854 OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
1855 const char *script, const char *language, const char *features)
1858 OTF_get_table (otf, "cmap");
1859 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
1863 OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
1864 const char *script, const char *language, const char *features)
1867 OTF_get_table (otf, "cmap");
1868 return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
1872 OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
1873 const char *script, const char *language,
1874 const char *gsub_features, const char *gpos_features)
1876 if (OTF_drive_cmap (otf, gstring) < 0)
1878 if (OTF_drive_gdef (otf, gstring) < 0)
1881 && OTF_drive_gsub (otf, gstring, script, language, gsub_features) < 0)
1884 && OTF_drive_gpos (otf, gstring, script, language, gpos_features) < 0)
1890 OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
1891 const char *script, const char *language,
1892 const char *features)
1894 return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
1898 iterate_coverage (OTF *otf, const char *feature,
1899 OTF_Feature_Callback callback,
1900 OTF_Coverage *coverage)
1904 if (coverage->CoverageFormat == 1)
1906 for (i = 0; i < coverage->Count; i++)
1907 if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
1912 for (i = 0; i < coverage->Count; i++)
1914 OTF_RangeRecord *range = coverage->table.RangeRecord + i;
1916 for (id = range->Start; id <= range->End; id++)
1917 if (callback (otf, feature, id) < 0)
1925 iterate_feature (OTF *otf, const char *feature,
1926 OTF_Feature_Callback callback,
1931 for (i = 0; i < lookup->SubTableCount; i++)
1933 unsigned lookup_type = lookup->LookupType;
1934 OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
1936 if (lookup_type == 7)
1938 OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
1940 lookup_type = extension1->ExtensionLookupType;
1941 subtable = extension1->ExtensionSubtable;
1944 if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
1946 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1950 else if (lookup_type == 4)
1952 OTF_GSUB_Ligature1 *lig1;
1954 if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
1957 lig1 = &subtable->u.ligature1;
1958 for (j = 0; j < lig1->LigSetCount; j++)
1960 OTF_LigatureSet *ligset = lig1->LigatureSet + j;
1962 for (k = 0; k < ligset->LigatureCount; k++)
1964 OTF_Ligature *lig = ligset->Ligature + k;
1965 for (l = 0; l < lig->CompCount - 1; l++)
1966 if (callback (otf, feature, lig->Component[l]) < 0)
1971 else if (lookup_type == 6)
1973 if (subtable->Format == 1)
1975 OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
1976 for (j = 0; j < context1->ChainRuleSetCount; j++)
1978 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
1979 for (k = 0; k < set->ChainRuleCount; k++)
1981 OTF_ChainRule *rule = set->ChainRule + k;
1982 for (l = 0; l < rule->LookupCount; l++)
1985 = (otf->gsub->LookupList.Lookup
1986 + rule->LookupRecord[l].LookupListIndex);
1987 if (iterate_feature (otf, feature, callback, lkup)
1994 else if (subtable->Format == 2)
1996 OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
1998 for (j = 0; j < context2->ChainClassSetCnt; j++)
2000 OTF_ChainClassSet *set = context2->ChainClassSet + j;
2001 for (k = 0; k < set->ChainClassRuleCnt; j++)
2003 OTF_ChainClassRule *rule = set->ChainClassRule + k;
2005 for (l = 0; l < rule->LookupCount; l++)
2008 = (otf->gsub->LookupList.Lookup
2009 + rule->LookupRecord[k].LookupListIndex);
2010 if (iterate_feature (otf, feature, callback, lkup)
2019 OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
2020 for (j = 0; j < context3->LookupCount; j++)
2023 = (otf->gsub->LookupList.Lookup
2024 + context3->LookupRecord[j].LookupListIndex);
2025 if (iterate_feature (otf, feature, callback, lkup) < 0)
2035 OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
2036 const char *script, const char *language,
2037 const char *feature)
2039 char *errfmt = "GSUB iterate feature%s";
2044 OTF_LangSys *langsys;
2047 if (OTF_get_table (otf, "GSUB") < 0)
2050 if (gsub->FeatureList.FeatureCount == 0
2051 || gsub->LookupList.LookupCount == 0)
2053 langsys = get_langsys (&gsub->ScriptList, script, language);
2056 lookup_flags = alloca (gsub->LookupList.LookupCount);
2058 || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
2059 feature, lookup_flags) < 0)
2060 OTF_ERROR (OTF_ERROR_MEMORY, " feature");
2062 for (i = 0; i < gsub->LookupList.LookupCount; i++)
2063 if (lookup_flags[i])
2064 if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)
2071 OTF_get_drive_log (OTF *otf)
2073 OTF_DriveLog *log = get_drive_log (otf);
2075 return (log ? log->tags : NULL);