From 3073762bf7bf41d3455e4ead67075f7ef436283c Mon Sep 17 00:00:00 2001 From: handa Date: Tue, 14 Oct 2003 12:57:38 +0000 Subject: [PATCH] *** empty log message *** --- src/otf.h | 10 +++ src/otfdrive.c | 249 +++++++++++++++++++++++++++++++++----------------------- src/otfopen.c | 25 ++++-- 3 files changed, 177 insertions(+), 107 deletions(-) diff --git a/src/otf.h b/src/otf.h index f490bf6..c3a307a 100644 --- a/src/otf.h +++ b/src/otf.h @@ -220,6 +220,8 @@ typedef struct unsigned numTables; OTF_EncodingRecord *EncodingRecord; unsigned short *unicode_table; + int max_glyph_id; + unsigned short *decode_table; } OTF_cmap; @@ -1231,6 +1233,14 @@ extern int OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring, char *gsub_features, char *gpos_features); +/*** (3-7) OTF_get_unicode() */ + +/*** + Return Unicode code point corresponding to the glyph-id CODE. + */ + +extern int OTF_get_unicode (OTF *otf, OTF_GlyphID code); + /*** (4) API for error handling ***/ /*** (4-1) Error codes ***/ diff --git a/src/otfdrive.c b/src/otfdrive.c index 14e422b..36c36ff 100644 --- a/src/otfdrive.c +++ b/src/otfdrive.c @@ -200,34 +200,38 @@ setup_lookup_indices (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList, 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; } @@ -236,14 +240,98 @@ static int 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; } @@ -331,11 +419,14 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index, 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; @@ -403,26 +494,17 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index, { 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; @@ -438,13 +520,12 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index, 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++) @@ -470,35 +551,18 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index, 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, @@ -512,42 +576,11 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index, 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, @@ -910,7 +943,7 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring) 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]; @@ -920,6 +953,18 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring) 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) diff --git a/src/otfopen.c b/src/otfopen.c index 29f4133..fb797ab 100644 --- a/src/otfopen.c +++ b/src/otfopen.c @@ -550,8 +550,9 @@ read_cmap_table (OTF *otf, OTF_Stream *stream) if (unicode_index >= 0) { OTF_EncodingRecord *rec = cmap->EncodingRecord + unicode_index; + OTF_GlyphID glyph_id, max_glyph_id = 0; - OTF_MALLOC (cmap->unicode_table, 0x10000, ""); + OTF_CALLOC (cmap->unicode_table, 0x10000, ""); switch (rec->subtable.format) { case 4: @@ -566,17 +567,31 @@ read_cmap_table (OTF *otf, OTF_Stream *stream) if (seg->idRangeOffset == 0xFFFF) for (c = seg->startCount; c <= seg->endCount; c++) - cmap->unicode_table[c] = c + seg->idDelta; + { + glyph_id = c + seg->idDelta; + cmap->unicode_table[c] = glyph_id; + if (glyph_id > max_glyph_id) + max_glyph_id = glyph_id; + } else for (c = seg->startCount; c <= seg->endCount && c != 0xFFFF; c++) - cmap->unicode_table[c] - = sub4->glyphIdArray[seg->idRangeOffset - + (c - seg->startCount)]; + { + glyph_id = sub4->glyphIdArray[seg->idRangeOffset + + (c - seg->startCount)]; + cmap->unicode_table[c] = glyph_id; + if (glyph_id > max_glyph_id) + max_glyph_id = glyph_id; + } } } } + OTF_CALLOC (cmap->decode_table, max_glyph_id + 1, ""); + for (i = 0; i < 0x10000; i++) + if (cmap->unicode_table[i]) + cmap->decode_table[cmap->unicode_table[i]] = i; + cmap->max_glyph_id = max_glyph_id; } return cmap; -- 1.7.10.4