From: handa Date: Tue, 29 Sep 2009 06:12:47 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: REL-0-9-11~62 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=5ec6f1a4429fefdae9967c245d7a2a86726fd11f;p=m17n%2Flibotf.git *** empty log message *** --- diff --git a/ChangeLog b/ChangeLog index 7bbd072..919fdb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-09-29 Kenichi Handa + + * src/otf.h (OTF_Feature_Callback): New type. + (OTF_iterate_gsub_feature): Extern it. + + * src/otfdrive.c (OTF_iterate_gsub_feature): New function. + 2009-08-13 Kenichi Handa * Version 0.9.10 released. diff --git a/src/otf.h b/src/otf.h index 200695d..afdbdb2 100644 --- a/src/otf.h +++ b/src/otf.h @@ -69,6 +69,7 @@ extern "C" { (3-6) OTF_drive_tables() (3-7) OTF_get_unicode() (3-8) OTF_drive_gsub_alternate() + (3-9) OTF_iterate_on_feature() (4) API for error handling (4-1) Error codes @@ -1417,6 +1418,14 @@ extern int OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring, const char *script, const char *language, const char *features); +/*** (3-9) OTF_iterate_on_feature() */ +typedef int (*OTF_Feature_Callback) (OTF *otf, const char *feature, + int c, unsigned glyph_id); + +extern int OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback, + const char *script, const char *language, + const char *feature); + /*** (4) API for error handling ***/ /*** (4-1) Error codes ***/ diff --git a/src/otfdrive.c b/src/otfdrive.c index bb65f7e..51e62f5 100644 --- a/src/otfdrive.c +++ b/src/otfdrive.c @@ -1846,3 +1846,105 @@ OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring, { return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1); } + +int +OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback, + const char *script, const char *language, + const char *feature) +{ + char *errfmt = "GSUB iterate feature%s"; + int errret = -1; + int i, j, k, l, m; + + OTF_GSUB *gsub; + OTF_LangSys *langsys; + char *lookup_flags; + + if (OTF_get_table (otf, "GSUB") < 0) + return errret; + gsub = otf->gsub; + if (gsub->FeatureList.FeatureCount == 0 + || gsub->LookupList.LookupCount == 0) + return 0; + langsys = get_langsys (&gsub->ScriptList, script, language); + if (! langsys) + return errret; + lookup_flags = alloca (gsub->LookupList.LookupCount); + if (! lookup_flags + || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys, + feature, lookup_flags) < 0) + OTF_ERROR (OTF_ERROR_MEMORY, " feature"); + + for (i = 0; i < gsub->LookupList.LookupCount; i++) + { + OTF_Lookup *lookup; + + if (! lookup_flags[i]) continue; + lookup = gsub->LookupList.Lookup + i; + for (j = 0; j < lookup->SubTableCount; j++) + { + unsigned lookup_type = lookup->LookupType; + OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + j; + int coverage_idx; + + if (lookup_type == 7) + { + OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1; + + lookup_type = extension1->ExtensionLookupType; + subtable = extension1->ExtensionSubtable; + } + if ((lookup_type >= 1 && lookup_type <= 4) || lookup_type == 8) + { + OTF_Coverage *coverage = &subtable->Coverage; + + if (coverage->CoverageFormat == 1) + { + for (k = 0; k < coverage->Count; k++) + { + unsigned id = coverage->table.GlyphArray[k]; + int c = OTF_get_unicode (otf, id); + if (callback (otf, feature, c, id) < 0) + return 0; + } + } + else + { + for (k = 0; k < coverage->Count; k++) + { + OTF_RangeRecord *range = coverage->table.RangeRecord + k; + unsigned id; + for (id = range->Start; id <= range->End; id++) + { + int c = OTF_get_unicode (otf, id); + if (callback (otf, feature, c, id) < 0) + return 0; + } + } + } + + if (lookup_type == 4) + { + OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1; + + for (k = 0; k < lig1->LigSetCount; k++) + { + OTF_LigatureSet *ligset = lig1->LigatureSet + k; + + for (l = 0; l < ligset->LigatureCount; l++) + { + OTF_Ligature *lig = ligset->Ligature + l; + for (m = 0; m < lig->CompCount - 1; m++) + { + unsigned id = lig->Component[m]; + int c = OTF_get_unicode (otf, id); + if (callback (otf, feature, c, id) < 0) + return 0; + } + } + } + } + } + } + } +}