From 92b52292483ef57fb568198d129f5eb13b5134db Mon Sep 17 00:00:00 2001 From: handa Date: Tue, 29 Sep 2009 08:09:05 +0000 Subject: [PATCH] Fix previous change. --- src/otf.h | 2 +- src/otfdrive.c | 211 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 142 insertions(+), 71 deletions(-) diff --git a/src/otf.h b/src/otf.h index afdbdb2..2564b80 100644 --- a/src/otf.h +++ b/src/otf.h @@ -1420,7 +1420,7 @@ extern int OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring, /*** (3-9) OTF_iterate_on_feature() */ typedef int (*OTF_Feature_Callback) (OTF *otf, const char *feature, - int c, unsigned glyph_id); + unsigned glyph_id); extern int OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback, const char *script, const char *language, diff --git a/src/otfdrive.c b/src/otfdrive.c index 51e62f5..24981a0 100644 --- a/src/otfdrive.c +++ b/src/otfdrive.c @@ -1847,104 +1847,175 @@ 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) +static int +iterate_coverage (OTF *otf, const char *feature, + OTF_Feature_Callback callback, + OTF_Coverage *coverage) { - char *errfmt = "GSUB iterate feature%s"; - int errret = -1; - int i, j, k, l, m; + int i; - OTF_GSUB *gsub; - OTF_LangSys *langsys; - char *lookup_flags; + if (coverage->CoverageFormat == 1) + { + for (i = 0; i < coverage->Count; i++) + if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0) + return -1; + } + else + { + for (i = 0; i < coverage->Count; i++) + { + OTF_RangeRecord *range = coverage->table.RangeRecord + i; + unsigned id; + for (id = range->Start; id <= range->End; id++) + if (callback (otf, feature, id) < 0) + return -1; + } + } + return 0; +} - 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"); +static int +iterate_feature (OTF *otf, const char *feature, + OTF_Feature_Callback callback, + OTF_Lookup *lookup) +{ + int i, j, k, l; - for (i = 0; i < gsub->LookupList.LookupCount; i++) + for (i = 0; i < lookup->SubTableCount; i++) { - OTF_Lookup *lookup; + unsigned lookup_type = lookup->LookupType; + OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i; - if (! lookup_flags[i]) continue; - lookup = gsub->LookupList.Lookup + i; - for (j = 0; j < lookup->SubTableCount; j++) + if (lookup_type == 7) { - unsigned lookup_type = lookup->LookupType; - OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + j; - int coverage_idx; + OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1; - if (lookup_type == 7) - { - OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1; + lookup_type = extension1->ExtensionLookupType; + subtable = extension1->ExtensionSubtable; + } - lookup_type = extension1->ExtensionLookupType; - subtable = extension1->ExtensionSubtable; - } - if ((lookup_type >= 1 && lookup_type <= 4) || lookup_type == 8) + if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8) + { + if (iterate_coverage (otf, feature, callback, &subtable->Coverage) + < 0) + return -1; + } + else if (lookup_type == 4) + { + OTF_GSUB_Ligature1 *lig1; + + if (iterate_coverage (otf, feature, callback, &subtable->Coverage) + < 0) + return -1; + lig1 = &subtable->u.ligature1; + for (j = 0; j < lig1->LigSetCount; j++) { - OTF_Coverage *coverage = &subtable->Coverage; + OTF_LigatureSet *ligset = lig1->LigatureSet + j; - if (coverage->CoverageFormat == 1) + for (k = 0; k < ligset->LigatureCount; k++) { - 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; - } + OTF_Ligature *lig = ligset->Ligature + k; + for (l = 0; l < lig->CompCount - 1; l++) + if (callback (otf, feature, lig->Component[l]) < 0) + return -1; } - else + } + } + else if (lookup_type == 6) + { + if (subtable->Format == 1) + { + OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1; + for (j = 0; j < context1->ChainRuleSetCount; j++) { - for (k = 0; k < coverage->Count; k++) + OTF_ChainRuleSet *set = context1->ChainRuleSet + j; + for (k = 0; k < set->ChainRuleCount; k++) { - OTF_RangeRecord *range = coverage->table.RangeRecord + k; - unsigned id; - for (id = range->Start; id <= range->End; id++) + OTF_ChainRule *rule = set->ChainRule + k; + for (l = 0; l < rule->LookupCount; l++) { - int c = OTF_get_unicode (otf, id); - if (callback (otf, feature, c, id) < 0) - return 0; + OTF_Lookup *lkup + = (otf->gsub->LookupList.Lookup + + rule->LookupRecord[l].LookupListIndex); + if (iterate_feature (otf, feature, callback, lkup) + < 0) + return -1; } } } + } + else if (subtable->Format == 2) + { + OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2; - if (lookup_type == 4) + for (j = 0; j < context2->ChainClassSetCnt; j++) { - OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1; - - for (k = 0; k < lig1->LigSetCount; k++) + OTF_ChainClassSet *set = context2->ChainClassSet + j; + for (k = 0; k < set->ChainClassRuleCnt; j++) { - OTF_LigatureSet *ligset = lig1->LigatureSet + k; + OTF_ChainClassRule *rule = set->ChainClassRule + k; - for (l = 0; l < ligset->LigatureCount; l++) + for (l = 0; l < rule->LookupCount; 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; - } + OTF_Lookup *lkup + = (otf->gsub->LookupList.Lookup + + rule->LookupRecord[k].LookupListIndex); + if (iterate_feature (otf, feature, callback, lkup) + < 0) + return -1; } } } } + else + { + OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3; + for (j = 0; j < context3->LookupCount; j++) + { + OTF_Lookup *lkup + = (otf->gsub->LookupList.Lookup + + context3->LookupRecord[j].LookupListIndex); + if (iterate_feature (otf, feature, callback, lkup) < 0) + return -1; + } + } } } + return 0; +} + +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; + + 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++) + if (lookup_flags[i]) + if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i) + < 0) + return -1; + return 0; } -- 1.7.10.4