static int
match_ids (OTF_GlyphString *gstring, int gidx, int count, OTF_GlyphID *ids)
{
- int i, j;
+ OTF_Glyph *gbeg = gstring->glyphs + gidx;
+ OTF_Glyph *gend = gstring->glyphs + gstring->used;
+ OTF_Glyph *g;
+ int i;
- if (gstring->used - gidx < count)
- return -1;
- for (i = j = 0; i < count; i++, j++)
- {
- if (! gstring->glyphs[gidx + j].glyph_id)
- /* Skip this glyph. */
- i--;
- else if (ids[i] && gstring->glyphs[gidx + i].glyph_id != ids[i])
- return -1;
- }
- return j;
+ for (g = gbeg, i = 0; g < gend && i < count; g++)
+ if (g->glyph_id && 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)
{
- if (match_ids (gstring, gidx, rule->BacktrackGlyphCount, rule->Backtrack)
- < 0)
+ int i, j;
+
+ for (i = rule->BacktrackGlyphCount, j = gidx - 1; j >= 0 && i > 0; j--)
+ if (gstring->glyphs[j].glyph_id)
+ i--;
+ if (i > 0)
return -1;
- gidx += rule->BacktrackGlyphCount + 1;
- if (match_ids (gstring, gidx, rule->InputGlyphCount - 1, rule->Input)
- < 0)
+
+ i = match_ids (gstring, j, rule->BacktrackGlyphCount, rule->Backtrack);
+ if (i < 0)
+ return -1;
+ gidx++;
+ i = match_ids (gstring, gidx, rule->InputGlyphCount - 1, rule->Input);
+ if (i < 0)
return -1;
- gidx += rule->InputGlyphCount;
- if (match_ids (gstring, gidx, rule->LookaheadGlyphCount - 1, rule->LookAhead)
- < 0)
+ gidx += i;
+ i = match_ids (gstring, gidx, rule->LookaheadGlyphCount, rule->LookAhead);
+ if (i < 0)
return -1;
return 0;
}
match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
int count, unsigned *classes)
{
+ OTF_Glyph *gbeg = gstring->glyphs + gidx;
+ OTF_Glyph *gend = gstring->glyphs + gstring->used;
+ OTF_Glyph *g;
int i;
- if (gstring->used - gidx < count)
+ for (g = gbeg, i = 0; g < gend && i < count; g++)
+ if (g->glyph_id
+ && 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,
+ OTF_ClassDef *BacktrackClassDef,
+ OTF_ClassDef *InputClassDef,
+ OTF_ClassDef *LookaheadClassDef,
+ OTF_ChainClassRule *rule)
+{
+ int i, j;
+
+ for (i = rule->BacktrackGlyphCount, j = gidx - 1; j >= 0 && i > 0; j--)
+ if (gstring->glyphs[j].glyph_id)
+ i--;
+ if (i > 0)
return -1;
- for (i = 0; i < count; i++)
- if (get_class_def (class_def, gstring->glyphs[gidx + i].glyph_id)
- != classes[i])
+
+ i = match_classes (BacktrackClassDef, gstring, j,
+ rule->BacktrackGlyphCount, rule->Backtrack);
+ if (i < 0)
+ return -1;
+ gidx++;
+ i = match_classes (InputClassDef, gstring, gidx,
+ rule->InputGlyphCount - 1, rule->Input);
+ if (i < 0)
+ return -1;
+ gidx += i;
+ i = match_classes (LookaheadClassDef, gstring, gidx,
+ rule->LookaheadGlyphCount, rule->LookAhead);
+ if (i < 0)
+ return -1;
+ return 0;
+}
+
+
+static int
+match_coverages (OTF_GlyphString *gstring, int gidx, int count,
+ OTF_Coverage *coverages)
+{
+ OTF_Glyph *gbeg = gstring->glyphs + gidx;
+ OTF_Glyph *gend = gstring->glyphs + gstring->used;
+ OTF_Glyph *g;
+ int i;
+
+ for (g = gbeg, i = 0; g < gend && i < count; g++)
+ if (g->glyph_id
+ && 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,
+ OTF_GSUB_ChainContext3 *context3)
+{
+ int i, j;
+
+ if (gidx < context3->BacktrackGlyphCount
+ || (gidx + context3->InputGlyphCount
+ + context3->LookaheadGlyphCount) >= gstring->used)
+ return -1;
+
+ for (i = context3->BacktrackGlyphCount, j = gidx - 1; j >= 0 && i > 0; j--)
+ if (gstring->glyphs[j].glyph_id)
+ i--;
+ if (i > 0)
+ return -1;
+
+ i = match_coverages (gstring, j, context3->BacktrackGlyphCount,
+ context3->Backtrack);
+ if (i < 0)
+ return -1;
+ gidx++;
+ i = match_coverages (gstring, gidx, context3->InputGlyphCount - 1,
+ context3->Input + 1);
+ if (i < 0)
+ return -1;
+ gidx += i;
+ i = match_coverages (gstring, gidx, context3->LookaheadGlyphCount,
+ context3->LookAhead);
+ if (i < 0)
+ return -1;
return 0;
}
for (j = 0; j < ligset->LigatureCount; j++)
{
+ int n;
+
lig = ligset->Ligature + j;
- if (match_ids (gstring, gidx + 1,
- lig->CompCount - 1, lig->Component) < 0)
+ n = match_ids (gstring, gidx + 1,
+ lig->CompCount - 1, lig->Component);
+ if (n < 0)
continue;
- gstring_subst (gstring, gidx, gidx + lig->CompCount,
+ gstring_subst (gstring, gidx, gidx + 1 + n,
&lig->LigGlyph, 1);
gidx++;
break;
{
OTF_GSUB_Context3 *context3 = &subtable->u.context3;
int orig_used;
- int j, k;
+ int j;
- if (gstring->used - gidx < context3->GlyphCount)
- continue;
- /* Start from the secoding coverage_idx because the
- first one is the same as subtable->Coverage and thus
- already tested */
- for (j = 1; j < context3->GlyphCount; j++)
- if (get_coverage_index (context3->Coverage + j,
- gstring->glyphs[gidx + j].glyph_id)
- < 0)
- break;
- if (j < context3->GlyphCount)
+ if (match_coverages (gstring, gidx + 1, context3->GlyphCount - 1,
+ context3->Coverage + 1) < 0)
continue;
orig_used = gstring->used;
- for (k = 0; k < context3->LookupCount; k++)
+ for (j = 0; j < context3->LookupCount; j++)
lookup_gsub (lookup_list,
- context3->LookupRecord[k].LookupListIndex,
+ context3->LookupRecord[j].LookupListIndex,
gstring,
- gidx + context3->LookupRecord[k].SequenceIndex);
+ gidx + context3->LookupRecord[j].SequenceIndex);
gidx += context3->GlyphCount + (gstring->used - orig_used);
}
break;
for (j = 0; j < set->ChainRuleCount; j++)
{
OTF_ChainRule *rule = set->ChainRule + j;
- int backs = rule->BacktrackGlyphCount;
- int inputs = rule->InputGlyphCount;
- int aheads = rule->LookaheadGlyphCount;
- if (gidx < backs || gidx + inputs + aheads > gstring->used)
+ if (gidx < rule->BacktrackGlyphCount
+ || (gidx + rule->InputGlyphCount
+ + rule->LookaheadGlyphCount) >= gstring->used)
continue;
- if (match_chain_ids (gstring, gidx - backs, rule) < 0)
+ if (match_chain_ids (gstring, gidx, rule) < 0)
continue;
orig_used = gstring->used;
for (k = 0; k < rule->LookupCount; k++)
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,
+ &context2->BacktrackClassDef,
+ &context2->InputClassDef,
+ &context2->LookaheadClassDef,
+ rule) < 0)
continue;
-
orig_used = gstring->used;
for (k = 0; k < rule->LookupCount; k++)
lookup_gsub (lookup_list,
else
{
OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
- int back_gidx = gidx - context3->BacktrackGlyphCount;
- int fore_gidx = gidx + context3->InputGlyphCount;
int orig_used;
int j;
- if (back_gidx < 0
- || fore_gidx + context3->LookaheadGlyphCount > gstring->used)
- break;
-
- for (j = 0; j < context3->BacktrackGlyphCount; j++)
- if (get_coverage_index (context3->Backtrack + j,
- gstring->glyphs[gidx - 1 - j].glyph_id)
- < 0)
- break;
- if (j < context3->BacktrackGlyphCount)
+ if (match_chain_coverages (gstring, gidx, context3) < 0)
continue;
-
- /* Start from the second coverage_idx because the first
- one is the same as subtable->Coverage and thus
- already tested */
- for (j = 1; j < context3->InputGlyphCount; j++)
- if (get_coverage_index (context3->Input + j,
- gstring->glyphs[gidx + j].glyph_id)
- < 0)
- break;
- if (j < context3->InputGlyphCount)
- continue;
-
- for (j = 0; j < context3->LookaheadGlyphCount; j++)
- if (get_coverage_index (context3->LookAhead + j,
- gstring->glyphs[fore_gidx + j].glyph_id)
- < 0)
- break;
- if (j < context3->LookaheadGlyphCount)
- continue;
-
orig_used = gstring->used;
for (j = 0; j < context3->LookupCount; j++)
lookup_gsub (lookup_list,
for (i = 0; i < gstring->used; i++)
{
int c = gstring->glyphs[i].c;
- if (c < 32 || ! cmap || ! cmap->unicode_table)
+ if (c < 32 || ! cmap->unicode_table)
gstring->glyphs[i].glyph_id = 0;
else
gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
return 0;
}
+int
+OTF_get_unicode (OTF *otf, OTF_GlyphID code)
+{
+ if (! otf->cmap
+ && OTF_get_table (otf, "cmap") < 0)
+ return code;
+ if (code == 0
+ || code > otf->cmap->max_glyph_id
+ || otf->cmap->decode_table)
+ return code;
+ return otf->cmap->decode_table[code];
+}
int
OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)