(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
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 ***/
{
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;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}