From d079cb1785768f2958fff718757f6c841f71bc37 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 19 May 2005 01:37:04 +0000 Subject: [PATCH] (enum OTF_ReaderFlag): New enum. (OTF_TableInfo): Change the prototype of the member `reader'. Caller changed. (read_head_table, read_name_table, read_cmap_table) (read_gdef_table): Adjusted for the change of OTF_TableInfo. (read_feature_list): Seek the stream at first. (read_gsub_gpos_table): Adjusted for the change of OTF_TableInfo. Pay attention to the arg `flag'. (read_gsub_table, read_gpos_table): Adjusted for the change of OTF_TableInfo. (OTF_get_table): Likewise. (OTF_get_scripts, OTF_get_features, OTF_check_features): New functions. --- src/otfopen.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 165 insertions(+), 28 deletions(-) diff --git a/src/otfopen.c b/src/otfopen.c index b6ba52e..7385805 100644 --- a/src/otfopen.c +++ b/src/otfopen.c @@ -239,15 +239,26 @@ struct OTF_MemoryRecord typedef struct OTF_MemoryRecord OTF_MemoryRecord; -typedef struct +enum OTF_ReaderFlag + { + OTF_READ_FULL, + OTF_READ_SCRIPTS, + OTF_READ_FEATURES, + OTF_READ_MAX, + }; + +struct _OTF_TableInfo; +typedef struct _OTF_TableInfo OTF_TableInfo; + +struct _OTF_TableInfo { /* Points to one of OTF->head, OTF->name, etc. */ void **address; /* Function to read one of OTF tables. */ - void *(*reader) (OTF *otf, OTF_Stream *stream); + void *(*reader) (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag); /* Stream given to . */ OTF_Stream *stream; -} OTF_TableInfo; +}; struct OTF_InternalData { @@ -317,8 +328,9 @@ allocate_memory_record (OTF *otf) /*** (1-2) "head" table */ static void * -read_head_table (OTF *otf, OTF_Stream *stream) +read_head_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) { + OTF_Stream *stream = table->stream; char *errfmt = "head%s"; void *errret = NULL; OTF_head *head; @@ -331,6 +343,7 @@ read_head_table (OTF *otf, OTF_Stream *stream) READ_USHORT (stream, head->flags); READ_USHORT (stream, head->unitsPerEm); + *table->address = head; return head; } @@ -408,8 +421,9 @@ read_name (OTF *otf, OTF_Stream *stream, OTF_NameRecord *rec) } static void * -read_name_table (OTF *otf, OTF_Stream *stream) +read_name_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) { + OTF_Stream *stream = table->stream; char *errfmt = "name%s"; void *errret = NULL; OTF_name *name; @@ -445,6 +459,7 @@ read_name_table (OTF *otf, OTF_Stream *stream) name->name[nameID] = (char *) rec->name; } + *table->address = name; return name; } @@ -452,8 +467,9 @@ read_name_table (OTF *otf, OTF_Stream *stream) /*** (1-4) "cmap" table */ static void * -read_cmap_table (OTF *otf, OTF_Stream *stream) +read_cmap_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) { + OTF_Stream *stream = table->stream; char *errfmt = "cmap%s"; void *errret = NULL; OTF_cmap *cmap; @@ -712,6 +728,7 @@ read_cmap_table (OTF *otf, OTF_Stream *stream) cmap->max_glyph_id = max_glyph_id; } + *table->address = cmap; return cmap; } @@ -1045,8 +1062,9 @@ read_gdef_header (OTF_Stream *stream, OTF_GDEFHeader *header) } static void * -read_gdef_table (OTF *otf, OTF_Stream *stream) +read_gdef_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) { + OTF_Stream *stream = table->stream; char *errfmt = "GDEF%s"; void *errret = NULL; OTF_GDEF *gdef; @@ -1070,6 +1088,7 @@ read_gdef_table (OTF *otf, OTF_Stream *stream) read_class_def_without_offset (otf, stream, &gdef->mark_attach_class_def); } + *table->address = gdef; return gdef; } @@ -1150,6 +1169,7 @@ read_feature_list (OTF *otf, OTF_Stream *stream, long offset, int errret = -1; int i, j; + SEEK_STREAM (stream, offset); READ_UINT16 (stream, list->FeatureCount); OTF_CALLOC (list->Feature, list->FeatureCount, ""); for (i = 0; i < list->FeatureCount; i++) @@ -1651,25 +1671,47 @@ read_chain_context3 (OTF *otf, OTF_Stream *stream, long offset, } static void * -read_gsub_gpos_table (OTF *otf, OTF_Stream *stream, int gsubp) +read_gsub_gpos_table (OTF *otf, OTF_TableInfo *table, int gsubp, + enum OTF_ReaderFlag flag) { + OTF_Stream *stream = table->stream; char *errfmt = gsubp ? "GSUB%s" : "GPOS%s"; void *errret = NULL; - OTF_GSUB_GPOS *gsub_gpos; - - OTF_CALLOC (gsub_gpos, 1, ""); - READ_FIXED (stream, gsub_gpos->Version); - READ_OFFSET (stream, gsub_gpos->ScriptList.offset); - READ_OFFSET (stream, gsub_gpos->FeatureList.offset); - READ_OFFSET (stream, gsub_gpos->LookupList.offset); - - if (read_script_list (otf, stream, gsub_gpos->ScriptList.offset, - &gsub_gpos->ScriptList) < 0 - || read_feature_list (otf, stream, gsub_gpos->FeatureList.offset, - &gsub_gpos->FeatureList) < 0 - || read_lookup_list (otf, stream, gsub_gpos->LookupList.offset, - &gsub_gpos->LookupList, gsubp) < 0) + OTF_GSUB_GPOS *gsub_gpos = *table->address; + + if (gsub_gpos) + SEEK_STREAM (stream, 10); + else + { + SEEK_STREAM (stream, 0); + OTF_CALLOC (gsub_gpos, 1, ""); + READ_FIXED (stream, gsub_gpos->Version); + READ_OFFSET (stream, gsub_gpos->ScriptList.offset); + READ_OFFSET (stream, gsub_gpos->FeatureList.offset); + READ_OFFSET (stream, gsub_gpos->LookupList.offset); + } + + if (! gsub_gpos->ScriptList.Script + && read_script_list (otf, stream, gsub_gpos->ScriptList.offset, + &gsub_gpos->ScriptList) < 0) return NULL; + if (flag != OTF_READ_SCRIPTS) + { + if (! gsub_gpos->FeatureList.Feature + && read_feature_list (otf, stream, gsub_gpos->FeatureList.offset, + &gsub_gpos->FeatureList) < 0) + return NULL; + if (flag != OTF_READ_FEATURES) + { + if (! gsub_gpos->LookupList.Lookup + && read_lookup_list (otf, stream, gsub_gpos->LookupList.offset, + &gsub_gpos->LookupList, gsubp) < 0) + return NULL; + } + } + + if (! *table->address) + *table->address = gsub_gpos; return gsub_gpos; } @@ -1971,9 +2013,9 @@ read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset, } static void * -read_gsub_table (OTF *otf, OTF_Stream *stream) +read_gsub_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) { - return read_gsub_gpos_table (otf, stream, 1); + return read_gsub_gpos_table (otf, table, 1, flag); } @@ -2499,9 +2541,9 @@ read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream, } static void * -read_gpos_table (OTF *otf, OTF_Stream *stream) +read_gpos_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) { - return read_gsub_gpos_table (otf, stream, 0); + return read_gsub_gpos_table (otf, table, 0, flag); } @@ -2791,14 +2833,18 @@ int OTF_get_table (OTF *otf, char *name) { OTF_TableInfo *table_info = get_table_info (otf, name); + void *address; if (! table_info) return -1; + if (! table_info->stream) + /* Already fully loaded. */ + return 0; - *table_info->address = (*table_info->reader) (otf, table_info->stream); + address = (*table_info->reader) (otf, table_info, OTF_READ_FULL); free_stream (table_info->stream); table_info->stream = NULL; - if (! *table_info->address) + if (! address) { table_info->reader = NULL; return -1; @@ -2814,7 +2860,98 @@ OTF_check_table (OTF *otf, char *name) return (get_table_info (otf, name) ? 0 : -1); } +/*** (2-5) OTF_get_scripts() */ + +int +OTF_get_scripts (OTF *otf, int gsubp) +{ + OTF_TableInfo *table_info + = (otf->internal_data->table_info + + (gsubp ? OTF_TABLE_TYPE_GSUB : OTF_TABLE_TYPE_GPOS)); + void *address; + + if (! table_info->reader) + return -1; + if (! table_info->stream) + /* Already fully loaded. */ + return 0; + address = (*table_info->reader) (otf, table_info, OTF_READ_SCRIPTS); + if (! address) + { + table_info->reader = NULL; + return -1; + } + return 0; +} + +/*** (2-6) OTF_get_features() */ + +int +OTF_get_features (OTF *otf, int gsubp) +{ + OTF_TableInfo *table_info + = (otf->internal_data->table_info + + (gsubp ? OTF_TABLE_TYPE_GSUB : OTF_TABLE_TYPE_GPOS)); + void *address; + + if (! table_info->reader) + return -1; + if (! table_info->stream) + /* Already fully loaded. */ + return 0; + + address = (*table_info->reader) (otf, table_info, OTF_READ_FEATURES); + if (! address) + { + table_info->reader = NULL; + return -1; + } + return 0; +} + +/*** (2-7) OTF_check_features */ + +int +OTF_check_features (OTF *otf, int gsubp, + OTF_Tag script, OTF_Tag language, OTF_Tag *features, + int n_features) +{ + OTF_ScriptList *script_list; + OTF_Script *Script = NULL; + OTF_LangSys *LangSys = NULL; + OTF_FeatureList *feature_list; + int i, j; + + if (OTF_get_features (otf, gsubp) < 0) + return -1; + script_list = &otf->gsub->ScriptList; + feature_list = &otf->gsub->FeatureList; + for (i = 0; i < script_list->ScriptCount && ! Script; i++) + if (script_list->Script[i].ScriptTag == script) + Script = script_list->Script + i; + if (! Script) + return 0; + if (language) + { + for (i = 0; i < Script->LangSysCount && ! LangSys; i++) + if (Script->LangSysRecord[i].LangSysTag == language) + LangSys = Script->LangSys + i; + } + if (! LangSys) + LangSys = &Script->DefaultLangSys; + for (j = 0; j < n_features; j++) + { + OTF_Tag feature = features[j]; + + for (i = 0; i < LangSys->FeatureCount; i++) + if (feature_list->Feature[i].FeatureTag == feature) + break; + if (i == LangSys->FeatureCount) + return 0; + } + return 1; +} /*** (5) API miscellaneous ***/ -- 1.7.10.4