static int
-gstring_subst (OTF_GlyphString *gstring, int from, int to,
+gstring_subst (OTF_GlyphString *gstring, int from, int to, int flag,
OTF_GlyphID *ids, int num)
{
int errret = -1;
int len = to - from;
int i;
+ int c = gstring->glyphs[from].c;
+ int from_idx = gstring->glyphs[from].f.index.from;
+ int to_idx = gstring->glyphs[to - 1].f.index.to;
+ int non_ignored_idx;
+
+ for (i = non_ignored_idx = to - 1; i >= from; i--)
+ if (flag & (1 << gstring->glyphs[i].GlyphClass))
+ {
+ OTF_Glyph temp = gstring->glyphs[i];
+
+ memmove (gstring->glyphs + i, gstring->glyphs + i + 1,
+ sizeof (OTF_Glyph) * (non_ignored_idx - i));
+ gstring->glyphs[non_ignored_idx--] = temp;
+ len--;
+ }
if (len < num)
GSTRING_INSERT (gstring, from, (num - len));
else if (len > num)
GSTRING_DELETE (gstring, from, (len - num));
for (i = 0; i < num; i++)
- gstring->glyphs[from + i].glyph_id = ids[i];
+ {
+ gstring->glyphs[from + i].c = c;
+ gstring->glyphs[from + i].glyph_id = ids[i];
+ gstring->glyphs[from + i].f.index.from = from_idx;
+ gstring->glyphs[from + i].f.index.to = to_idx;
+ }
return 0;
}
OTF_Tag script_tag = OTF_tag (script);
OTF_Tag langsys_tag = OTF_tag (language);
int i, j;
+ OTF_Tag dflt_tag = OTF_tag ("DFLT");
+ OTF_Script *dflt = NULL;
for (i = 0; i < script_list->ScriptCount; i++)
- if (script_list->Script[i].ScriptTag == script_tag)
- {
- OTF_Script *script = script_list->Script + i;
-
- if (! langsys_tag)
- return &script->DefaultLangSys;
- for (j = 0; j < script->LangSysCount; j++)
- if (script->LangSysRecord[j].LangSysTag == langsys_tag)
- return script->LangSys + j;
- return &script->DefaultLangSys;
- }
+ {
+ OTF_Script *script = script_list->Script + i;
+
+ if (script_list->Script[i].ScriptTag == dflt_tag)
+ dflt = script;
+ if (script_list->Script[i].ScriptTag == script_tag)
+ {
+ if (! langsys_tag)
+ return &script->DefaultLangSys;
+ for (j = 0; j < script->LangSysCount; j++)
+ if (script->LangSysRecord[j].LangSysTag == langsys_tag)
+ return script->LangSys + j;
+ return &script->DefaultLangSys;
+ }
+ }
- return NULL;
+ if (! dflt)
+ dflt = script_list->Script;
+ if (! langsys_tag)
+ return &dflt->DefaultLangSys;
+ for (j = 0; j < dflt->LangSysCount; j++)
+ if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
+ return dflt->LangSys + j;
+ return &dflt->DefaultLangSys;
}
static int
}
static int
-match_ids (OTF_GlyphString *gstring, int gidx, int count, OTF_GlyphID *ids)
+match_ids (OTF_GlyphString *gstring, int gidx, int flag,
+ int count, OTF_GlyphID *ids)
{
OTF_Glyph *gbeg = gstring->glyphs + gidx;
OTF_Glyph *gend = gstring->glyphs + gstring->used;
int i;
for (g = gbeg, i = 0; g < gend && i < count; g++)
- if (g->glyph_id && g->glyph_id != ids[i++])
+ if (g->glyph_id && ! (flag & (1 << g->GlyphClass))
+ && g->glyph_id != ids[i++])
return -1;
return (i < count ? -1 : g - gbeg);
}
static int
-match_chain_ids (OTF_GlyphString *gstring, int gidx, OTF_ChainRule *rule)
+match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
+ OTF_ChainRule *rule)
{
int i = rule->BacktrackGlyphCount;
break;
if (i > 0)
return -1;
- if (match_ids (gstring, j, rule->BacktrackGlyphCount, rule->Backtrack)
+ if (match_ids (gstring, j, flag,
+ rule->BacktrackGlyphCount, rule->Backtrack)
< 0)
return -1;
}
gidx++;
- i = match_ids (gstring, gidx, rule->InputGlyphCount - 1, rule->Input);
+ i = match_ids (gstring, gidx, flag,
+ rule->InputGlyphCount - 1, rule->Input);
if (i < 0)
return -1;
gidx += i;
- i = match_ids (gstring, gidx, rule->LookaheadGlyphCount, rule->LookAhead);
+ i = match_ids (gstring, gidx, flag,
+ rule->LookaheadGlyphCount, rule->LookAhead);
if (i < 0)
return -1;
return 0;
static int
match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
- int count, unsigned *classes)
+ int flag, int count, unsigned *classes)
{
OTF_Glyph *gbeg = gstring->glyphs + gidx;
OTF_Glyph *gend = gstring->glyphs + gstring->used;
int i;
for (g = gbeg, i = 0; g < gend && i < count; g++)
- if (g->glyph_id
+ if (g->glyph_id && ! (flag & (1 << g->GlyphClass))
&& get_class_def (class_def, g->glyph_id) != classes[i++])
return -1;
return (i < count ? -1 : g - gbeg);
}
static int
-match_chain_classes (OTF_GlyphString *gstring, int gidx,
+match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
OTF_ClassDef *BacktrackClassDef,
OTF_ClassDef *InputClassDef,
OTF_ClassDef *LookaheadClassDef,
break;
if (i > 0)
return -1;
- if (match_classes (BacktrackClassDef, gstring, j,
+ if (match_classes (BacktrackClassDef, gstring, j, flag,
rule->BacktrackGlyphCount, rule->Backtrack) < 0);
return -1;
}
gidx++;
- i = match_classes (InputClassDef, gstring, gidx,
+ i = match_classes (InputClassDef, gstring, gidx, flag,
rule->InputGlyphCount - 1, rule->Input);
if (i < 0)
return -1;
gidx += i;
- i = match_classes (LookaheadClassDef, gstring, gidx,
+ i = match_classes (LookaheadClassDef, gstring, gidx, flag,
rule->LookaheadGlyphCount, rule->LookAhead);
if (i < 0)
return -1;
static int
-match_coverages (OTF_GlyphString *gstring, int gidx, int count,
+match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
OTF_Coverage *coverages)
{
OTF_Glyph *gbeg = gstring->glyphs + gidx;
int i;
for (g = gbeg, i = 0; g < gend && i < count; g++)
- if (g->glyph_id
+ if (g->glyph_id && ! (flag & (1 << g->GlyphClass))
&& get_coverage_index (coverages + i++, g->glyph_id) < 0)
return -1;
return (i < count ? -1 : g - gbeg);
}
static int
-match_chain_coverages (OTF_GlyphString *gstring, int gidx,
+match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
OTF_GSUB_ChainContext3 *context3)
{
int i = context3->BacktrackGlyphCount;
break;
if (i > 0)
return -1;
- if (match_coverages (gstring, j, context3->BacktrackGlyphCount,
+ if (match_coverages (gstring, j, flag, context3->BacktrackGlyphCount,
context3->Backtrack) < 0)
return -1;
}
gidx++;
if (context3->InputGlyphCount > 1)
{
- i = match_coverages (gstring, gidx, context3->InputGlyphCount - 1,
+ i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
context3->Input + 1);
if (i < 0)
return -1;
gidx += i;
}
- if (match_coverages (gstring, gidx, context3->LookaheadGlyphCount,
+ if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
context3->LookAhead) < 0)
return -1;
return 0;
char *errfmt = "GSUB Looking up%s";
int errret = -1;
OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
- unsigned int flag = lookup->LookupFlag;
+ unsigned int flag = lookup->LookupFlag & OTF_LookupFlagIgnoreMask;
int orig_gidx = gidx;
OTF_Glyph *g = gstring->glyphs + gidx;
int i;
OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
- gstring_subst (gstring, gidx, gidx + 1,
+ gstring_subst (gstring, gidx, gidx + 1, flag,
seq->Substitute, seq->GlyphCount);
gidx += seq->GlyphCount;
}
break;
case 3:
+ /* For the moment, we always ignore this feature. */
+ break;
if (subtable->Format == 1)
{
OTF_GSUB_Alternate1 *alt1 = &subtable->u.alternate1;
int n;
lig = ligset->Ligature + j;
- n = match_ids (gstring, gidx + 1,
+ n = match_ids (gstring, gidx + 1, flag,
lig->CompCount - 1, lig->Component);
if (n < 0)
continue;
- gstring_subst (gstring, gidx, gidx + 1 + n,
+ gstring_subst (gstring, gidx, gidx + 1 + n, flag,
&lig->LigGlyph, 1);
gidx++;
break;
for (j = 0; j < set->RuleCount; j++)
{
rule = set->Rule + j;
- if (match_ids (gstring, gidx + 1,
+ if (match_ids (gstring, gidx + 1, flag,
rule->GlyphCount - 1, rule->Input) < 0)
continue;
orig_used = gstring->used;
class = get_class_def (&context2->ClassDef, g->glyph_id);
set = context2->ClassSet + class;
- for (j = 0; j < set->ClassRuleCnt; j++)
- {
- rule = set->ClassRule + j;
- if (match_classes (&context2->ClassDef,
- gstring, gidx + 1,
- rule->GlyphCount - 1, rule->Class)
- < 0)
- continue;
- orig_used = gstring->used;
- for (k = 0; k < rule->LookupCount; k++)
- lookup_gsub (lookup_list,
- rule->LookupRecord[k].LookupListIndex,
- gstring,
- gidx + rule->LookupRecord[k].SequenceIndex);
- gidx += rule->GlyphCount + (gstring->used - orig_used);
- break;
- }
+ if (set)
+ for (j = 0; j < set->ClassRuleCnt; j++)
+ {
+ rule = set->ClassRule + j;
+ if (match_classes (&context2->ClassDef,
+ gstring, gidx + 1, flag,
+ rule->GlyphCount - 1, rule->Class)
+ < 0)
+ continue;
+ orig_used = gstring->used;
+ for (k = 0; k < rule->LookupCount; k++)
+ lookup_gsub (lookup_list,
+ rule->LookupRecord[k].LookupListIndex,
+ gstring,
+ gidx + rule->LookupRecord[k].SequenceIndex);
+ gidx += rule->GlyphCount + (gstring->used - orig_used);
+ break;
+ }
}
else /* subtable->Format == 3 */
{
int orig_used;
int j;
- if (match_coverages (gstring, gidx + 1, context3->GlyphCount - 1,
+ if (match_coverages (gstring, gidx + 1, flag,
+ context3->GlyphCount - 1,
context3->Coverage + 1) < 0)
continue;
orig_used = gstring->used;
|| (gidx + rule->InputGlyphCount
+ rule->LookaheadGlyphCount) > gstring->used)
continue;
- if (match_chain_ids (gstring, gidx, rule) < 0)
+ if (match_chain_ids (gstring, gidx, flag, rule) < 0)
continue;
orig_used = gstring->used;
for (k = 0; k < rule->LookupCount; k++)
|| (gidx + rule->InputGlyphCount
+ rule->LookaheadGlyphCount) > gstring->used)
continue;
- if (match_chain_classes (gstring, gidx,
+ if (match_chain_classes (gstring, gidx, flag,
&context2->BacktrackClassDef,
&context2->InputClassDef,
&context2->LookaheadClassDef,
if (gidx < context3->BacktrackGlyphCount
|| (gidx + context3->InputGlyphCount
+ context3->LookaheadGlyphCount) > gstring->used)
- return -1;
- if (match_chain_coverages (gstring, gidx, context3) < 0)
+ continue;
+ if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
continue;
orig_used = gstring->used;
for (j = 0; j < context3->LookupCount; j++)
char *errfmt = "GPOS Looking up%s";
int errret = -1;
OTF_Lookup *lookup = lookup_list->Lookup + lookup_list_index;
- unsigned int flag = lookup->LookupFlag;
+ unsigned int flag = lookup->LookupFlag & OTF_LookupFlagIgnoreMask;
int orig_gidx = gidx;
OTF_Glyph *g = gstring->glyphs + gidx;
int i;
if (! g->glyph_id
+ || g->positioning_type
|| (g->GlyphClass
&& (flag & (1 << g->GlyphClass))))
return (gidx + 1);
break;
case 2:
- if (gidx + 1 >= gstring->used)
- continue;
- if (subtable->Format == 1)
- {
- OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
- OTF_PairSet *set = pair1->PairSet + coverage_idx;
- int j;
+ {
+ int next_gidx = gidx + 1;
+ OTF_Glyph *nextg;
- for (j = 0; j < set->PairValueCount; j++)
- {
- if (set->PairValueRecord[j].SecondGlyph != g[1].glyph_id)
- continue;
- gidx++;
- g->positioning_type = lookup->LookupType;
- g->f.f2.format = pair1->ValueFormat1;
- g->f.f2.value = &set->PairValueRecord[j].Value1;
- if (pair1->ValueFormat2)
+ while (next_gidx < gstring->used
+ && (! gstring->glyphs[next_gidx].glyph_id
+ || ! (flag
+ & (1 << gstring->glyphs[next_gidx].GlyphClass))))
+ next_gidx++;
+
+ if (next_gidx >= gstring->used)
+ continue;
+ nextg = gstring->glyphs + next_gidx;
+ if (nextg->positioning_type)
+ continue;
+ if (subtable->Format == 1)
+ {
+ OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
+ OTF_PairSet *set = pair1->PairSet + coverage_idx;
+ int j;
+
+ for (j = 0; j < set->PairValueCount; j++)
+ if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
{
- g++, gidx++;
- g->positioning_type = lookup->LookupType;
- g->f.f2.format = pair1->ValueFormat2;
- g->f.f2.value = &set->PairValueRecord[j].Value2;
+ if (pair1->ValueFormat1)
+ {
+ g->positioning_type = lookup->LookupType;
+ g->f.f2.format = pair1->ValueFormat1;
+ g->f.f2.value = &set->PairValueRecord[j].Value1;
+ }
+ gidx = next_gidx;
+ if (pair1->ValueFormat2)
+ {
+ nextg->positioning_type = lookup->LookupType;
+ nextg->f.f2.format = pair1->ValueFormat2;
+ nextg->f.f2.value = &set->PairValueRecord[j].Value2;
+ gidx++;
+ }
+ break;
}
- }
- }
- else if (subtable->Format == 2)
- {
- OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
- unsigned class1, class2;
-
- gidx++;
- class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
- class2 = get_class_def (&pair2->ClassDef2, g[1].glyph_id);
- g->positioning_type = lookup->LookupType;
- g->f.f2.format = pair2->ValueFormat1;
- g->f.f2.value
- = &pair2->Class1Record[class1].Class2Record[class2].Value1;
- if (pair2->ValueFormat2)
- {
- g++, gidx++;
- g->positioning_type = lookup->LookupType;
- g->f.f2.format = pair2->ValueFormat2;
- g->f.f2.value
- = &pair2->Class1Record[class1].Class2Record[class2].Value2;
- }
- }
+ }
+ else if (subtable->Format == 2)
+ {
+ OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
+ unsigned class1, class2;
+
+ class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
+ class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
+ if (pair2->ValueFormat1)
+ {
+ g->positioning_type = lookup->LookupType;
+ g->f.f2.format = pair2->ValueFormat1;
+ g->f.f2.value
+ = &pair2->Class1Record[class1].Class2Record[class2].Value1;
+ }
+ gidx = next_gidx;
+ if (pair2->ValueFormat2)
+ {
+ nextg->positioning_type = lookup->LookupType;
+ nextg->f.f2.format = pair2->ValueFormat2;
+ nextg->f.f2.value
+ = &pair2->Class1Record[class1].Class2Record[class2].Value2;
+ gidx++;
+ }
+ }
+ }
break;
case 3:
OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
OTF_MarkRecord *mark_record;
OTF_AnchorRecord *base_record;
- int coverage_idx_base
+ OTF_Glyph *baseg = g - 1;
+ int coverage_idx_base;
+
+ while (baseg >= gstring->glyphs
+ && (! baseg->glyph_id
+ || (baseg->GlyphClass
+ && (flag & (1 << baseg->GlyphClass)))))
+ baseg--;
+ coverage_idx_base
= get_coverage_index (&mark_base1->BaseCoverage,
- g[-1].glyph_id);
+ baseg->glyph_id);
if (coverage_idx_base < 0)
continue;
g->f.f4.base_anchor
= &base_record->Anchor[mark_record->Class];
g->positioning_type = lookup->LookupType;
- break;
}
break;
continue;
if (subtable->Format == 1)
{
- /* As the document of this lookup type is quite
- ambiguous, and we can't know the exact procedure to
- handle it?!? */
- OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
+ OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
+ unsigned class = g->MarkAttachClass;
+ OTF_Glyph *ligg = g - 1;
+ int coverage_idx_lig;
+ OTF_MarkRecord *mark_record;
+ OTF_ComponentRecord *cmp_record;
+ OTF_LigatureAttach *attach;
+ int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
+ int j;
+
+ for (j = 0; j < mark_lig1->ClassCount; j++)
+ num_class[j] = 0;
+
+ while (ligg >= gstring->glyphs
+ && (! ligg->glyph_id
+ || (ligg->GlyphClass
+ && (flag & (1 << ligg->GlyphClass)))))
+ {
+ if (ligg->positioning_type == 5
+ && ligg->MarkAttachClass < mark_lig1->ClassCount)
+ num_class[ligg->MarkAttachClass]++;
+ ligg--;
+ }
+ coverage_idx_lig
+ = get_coverage_index (&mark_lig1->LigatureCoverage,
+ ligg->glyph_id);
+ if (coverage_idx_lig < 0)
+ continue;
+ mark_record = mark_lig1->MarkArray.MarkRecord + coverage_idx;
+ g->MarkAttachClass = mark_record->Class;
+ attach = (mark_lig1->LigatureArray.LigatureAttach
+ + coverage_idx_lig);
+ for (j = 0; j < attach->ComponentCount; j++)
+ {
+ OTF_Anchor *lig_anchor
+ = attach->ComponentRecord[j].LigatureAnchor;
+
+ if (lig_anchor[mark_record->Class].AnchorFormat
+ && num_class[mark_record->Class]-- == 0)
+ {
+ g->positioning_type = lookup->LookupType;
+ g->f.f5.mark_anchor = &mark_record->MarkAnchor;
+ g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
+ break;
+ }
+ }
}
break;
OTF_GPOS_MarkMark1 *mark_mark1 = &subtable->u.mark_mark1;
OTF_MarkRecord *mark1_record;
OTF_AnchorRecord *mark2_record;
- int coverage_idx_base
+ OTF_Glyph *prevg = g - 1;
+ int coverage_idx_base;
+
+ while (prevg >= gstring->glyphs
+ && (! prevg->glyph_id
+ || (prevg->GlyphClass
+ && (flag & (1 << prevg->GlyphClass)))))
+ prevg--;
+ if (prevg < gstring->glyphs)
+ continue;
+ coverage_idx_base
= get_coverage_index (&mark_mark1->Mark2Coverage,
- g[-1].glyph_id);
-
+ prevg->glyph_id);
if (coverage_idx_base < 0)
continue;
mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
break;
case 7:
- OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
+ if (subtable->Format == 1)
+ {
+ OTF_GPOS_Context1 *context1 = &subtable->u.context1;
+ OTF_RuleSet *set = context1->RuleSet + coverage_idx;
+ OTF_Rule *rule;
+ int orig_used;
+ int j, k;
+
+ for (j = 0; j < set->RuleCount; j++)
+ {
+ rule = set->Rule + j;
+ if (match_ids (gstring, gidx + 1, flag,
+ rule->GlyphCount - 1, rule->Input) < 0)
+ continue;
+ orig_used = gstring->used;
+ for (k = 0; k < rule->LookupCount; k++)
+ lookup_gpos (lookup_list,
+ rule->LookupRecord[k].LookupListIndex,
+ gstring,
+ gidx + rule->LookupRecord[k].SequenceIndex);
+ gidx += rule->GlyphCount + (gstring->used - orig_used);
+ break;
+ }
+ }
+ else if (subtable->Format == 2)
+ {
+ OTF_GPOS_Context2 *context2 = &subtable->u.context2;
+ OTF_ClassSet *set;
+ OTF_ClassRule *rule;
+ unsigned class;
+ int orig_used;
+ int j, k;
+
+ class = get_class_def (&context2->ClassDef, g->glyph_id);
+ set = context2->ClassSet + class;
+ if (set)
+ for (j = 0; j < set->ClassRuleCnt; j++)
+ {
+ rule = set->ClassRule + j;
+ if (match_classes (&context2->ClassDef,
+ gstring, gidx + 1, flag,
+ rule->GlyphCount - 1, rule->Class)
+ < 0)
+ continue;
+ orig_used = gstring->used;
+ for (k = 0; k < rule->LookupCount; k++)
+ lookup_gpos (lookup_list,
+ rule->LookupRecord[k].LookupListIndex,
+ gstring,
+ gidx + rule->LookupRecord[k].SequenceIndex);
+ gidx += rule->GlyphCount + (gstring->used - orig_used);
+ break;
+ }
+ }
+ else /* subtable->Format == 3 */
+ {
+ OTF_GPOS_Context3 *context3 = &subtable->u.context3;
+ int orig_used;
+ int j;
+
+ if (match_coverages (gstring, gidx + 1, flag,
+ context3->GlyphCount - 1,
+ context3->Coverage + 1) < 0)
+ continue;
+ orig_used = gstring->used;
+ for (j = 0; j < context3->LookupCount; j++)
+ lookup_gpos (lookup_list,
+ context3->LookupRecord[j].LookupListIndex,
+ gstring,
+ gidx + context3->LookupRecord[j].SequenceIndex);
+ gidx += context3->GlyphCount + (gstring->used - orig_used);
+ }
break;
case 8:
if (subtable->Format == 1)
- OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
+ {
+ OTF_GPOS_ChainContext1 *context1 = &subtable->u.chain_context1;
+ OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
+ int orig_used;
+ int j, k;
+
+ for (j = 0; j < set->ChainRuleCount; j++)
+ {
+ OTF_ChainRule *rule = set->ChainRule + j;
+
+ if (gidx < rule->BacktrackGlyphCount
+ || (gidx + rule->InputGlyphCount
+ + rule->LookaheadGlyphCount) > gstring->used)
+ continue;
+ if (match_chain_ids (gstring, gidx, flag, rule) < 0)
+ continue;
+ orig_used = gstring->used;
+ for (k = 0; k < rule->LookupCount; k++)
+ lookup_gpos (lookup_list,
+ rule->LookupRecord[k].LookupListIndex,
+ gstring,
+ gidx + rule->LookupRecord[k].SequenceIndex);
+ gidx += rule->InputGlyphCount + (gstring->used - orig_used);
+ break;
+ }
+ }
else if (subtable->Format == 2)
{
OTF_GPOS_ChainContext2 *context2 = &subtable->u.chain_context2;
for (j = 0; j < set->ChainClassRuleCnt; j++)
{
OTF_ChainClassRule *rule = set->ChainClassRule + j;
- int fore_idx = gidx + rule->InputGlyphCount;
int k;
if (gidx < rule->BacktrackGlyphCount
|| (gidx + rule->InputGlyphCount
+ rule->LookaheadGlyphCount) > gstring->used)
continue;
- for (k = 0; k < rule->BacktrackGlyphCount; k++)
- if (get_class_def (&context2->BacktrackClassDef,
- gstring->glyphs[gidx - 1 - k].glyph_id)
- != rule->Backtrack[k])
- break;
- if (k < rule->BacktrackGlyphCount)
- continue;
- for (k = 1; k < rule->InputGlyphCount; k++)
- if (get_class_def (&context2->InputClassDef,
- gstring->glyphs[gidx + k].glyph_id)
- != rule->Input[k - 1])
- break;
- if (k < rule->InputGlyphCount)
- continue;
- for (k = 0; k < rule->LookaheadGlyphCount; k++)
- if (get_class_def (&context2->LookaheadClassDef,
- gstring->glyphs[fore_idx + k].glyph_id)
- != rule->LookAhead[k])
- break;
- if (k < rule->LookaheadGlyphCount)
+ if (match_chain_classes (gstring, gidx, flag,
+ &context2->BacktrackClassDef,
+ &context2->InputClassDef,
+ &context2->LookaheadClassDef,
+ rule) < 0)
continue;
-
orig_used = gstring->used;
for (k = 0; k < rule->LookupCount; k++)
lookup_gpos (lookup_list,
}
}
else if (subtable->Format == 3)
- OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
+ {
+ OTF_GPOS_ChainContext3 *context3 = &subtable->u.chain_context3;
+ int orig_used;
+ int j;
+
+ if (gidx < context3->BacktrackGlyphCount
+ || (gidx + context3->InputGlyphCount
+ + context3->LookaheadGlyphCount) > gstring->used)
+ continue;
+ if (match_chain_coverages (gstring, gidx, flag, context3) < 0)
+ continue;
+ orig_used = gstring->used;
+ for (j = 0; j < context3->LookupCount; j++)
+ lookup_gpos (lookup_list,
+ context3->LookupRecord[j].LookupListIndex,
+ gstring,
+ gidx + context3->LookupRecord[j].SequenceIndex);
+ gidx += context3->InputGlyphCount + (gstring->used - orig_used);
+ }
else
OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (invalid subformat)");
break;
return 0;
}
+
int
OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
int platform_id, int encoding_id)
int *lookup_indices;
int i, n;
+ for (i = 0; i < gstring->used; i++)
+ gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
+
if (! otf->gsub
&& OTF_get_table (otf, "GSUB") < 0)
return errret;
if (n < 0)
return errret;
+ for (i = 0; i < gstring->used; i++)
+ gstring->glyphs[i].positioning_type = 0;
+
for (i = 0; i < n; i++)
{
int index = lookup_indices[i];