From d3d08d191895ac7ca56abaa471899e85396b4f10 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 23 Jul 2009 07:57:02 +0000 Subject: [PATCH] (lookup_encoding_0, lookup_encoding_2) (lookup_encoding_4, lookup_encoding_6, lookup_encoding_8) (lookup_encoding_10, lookup_encoding_12): Arguments and return value changed. (lookup_cmap_func): New function type. (lookup_cmap_func_table): New variable. (get_GlyphID): New function. (get_uvs_glyph): Call get_GlyphID instead of directly accessing cmal->unicode_table. (OTF_drive_cmap, OTF_drive_cmap2): Call one of lookup functions in lookup_cmap_func_table. --- src/otfdrive.c | 158 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 58 deletions(-) diff --git a/src/otfdrive.c b/src/otfdrive.c index 7a41174..bb65f7e 100644 --- a/src/otfdrive.c +++ b/src/otfdrive.c @@ -1259,83 +1259,107 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index, return gidx; } -static int -lookup_encoding_0 (OTF_EncodingSubtable0 *sub0, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_0 (int c, OTF_EncodingSubtable *sub) { - int i, c; - - for (i = 0; i < gstring->used; i++) - { - c = gstring->glyphs[i].c; - if (c < 0 || c >= 256) - gstring->glyphs[i].glyph_id = 0; - else - gstring->glyphs[i].glyph_id = sub0->glyphIdArray[c]; - } - return 0; + return ((c < 0 || c >= 256) + ? 0 + : sub->f.f0->glyphIdArray[c]); } -static int -lookup_encoding_2 (OTF_EncodingSubtable2 *sub2, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_2 (int c, OTF_EncodingSubtable *sub) { return 0; } -static int -lookup_encoding_4 (OTF_EncodingSubtable4 *sub4, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_4 (int c, OTF_EncodingSubtable *sub) { - int i, j, c; - int segCount = sub4->segCountX2 / 2; + int segCount, i; + OTF_EncodingSubtable4 *sub4; - for (i = 0; i < gstring->used; i++) + if (c < 0) + return 0; + sub4 = sub->f.f4; + segCount = sub4->segCountX2 / 2; + for (i = 0; i < segCount; i++) { - c = gstring->glyphs[i].c; - if (c < 0) - gstring->glyphs[i].glyph_id = 0; - for (j = 0; j < segCount; j++) - { - OTF_cmapSegment *seg = sub4->segments + i; + OTF_cmapSegment *seg = sub4->segments + i; - if (c >= seg->startCount && c <= seg->endCount) - { - if (seg->idRangeOffset == 0xFFFF) - gstring->glyphs[i].glyph_id = c + seg->idDelta; - else - gstring->glyphs[i].glyph_id - = sub4->glyphIdArray[seg->idRangeOffset - + (c - seg->startCount)]; - break; - } + if (c >= seg->startCount && c <= seg->endCount) + { + if (seg->idRangeOffset == 0xFFFF) + return c + seg->idDelta; + else + return sub4->glyphIdArray[seg->idRangeOffset + + (c - seg->startCount)]; } } - return 0; } -static int -lookup_encoding_6 (OTF_EncodingSubtable6 *sub6, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_6 (int c, OTF_EncodingSubtable *sub) { return 0; } -static int -lookup_encoding_8 (OTF_EncodingSubtable8 *sub8, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_8 (int c, OTF_EncodingSubtable *sub) { return 0; } -static int -lookup_encoding_10 (OTF_EncodingSubtable10 *sub10, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_10 (int c, OTF_EncodingSubtable *sub) { return 0; } -static int -lookup_encoding_12 (OTF_EncodingSubtable12 *sub12, OTF_GlyphString *gstring) +static unsigned +lookup_encoding_12 (int c, OTF_EncodingSubtable *sub) { + OTF_EncodingSubtable12 *sub12; + OTF_cmapGroup *g, *gend; + + if (c < 0) + return 0; + sub12 = sub->f.f12; + g = sub12->Groups; + gend = sub12->Groups + sub12->nGroups; + while (g < gend) + { + if (g->startCharCode <= c && c <= g->endCharCode) + return (g->startGlyphID + (c - g->startCharCode)); + g++; + } return 0; } +typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *); + +static lookup_cmap_func lookup_cmap_func_table[] = + { + lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6, + lookup_encoding_8, lookup_encoding_10, lookup_encoding_12 + }; + +static unsigned +get_GlyphID (OTF_cmap *cmap, int c) +{ + OTF_EncodingSubtable *sub; + lookup_cmap_func lookupper; + + if (c < 0x10000 && cmap->unicode_table) + return cmap->unicode_table[c]; + if (cmap->table_index < 0) + return 0; + sub = &cmap->EncodingRecord[cmap->table_index].subtable; + lookupper = lookup_cmap_func_table[sub->format / 2]; + return lookupper (c, sub); +} + static OTF_GlyphID get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2) { @@ -1371,7 +1395,7 @@ get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2) startUnicodeValue = uVRs[bottom].startUnicodeValue; additionalCount = uVRs[bottom].additionalCount; if (c1 <= startUnicodeValue + additionalCount) - return cmap->unicode_table[c1]; + return get_GlyphID (cmap, c1); } } if (record->nonDefaultUVSOffset) @@ -1504,12 +1528,21 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring) { OTF_cmap *cmap; int i; + OTF_EncodingSubtable *sub; + lookup_cmap_func lookupper; if (! otf->cmap && OTF_get_table (otf, "cmap") < 0) return -1; cmap = otf->cmap; + if (cmap->table_index < 0) + lookupper = NULL; + else + { + sub = &cmap->EncodingRecord[cmap->table_index].subtable; + lookupper = lookup_cmap_func_table[sub->format / 2]; + } for (i = 0; i < gstring->used; i++) if (! gstring->glyphs[i].glyph_id) { @@ -1518,8 +1551,10 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring) gstring->glyphs[i].glyph_id = 0; else if (UVS_P (c) && i > 0) check_cmap_uvs (cmap, gstring, i); - else + else if (c < 0x10000) gstring->glyphs[i].glyph_id = cmap->unicode_table[c]; + else if (lookupper) + gstring->glyphs[i].glyph_id = lookupper (c, sub); } return 0; } @@ -1534,6 +1569,7 @@ OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring, char *errfmt = "CMAP Looking up%s"; int errret = -1; OTF_EncodingRecord *enc; + lookup_cmap_func lookupper; if (! otf->cmap && OTF_get_table (otf, "cmap") < 0) @@ -1547,17 +1583,23 @@ OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring, if (i == cmap->numTables) OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)"); enc = cmap->EncodingRecord + i; - switch (enc->subtable.format) - { - case 0: return lookup_encoding_0 (enc->subtable.f.f0, gstring); - case 2: return lookup_encoding_2 (enc->subtable.f.f2, gstring); - case 4: return lookup_encoding_4 (enc->subtable.f.f4, gstring); - case 6: return lookup_encoding_6 (enc->subtable.f.f6, gstring); - case 8: return lookup_encoding_8 (enc->subtable.f.f8, gstring); - case 10: return lookup_encoding_10 (enc->subtable.f.f10, gstring); - case 12: return lookup_encoding_12 (enc->subtable.f.f12, gstring); - } - OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)"); + if (enc->subtable.format > 12) + OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)"); + lookupper = lookup_cmap_func_table[enc->subtable.format / 2]; + + for (i = 0; i < gstring->used; i++) + if (! gstring->glyphs[i].glyph_id) + { + int c = gstring->glyphs[i].c; + if (c < 32 || ! cmap->unicode_table) + gstring->glyphs[i].glyph_id = 0; + else if (UVS_P (c) && i > 0) + check_cmap_uvs (cmap, gstring, i); + else if (c < 0x10000) + gstring->glyphs[i].glyph_id = cmap->unicode_table[c]; + else + gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable); + } } -- 1.7.10.4