From 30d11b2afa7ef0bae8737d8265a359fa7375206f Mon Sep 17 00:00:00 2001 From: handa Date: Mon, 25 Nov 2002 00:10:54 +0000 Subject: [PATCH 1/1] *** empty log message *** --- example/otfdraw.c | 10 +- example/otfdump.c | 76 ++++----- src/otf-open.c | 464 +++++++++++++++++++++++++++++++++-------------------- src/otf-proc.c | 68 +++++--- src/otf.h | 261 ++++++++++++++++++++---------- 5 files changed, 543 insertions(+), 336 deletions(-) diff --git a/example/otfdraw.c b/example/otfdraw.c index 70134e8..8f5bf65 100644 --- a/example/otfdraw.c +++ b/example/otfdraw.c @@ -97,16 +97,16 @@ main (int argc, char **argv) gstring.glyphs[gstring.used++].c = 0x947; gstring.glyphs[gstring.used++].c = 0x915; #endif - otf_cmap (otf, &gstring); - otf_gdef (otf, &gstring); + otf_drive_cmap (otf, &gstring); + otf_drive_gdef (otf, &gstring); otf_dump_gstring (&gstring); - if (otf_gsub (otf, otf_tag ("deva"), 0, &gstring) < 0) + if (otf_drive_gsub (otf, otf_tag ("deva"), 0, &gstring) < 0) printf ("otf_gsub error\n"); else printf ("RESULT of GSUB\n"); otf_dump_gstring (&gstring); - if (otf_gpos (otf, otf_tag ("deva"), 0, &gstring) < 0) + if (otf_drive_gpos (otf, otf_tag ("deva"), 0, &gstring) < 0) printf ("otf_gsub error\n"); else printf ("RESULT of GPOS\n"); @@ -125,7 +125,7 @@ main (int argc, char **argv) if (err == FT_Err_Unknown_File_Format) quit ("FT_New_Face: unknown file format"); else if (err) - quit ("FT_New_Face: another error"); + quit ("FT_New_Face: unknown error"); err = FT_Set_Char_Size (face, 0, 32*64, 400, 400); if (err) quit ("FT_Set_Char_Size"); diff --git a/example/otfdump.c b/example/otfdump.c index ca0600a..2918d7d 100644 --- a/example/otfdump.c +++ b/example/otfdump.c @@ -56,8 +56,6 @@ dump_table_directory (int indent, OTF_TableDirectory *table, int idx) static void dump_head_table (int indent, OTF_head *head) { - int i; - IPRINT ("(head"); indent++; IPRINT ("(TableVersionNumber %d.%d)", @@ -169,8 +167,8 @@ dump_script_list (int indent, OTF_ScriptList *list) OTF_Script *script = list->Script + i; IPRINT ("(Script (%d) ", i); - dump_tag (list->ScriptRecord[i].ScriptTag); - printf (" (Offset #x%04X)", list->ScriptRecord[i].Script); + dump_tag (list->Script[i].ScriptTag); + printf (" (Offset #x%04X)", list->Script[i].offset); indent++; IPRINT ("(DefaultLangSysOffset #x%04X)", script->DefaultLangSysOffset); @@ -202,8 +200,8 @@ dump_feature_list (int indent, OTF_FeatureList *list) OTF_Feature *feature = list->Feature + i; IPRINT ("(Feature (%d) ", i); - dump_tag (list->FeatureRecord[i].FeatureTag); - printf (" (Offset #x%04X)", list->FeatureRecord[i].Feature); + dump_tag (list->Feature[i].FeatureTag); + printf (" (Offset #x%04X)", list->Feature[i].offset); printf (" (LookupCount %d)", feature->LookupCount); if (feature->LookupCount) { @@ -456,7 +454,7 @@ dump_lookup_list (int indent, OTF_LookupList *list, int gsub) OTF_Lookup *lookup = list->Lookup + i; IPRINT ("(Lookup (%d) (Offset #x%04X)", - i, list->LookupOffset[i]); + i, lookup->offset); printf (" (Type %d) (Flag #x%04X) (SubTableCount %d)", lookup->LookupType, lookup->LookupFlag, lookup->SubTableCount); if (gsub) @@ -476,18 +474,6 @@ dump_lookup_list (int indent, OTF_LookupList *list, int gsub) /* GSUB */ -static void -dump_gsub_header (int indent, OTF_GSUBHeader *header) -{ - IPRINT ("(Header"); - indent++; - IPRINT ("(Version %d.%d)", - header->Version.high, header->Version.low); - IPRINT ("(ScriptList #x%04X)", header->ScriptList); - IPRINT ("(FeatureList #x%04X)", header->FeatureList); - IPRINT ("(LookupList #x%04X))", header->LookupList); -} - static void dump_lookup_subtable_gsub (int indent, int index, unsigned type, @@ -594,10 +580,16 @@ dump_gsub_table (int indent, OTF_GSUB *gsub) { IPRINT ("(GSUB"); indent++; - dump_gsub_header (indent, &gsub->header); - dump_script_list (indent, &gsub->script_list); - dump_feature_list (indent, &gsub->feature_list); - dump_lookup_list (indent, &gsub->lookup_list, 1); + IPRINT ("(Header"); + indent++; + IPRINT ("(Version %d.%d)", gsub->Version.high, gsub->Version.low); + IPRINT ("(ScriptList #x%04X)", gsub->ScriptList.offset); + IPRINT ("(FeatureList #x%04X)", gsub->FeatureList.offset); + IPRINT ("(LookupList #x%04X))", gsub->LookupList.offset); + indent--; + dump_script_list (indent, &gsub->ScriptList); + dump_feature_list (indent, &gsub->FeatureList); + dump_lookup_list (indent, &gsub->LookupList, 1); printf (")"); } @@ -735,10 +727,16 @@ dump_gpos_table (int indent, OTF_GPOS *gpos) { IPRINT ("(GPOS"); indent++; - dump_gsub_header (indent, (OTF_GPOSHeader *) &gpos->header); - dump_script_list (indent, &gpos->script_list); - dump_feature_list (indent, &gpos->feature_list); - dump_lookup_list (indent, &gpos->lookup_list, 0); + IPRINT ("(Header"); + indent++; + IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low); + IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset); + IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset); + IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset); + indent--; + dump_script_list (indent, &gpos->ScriptList); + dump_feature_list (indent, &gpos->FeatureList); + dump_lookup_list (indent, &gpos->LookupList, 0); printf (")"); } @@ -965,23 +963,15 @@ otf_dump (OTF *otf) dump_offset_table (1, &otf->offset_table); for (i = 0; i < otf->offset_table.numTables; i++) dump_table_directory (1, otf->table_dirs + i, i); - if (otf->head) - dump_head_table (1, otf->head); - if (otf->name) - dump_name_table (1, otf->name); - if (otf->cmap) - dump_cmap_table (1, otf->cmap); - if (otf->gdef) - dump_gdef_table (1, otf->gdef); - if (otf->gsub) - dump_gsub_table (1, otf->gsub); - if (otf->gpos) - dump_gpos_table (1, otf->gpos); + dump_head_table (1, (OTF_head *) otf_get_table (otf, otf_tag ("head"))); + dump_name_table (1, (OTF_name *) otf_get_table (otf, otf_tag ("name"))); + dump_cmap_table (1, (OTF_cmap *) otf_get_table (otf, otf_tag ("cmap"))); + dump_gdef_table (1, (OTF_GDEF *) otf_get_table (otf, otf_tag ("GDEF"))); + dump_gsub_table (1, (OTF_GSUB *) otf_get_table (otf, otf_tag ("GSUB"))); + dump_gpos_table (1, (OTF_GPOS *) otf_get_table (otf, otf_tag ("GPOS"))); #if 0 - if (otf->base) - dump_base_table (otf->base); - if (otf->jstf) - dump_jstf_table (otf->jstf); + dump_base_table (1, (OTF_BASE *) otf_get_table (otf, otf_tag ("BASE"))); + dump_jstf_table (1, (OTF_JSTF *) otf_get_table (otf, otf_tag ("JSTF"))); #endif printf (")\n"); } diff --git a/src/otf-open.c b/src/otf-open.c index 92e1b07..6d0e33f 100644 --- a/src/otf-open.c +++ b/src/otf-open.c @@ -27,36 +27,22 @@ */ -typedef struct -{ - FILE *fp; - char *name; - long pos; - long bufsize; - long allocated; - unsigned char *buf; -} OTF_Stream; - typedef long OTF_StreamState; OTF_Stream * -stream_open (char *filename) +make_stream () { - FILE *fp; OTF_Stream *stream; - char *errfmt = "stream open for %s"; + char *errfmt = "stream creation%s"; void *errret = NULL; - fp = fopen (filename, "r"); - if (! fp) - OTF_ERROR (OTF_ERROR_FILE, filename); - OTF_CALLOC (stream, 1, filename); - stream->fp = fp; + OTF_CALLOC (stream, 1, ""); return stream; } int -stream_setup (OTF_Stream *stream, long offset, int nbytes, char *name) +setup_stream (OTF_Stream *stream, FILE *fp, long offset, int nbytes, + char *name) { char *errfmt = "stream setup for %s"; int errret = -1; @@ -75,38 +61,31 @@ stream_setup (OTF_Stream *stream, long offset, int nbytes, char *name) stream->allocated = nbytes; } stream->bufsize = nbytes; - if (fseek (stream->fp, offset, SEEK_SET) < 0) + if (fseek (fp, offset, SEEK_SET) < 0) OTF_ERROR (OTF_ERROR_FILE, stream->name); - if (fread (stream->buf, 1, nbytes, stream->fp) != nbytes) + if (fread (stream->buf, 1, nbytes, fp) != nbytes) OTF_ERROR (OTF_ERROR_FILE, stream->name); return 0; } void -stream_close (OTF_Stream *stream) +free_stream (OTF_Stream *stream) { - fclose (stream->fp); + free (stream->buf); free (stream); } -#define STREAM_SAVE_STATE(stream, state) ((state) = (stream)->pos) -#define STREAM_RESTORE_STATE(stream, state) ((stream)->pos = (state)) -#define STREAM_SEEK(stream, offset) ((stream)->pos = (offset)) - -int -stream_overrun (OTF_Stream *stream) -{ - char *errfmt = "buffer overrun in %s"; - int errret = -1; - - OTF_ERROR (OTF_ERROR_TABLE, (stream)->name); -} +#define SAVE_STREAM(stream, state) ((state) = (stream)->pos) +#define RESTORE_STREAM(stream, state) ((stream)->pos = (state)) +#define SEEK_STREAM(stream, offset) ((stream)->pos = (offset)) #define STREAM_CHECK_SIZE(stream, size) \ if ((stream)->pos + (size) > (stream)->bufsize) \ { \ - stream_overrun (stream); \ + char *errfmt = "buffer overrun in %s"; \ + \ + OTF_ERROR (OTF_ERROR_TABLE, (stream)->name); \ return errret; \ } \ else @@ -185,21 +164,28 @@ read_offset_table (OTF_Stream *stream, OTF_OffsetTable *table) return 0; } -static int +static OTF_Tag read_table_directory (OTF_Stream *stream, OTF_TableDirectory *table) { - int errret = -1; - - READ_TAG (stream, table->tag); + int errret = 0; + OTF_Tag tag; + + READ_TAG (stream, tag); + table->tag = tag; + table->name[0] = tag >> 24; + table->name[1] = (tag >> 16) & 0xFF; + table->name[0] = (tag >> 8) & 0xFF; + table->name[0] = tag >> 8; + table->name[0] = '\0'; READ_ULONG (stream, table->checkSum); READ_ULONG (stream, table->offset); READ_ULONG (stream, table->length); - return 0; + return tag; } -OTF_head * +static void * read_head_table (OTF_Stream *stream) { char *errfmt = "head%s"; @@ -217,6 +203,12 @@ read_head_table (OTF_Stream *stream) return head; } +static void +free_head_table (OTF_head *head) +{ + free (head); +} + static int @@ -226,22 +218,21 @@ read_script_list (OTF_Stream *stream, long offset, OTF_ScriptList *list) int errret = -1; int i, j, k; - STREAM_SEEK (stream, offset); + SEEK_STREAM (stream, offset); READ_USHORT (stream, list->ScriptCount); - OTF_MALLOC (list->ScriptRecord, list->ScriptCount, ""); OTF_CALLOC (list->Script, list->ScriptCount, ""); for (i = 0; i < list->ScriptCount; i++) { - READ_TAG (stream, list->ScriptRecord[i].ScriptTag); - READ_OFFSET (stream, list->ScriptRecord[i].Script); + READ_TAG (stream, list->Script[i].ScriptTag); + READ_OFFSET (stream, list->Script[i].offset); } for (i = 0; i < list->ScriptCount; i++) { OTF_Script *script = list->Script + i; - long script_offset = offset + list->ScriptRecord[i].Script; + long script_offset = offset + script->offset; - STREAM_SEEK (stream, script_offset); + SEEK_STREAM (stream, script_offset); READ_OFFSET (stream, script->DefaultLangSysOffset); READ_USHORT (stream, script->LangSysCount); OTF_MALLOC (script->LangSysRecord, script->LangSysCount, " (LangSys)"); @@ -256,7 +247,7 @@ read_script_list (OTF_Stream *stream, long offset, OTF_ScriptList *list) { OTF_LangSys *langsys = &script->DefaultLangSys; - STREAM_SEEK (stream, script_offset + script->DefaultLangSysOffset); + SEEK_STREAM (stream, script_offset + script->DefaultLangSysOffset); READ_OFFSET (stream, langsys->LookupOrder); READ_USHORT (stream, langsys->ReqFeatureIndex); READ_USHORT (stream, langsys->FeatureCount); @@ -270,7 +261,7 @@ read_script_list (OTF_Stream *stream, long offset, OTF_ScriptList *list) { OTF_LangSys *langsys = script->LangSys + j; - STREAM_SEEK (stream, + SEEK_STREAM (stream, script_offset + script->LangSysRecord[j].LangSys); READ_OFFSET (stream, langsys->LookupOrder); READ_USHORT (stream, langsys->ReqFeatureIndex); @@ -293,18 +284,17 @@ read_feature_list (OTF_Stream *stream, long offset, OTF_FeatureList *list) int i, j; READ_UINT16 (stream, list->FeatureCount); - OTF_MALLOC (list->FeatureRecord, list->FeatureCount, ""); OTF_CALLOC (list->Feature, list->FeatureCount, ""); for (i = 0; i < list->FeatureCount; i++) { - READ_TAG (stream, list->FeatureRecord[i].FeatureTag); - READ_OFFSET (stream, list->FeatureRecord[i].Feature); + READ_TAG (stream, list->Feature[i].FeatureTag); + READ_OFFSET (stream, list->Feature[i].offset); } for (i = 0; i < list->FeatureCount; i++) { OTF_Feature *feature = list->Feature + i; - STREAM_SEEK (stream, offset + list->FeatureRecord[i].Feature); + SEEK_STREAM (stream, offset + feature->offset); READ_OFFSET (stream, feature->FeatureParams); READ_UINT16 (stream, feature->LookupCount); OTF_MALLOC (feature->LookupListIndex, feature->LookupCount, @@ -331,18 +321,17 @@ read_lookup_list (OTF_Stream *stream, long offset, int errret = -1; int i, j; - STREAM_SEEK (stream, offset); + SEEK_STREAM (stream, offset); READ_UINT16 (stream, list->LookupCount); - OTF_MALLOC (list->LookupOffset, list->LookupCount, ""); OTF_CALLOC (list->Lookup, list->LookupCount, ""); for (i = 0; i < list->LookupCount; i++) - READ_OFFSET (stream, list->LookupOffset[i]); + READ_OFFSET (stream, list->Lookup[i].offset); for (i = 0; i < list->LookupCount; i++) { OTF_Lookup *lookup = list->Lookup + i; - STREAM_SEEK (stream, offset + list->LookupOffset[i]); + SEEK_STREAM (stream, offset + lookup->offset); READ_UINT16 (stream, lookup->LookupType); READ_UINT16 (stream, lookup->LookupFlag); READ_UINT16 (stream, lookup->SubTableCount); @@ -356,7 +345,7 @@ read_lookup_list (OTF_Stream *stream, long offset, for (j = 0; j < lookup->SubTableCount; j++) { long this_offset - = offset + list->LookupOffset[i] + lookup->SubTableOffset[j]; + = offset + lookup->offset + lookup->SubTableOffset[j]; if (read_lookup_subtable_gsub (stream, this_offset, lookup->LookupType, @@ -367,7 +356,7 @@ read_lookup_list (OTF_Stream *stream, long offset, for (j = 0; j < lookup->SubTableCount; j++) { long this_offset - = offset + list->LookupOffset[i] + lookup->SubTableOffset[j]; + = offset + lookup->offset + lookup->SubTableOffset[j]; if (read_lookup_subtable_gpos (stream, this_offset, lookup->LookupType, @@ -428,8 +417,8 @@ read_coverage (OTF_Stream *stream, long offset, OTF_Coverage *coverage) int count; READ_OFFSET (stream, coverage->offset); - STREAM_SAVE_STATE (stream, state); - STREAM_SEEK (stream, offset + coverage->offset); + SAVE_STREAM (stream, state); + SEEK_STREAM (stream, offset + coverage->offset); READ_UINT16 (stream, coverage->CoverageFormat); if (coverage->CoverageFormat == 1) count = read_glyph_ids (stream, &coverage->table.GlyphArray, 0); @@ -440,7 +429,7 @@ read_coverage (OTF_Stream *stream, long offset, OTF_Coverage *coverage) if (count < 0) return -1; coverage->Count = (unsigned) count; - STREAM_RESTORE_STATE (stream, state); + RESTORE_STREAM (stream, state); return 0; } @@ -469,7 +458,7 @@ read_class_def_without_offset (OTF_Stream *stream, OTF_ClassDef *class) char *errfmt = "ClassDef%s"; int errret = -1; - STREAM_SEEK (stream, class->offset); + SEEK_STREAM (stream, class->offset); READ_UINT16 (stream, class->ClassFormat); if (class->ClassFormat == 1) { @@ -502,8 +491,8 @@ read_class_def (OTF_Stream *stream, long offset, OTF_ClassDef *class) OTF_StreamState state; READ_OFFSET (stream, class->offset); - STREAM_SAVE_STATE (stream, state); - STREAM_SEEK (stream, offset + class->offset); + SAVE_STREAM (stream, state); + SEEK_STREAM (stream, offset + class->offset); READ_UINT16 (stream, class->ClassFormat); if (class->ClassFormat == 1) { @@ -525,10 +514,25 @@ read_class_def (OTF_Stream *stream, long offset, OTF_ClassDef *class) else OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)"); - STREAM_RESTORE_STATE (stream, state); + RESTORE_STREAM (stream, state); return 0; } +static void +free_class_def (OTF_ClassDef *class) +{ + if (class->ClassFormat == 1) + { + if (class->f.f1.GlyphCount) + free (class->f.f1.ClassValueArray); + } + else if (class->ClassFormat == 2) + { + + } +} + + static int read_device_table (OTF_Stream *stream, long offset, OTF_DeviceTable *table) { @@ -543,7 +547,7 @@ read_device_table (OTF_Stream *stream, long offset, OTF_DeviceTable *table) int int8 : 8; } intval; - STREAM_SEEK (stream, offset + table->offset); + SEEK_STREAM (stream, offset + table->offset); READ_UINT16 (stream, table->StartSize); READ_UINT16 (stream, table->EndSize); READ_UINT16 (stream, table->DeltaFormat); @@ -590,19 +594,7 @@ read_device_table (OTF_Stream *stream, long offset, OTF_DeviceTable *table) /* GSUB */ -static int -read_gsub_header (OTF_Stream *stream, OTF_GSUBHeader *header) -{ - int errret = -1; - - READ_FIXED (stream, header->Version); - READ_OFFSET (stream, header->ScriptList); - READ_OFFSET (stream, header->FeatureList); - READ_OFFSET (stream, header->LookupList); - return 0; -} - -static OTF_GSUB * +static void * read_gsub_table (OTF_Stream *stream) { char *errfmt = "GSUB%s"; @@ -610,13 +602,17 @@ read_gsub_table (OTF_Stream *stream) OTF_GSUB *gsub; OTF_CALLOC (gsub, 1, ""); - if (read_gsub_header (stream, &gsub->header) < 0 - || read_script_list (stream, gsub->header.ScriptList, - &gsub->script_list) < 0 - || read_feature_list (stream, gsub->header.FeatureList, - &gsub->feature_list) < 0 - || read_lookup_list (stream, gsub->header.LookupList, - &gsub->lookup_list, 1) < 0) + READ_FIXED (stream, gsub->Version); + READ_OFFSET (stream, gsub->ScriptList.offset); + READ_OFFSET (stream, gsub->FeatureList.offset); + READ_OFFSET (stream, gsub->LookupList.offset); + + if (read_script_list (stream, gsub->ScriptList.offset, + &gsub->ScriptList) < 0 + || read_feature_list (stream, gsub->FeatureList.offset, + &gsub->FeatureList) < 0 + || read_lookup_list (stream, gsub->LookupList.offset, + &gsub->LookupList, 1) < 0) return NULL; return gsub; } @@ -638,7 +634,7 @@ read_sequence (OTF_Stream *stream, long offset, OTF_Sequence **seq) READ_OFFSET (stream, (*seq)[i].offset); for (i = 0; i < count; i++) { - STREAM_SEEK (stream, offset + (*seq)[i].offset); + SEEK_STREAM (stream, offset + (*seq)[i].offset); (*seq)[i].GlyphCount = read_glyph_ids (stream, &(*seq)[i].Substitute, 0); if (! (*seq)[i].GlyphCount) return 0; @@ -662,7 +658,7 @@ read_ligature (OTF_Stream *stream, long offset, OTF_Ligature **ligature) READ_OFFSET (stream, (*ligature)[i].offset); for (i = 0; i < count; i++) { - STREAM_SEEK (stream, offset + (*ligature)[i].offset); + SEEK_STREAM (stream, offset + (*ligature)[i].offset); READ_GLYPHID (stream, (*ligature)[i].LigGlyph); (*ligature)[i].CompCount = read_glyph_ids (stream, &(*ligature)[i].Component, -1); @@ -690,7 +686,7 @@ read_ligature_set (OTF_Stream *stream, long offset, OTF_LigatureSet **ligset) { int lig_count; - STREAM_SEEK (stream, offset + (*ligset)[i].offset); + SEEK_STREAM (stream, offset + (*ligset)[i].offset); lig_count = read_ligature (stream, offset + (*ligset)[i].offset, &(*ligset)[i].Ligature); if (lig_count < 0) @@ -736,7 +732,7 @@ read_chain_subrule (OTF_Stream *stream, long offset, OTF_ChainSubRule **rule) READ_OFFSET (stream, (*rule)[i].offset); for (i = 0; i < count; i++) { - STREAM_SEEK (stream, offset + (*rule)[i].offset); + SEEK_STREAM (stream, offset + (*rule)[i].offset); (*rule)[i].BacktrackGlyphCount = read_glyph_ids (stream, &(*rule)[i].Backtrack, 0); if (! (*rule)[i].BacktrackGlyphCount) @@ -775,7 +771,7 @@ read_chain_subrule_set (OTF_Stream *stream, long offset, READ_OFFSET (stream, (*set)[i].offset); for (i = 0; i < count; i++) { - STREAM_SEEK (stream, offset + (*set)[i].offset); + SEEK_STREAM (stream, offset + (*set)[i].offset); (*set)[i].ChainSubRuleCount = read_chain_subrule (stream, offset + (*set)[i].offset, &(*set)[i].ChainSubRule); @@ -802,7 +798,7 @@ read_chain_subclass_rule (OTF_Stream *stream, long offset, READ_OFFSET (stream, (*rule)[i].offset); for (i = 0; i < count; i++) { - STREAM_SEEK (stream, offset + (*rule)[i].offset); + SEEK_STREAM (stream, offset + (*rule)[i].offset); (*rule)[i].BacktrackGlyphCount = read_glyph_ids (stream, (OTF_GlyphID **) &(*rule)[i].Backtrack, 0); if (! (*rule)[i].BacktrackGlyphCount) @@ -840,7 +836,7 @@ read_chain_subclass_set (OTF_Stream *stream, long offset, READ_OFFSET (stream, (*set)[i].offset); for (i = 0; i < count; i++) { - STREAM_SEEK (stream, offset + (*set)[i].offset); + SEEK_STREAM (stream, offset + (*set)[i].offset); (*set)[i].ChainSubClassRuleCnt = read_chain_subclass_rule (stream, offset + (*set)[i].offset, &(*set)[i].ChainSubClassRule); @@ -859,7 +855,7 @@ read_lookup_subtable_gsub (OTF_Stream *stream, long offset, int errret = -1; int count; - STREAM_SEEK (stream, offset); + SEEK_STREAM (stream, offset); READ_UINT16 (stream, subtable->Format); switch (type) { @@ -1007,7 +1003,7 @@ read_value_record (OTF_Stream *stream, long offset, READ_OFFSET (stream, value_record->XAdvDevice.offset); if (bit & OTF_YAdvDevice) READ_OFFSET (stream, value_record->YAdvDevice.offset); - STREAM_SAVE_STATE (stream, state); + SAVE_STREAM (stream, state); if (value_record->XPlaDevice.offset) { if (read_device_table (stream, offset, &value_record->XPlaDevice) < 0) @@ -1028,7 +1024,7 @@ read_value_record (OTF_Stream *stream, long offset, if (read_device_table (stream, offset, &value_record->YAdvDevice) < 0) return -1; } - STREAM_RESTORE_STATE (stream, state); + RESTORE_STREAM (stream, state); return 0; } @@ -1039,7 +1035,7 @@ read_anchor (OTF_Stream *stream, long offset, OTF_Anchor *anchor) char *errfmt = "Anchor%s"; int errret = -1; - STREAM_SEEK (stream, offset + anchor->offset); + SEEK_STREAM (stream, offset + anchor->offset); READ_UINT16 (stream, anchor->AnchorFormat); READ_INT16 (stream, anchor->XCoordinate); READ_INT16 (stream, anchor->YCoordinate); @@ -1081,8 +1077,8 @@ read_mark_array (OTF_Stream *stream, long offset, OTF_MarkArray *array) int i; READ_OFFSET (stream, array->offset); - STREAM_SAVE_STATE (stream, state); - STREAM_SEEK (stream, offset + array->offset); + SAVE_STREAM (stream, state); + SEEK_STREAM (stream, offset + array->offset); READ_UINT16 (stream, array->MarkCount); OTF_MALLOC (array->MarkRecord, array->MarkCount, ""); for (i = 0; i < array->MarkCount; i++) @@ -1094,7 +1090,7 @@ read_mark_array (OTF_Stream *stream, long offset, OTF_MarkArray *array) if (read_anchor (stream, offset + array->offset, &array->MarkRecord[i].MarkAnchor) < 0) return -1;; - STREAM_RESTORE_STATE (stream, state); + RESTORE_STREAM (stream, state); return 0; } @@ -1108,8 +1104,8 @@ read_base_array (OTF_Stream *stream, long offset, int i, j; READ_OFFSET (stream, array->offset); - STREAM_SAVE_STATE (stream, state); - STREAM_SEEK (stream, offset + array->offset); + SAVE_STREAM (stream, state); + SEEK_STREAM (stream, offset + array->offset); READ_UINT16 (stream, array->BaseCount); OTF_MALLOC (array->BaseRecord, array->BaseCount, ""); for (i = 0; i < array->BaseCount; i++) @@ -1124,7 +1120,7 @@ read_base_array (OTF_Stream *stream, long offset, if (read_anchor (stream, offset + array->offset, &array->BaseRecord[i].BaseAnchor[j]) < 0) return -1; - STREAM_RESTORE_STATE (stream, state); + RESTORE_STREAM (stream, state); return 0; } @@ -1163,7 +1159,7 @@ read_lookup_subtable_gpos (OTF_Stream *stream, long offset, unsigned type, char *errfmt = "GPOS LookupSubTable%s"; int errret = -1; - STREAM_SEEK (stream, offset); + SEEK_STREAM (stream, offset); READ_UINT16 (stream, subtable->Format); switch (type) { @@ -1193,7 +1189,7 @@ read_lookup_subtable_gpos (OTF_Stream *stream, long offset, unsigned type, } else if (subtable->Format == 2) { - STREAM_SEEK (stream, offset + 2); + SEEK_STREAM (stream, offset + 2); read_coverage (stream, offset, &subtable->Coverage); READ_UINT16 (stream, subtable->sub.gpos.pair2.ValueFormat1); READ_UINT16 (stream, subtable->sub.gpos.pair2.ValueFormat2); @@ -1284,21 +1280,25 @@ read_lookup_subtable_gpos (OTF_Stream *stream, long offset, unsigned type, } -static OTF_GPOS * +static void * read_gpos_table (OTF_Stream *stream) { char *errfmt = "GPOS%s"; void *errret = NULL; OTF_GPOS *gpos; - OTF_MALLOC (gpos, 1, ""); - if (read_gsub_header (stream, (OTF_GPOSHeader *) &gpos->header) < 0 - || read_script_list (stream, gpos->header.ScriptList, - &gpos->script_list) < 0 - || read_feature_list (stream, gpos->header.FeatureList, - &gpos->feature_list) < 0 - || read_lookup_list (stream, gpos->header.LookupList, - &gpos->lookup_list, 0) < 0) + OTF_CALLOC (gpos, 1, ""); + READ_FIXED (stream, gpos->Version); + READ_OFFSET (stream, gpos->ScriptList.offset); + READ_OFFSET (stream, gpos->FeatureList.offset); + READ_OFFSET (stream, gpos->LookupList.offset); + + if (read_script_list (stream, gpos->ScriptList.offset, + &gpos->ScriptList) < 0 + || read_feature_list (stream, gpos->FeatureList.offset, + &gpos->FeatureList) < 0 + || read_lookup_list (stream, gpos->LookupList.offset, + &gpos->LookupList, 0) < 0) return NULL; return gpos; } @@ -1349,7 +1349,7 @@ read_attach_list (OTF_Stream *stream, long offset, OTF_AttachList *list) { int count; - STREAM_SEEK (stream, offset + list->AttachPoint[i].offset); + SEEK_STREAM (stream, offset + list->AttachPoint[i].offset); READ_UINT16 (stream, count); list->AttachPoint[i].PointCount = count; OTF_MALLOC (list->AttachPoint[i].PointIndex, count, " (PointIndex)"); @@ -1359,13 +1359,18 @@ read_attach_list (OTF_Stream *stream, long offset, OTF_AttachList *list) return 0; } +static void +free_attach_list (OTF_AttachList *list) +{ +} + static int read_caret_value (OTF_Stream *stream, long offset, OTF_CaretValue *caret) { char *errfmt = "CaretValue%s"; int errret = -1; - STREAM_SEEK (stream, offset + caret->offset); + SEEK_STREAM (stream, offset + caret->offset); READ_UINT16 (stream, caret->CaretValueFormat); if (caret->CaretValueFormat == 1) READ_INT16 (stream, caret->f.f1.Coordinate); @@ -1400,7 +1405,7 @@ read_lig_caret_list (OTF_Stream *stream, long offset, OTF_LigCaretList *list) { int count; - STREAM_SEEK (stream, offset + list->LigGlyph[i].offset); + SEEK_STREAM (stream, offset + list->LigGlyph[i].offset); READ_UINT16 (stream, count); list->LigGlyph[i].CaretCount = count; OTF_MALLOC (list->LigGlyph[i].CaretValue, count, " (CaretValue)"); @@ -1414,6 +1419,10 @@ read_lig_caret_list (OTF_Stream *stream, long offset, OTF_LigCaretList *list) return 0; } +static void +free_lig_caret_list (OTF_LigCaretList *list) +{ +} static int read_gdef_header (OTF_Stream *stream, OTF_GDEFHeader *header) @@ -1428,7 +1437,7 @@ read_gdef_header (OTF_Stream *stream, OTF_GDEFHeader *header) return 0; } -static OTF_GDEF * +static void * read_gdef_table (OTF_Stream *stream) { char *errfmt = "GDEF%s"; @@ -1457,11 +1466,26 @@ read_gdef_table (OTF_Stream *stream) return gdef; } +static void +free_gdef_table (OTF_GDEF *gdef) +{ + if (gdef->header.GlyphClassDef) + free_class_def (&gdef->glyph_class_def); + if (gdef->header.AttachList) + free_attach_list (&gdef->attach_list); + if (gdef->header.LigCaretList) + free_lig_caret_list (&gdef->lig_caret_list); + if (gdef->header.MarkAttachClassDef) + free_class_def (&gdef->mark_attach_class_def); + free (gdef); +} + + /* cmap */ -static OTF_cmap * +static void * read_cmap_table (OTF_Stream *stream) { char *errfmt = "cmap%s"; @@ -1486,7 +1510,7 @@ read_cmap_table (OTF_Stream *stream) { unsigned format; - STREAM_SEEK (stream, cmap->EncodingRecord[i].offset); + SEEK_STREAM (stream, cmap->EncodingRecord[i].offset); READ_USHORT (stream, format); cmap->EncodingRecord[i].subtable.format = format; READ_USHORT (stream, cmap->EncodingRecord[i].subtable.length); @@ -1559,9 +1583,39 @@ read_cmap_table (OTF_Stream *stream) return cmap; } +static void +free_cmap_table (OTF_cmap *cmap) +{ + int i; + + for (i = 0; i < cmap->numTables; i++) + { + unsigned format = cmap->EncodingRecord[i].subtable.format; + + switch (format) + { + case 0: + free (cmap->EncodingRecord[i].subtable.f.f0); + break; + + case 4: + { + OTF_EncodingSubtable4 *sub4 + = cmap->EncodingRecord[i].subtable.f.f4; + + free (sub4->glyphIdArray); + free (sub4->segments); + free (sub4); + } + break; + } + } + free (cmap); +} + -/* name */ +/* TABLE: name */ static char * read_name (OTF_Stream *stream, OTF_NameRecord *rec, int bytes) @@ -1573,8 +1627,8 @@ read_name (OTF_Stream *stream, OTF_NameRecord *rec, int bytes) int i; int c; - STREAM_SAVE_STATE (stream, state); - STREAM_SEEK (stream, stream->pos + rec->offset); + SAVE_STREAM (stream, state); + SEEK_STREAM (stream, stream->pos + rec->offset); if (bytes == 1) { @@ -1607,11 +1661,11 @@ read_name (OTF_Stream *stream, OTF_NameRecord *rec, int bytes) } } str[i] = '\0'; - STREAM_RESTORE_STATE (stream, state); + RESTORE_STREAM (stream, state); return str; } -static OTF_name * +static void * read_name_table (OTF_Stream *stream) { char *errfmt = "name%s"; @@ -1659,32 +1713,47 @@ read_name_table (OTF_Stream *stream) return name; } +static void +free_name_table (OTF_name *name) +{ + int i; + + for (i = 0; i < name->count; i++) + if (name->name[i]) + free (name->name[i]); + + free (name->nameRecord); + free (name); +} +/* APIs */ + OTF * otf_open (char *otf_name) { + FILE *fp; char *errfmt = "OTF%s"; void *errret = NULL; OTF_Stream *stream; OTF *otf; - OTF_Tag head_tag, cmap_tag, name_tag, gdef_tag, gsub_tag, gpos_tag; + OTF_Tag head_tag, name_tag, cmap_tag, gdef_tag, gsub_tag, gpos_tag; int i; - stream = stream_open (otf_name); - if (! stream) - return NULL; + fp = fopen (otf_name, "r"); + if (! fp) + OTF_ERROR (OTF_ERROR_FILE, otf_name); head_tag = otf_tag ("head"); - cmap_tag = otf_tag ("cmap"); name_tag = otf_tag ("name"); + cmap_tag = otf_tag ("cmap"); gdef_tag = otf_tag ("GDEF"); gsub_tag = otf_tag ("GSUB"); gpos_tag = otf_tag ("GPOS"); - /* Size of Offset Table in OTF is 12 bytes. */ - if (stream_setup (stream, 0, 12, "Offset Table") < 0) + stream = make_stream (); + if (! stream) return NULL; OTF_CALLOC_GOTO (otf, 1, " (body)", err); @@ -1694,68 +1763,62 @@ otf_open (char *otf_name) otf_error = OTF_ERROR_MEMORY; goto err; } + /* Size of Offset Table is 12 bytes. */ + if (setup_stream (stream, fp, 0, 12, "Offset Table") < 0) + goto err; if (read_offset_table (stream, &otf->offset_table) < 0) goto err; - /* Size of each Table Directory in OTF is 16 bytes. */ - if (stream_setup (stream, 12, 16 * otf->offset_table.numTables, + /* Size of each Table Directory is 16 bytes. */ + if (setup_stream (stream, fp, 12, 16 * otf->offset_table.numTables, "Table Directory") < 0) goto err; OTF_CALLOC_GOTO (otf->table_dirs, otf->offset_table.numTables, " (OffsetTable)", err); for (i = 0; i < otf->offset_table.numTables; i++) - if (read_table_directory (stream, otf->table_dirs + i) < 0) - goto err; - - for (i = 0; i < otf->offset_table.numTables; i++) { - if (otf->table_dirs[i].tag == head_tag) - { - stream_setup (stream, otf->table_dirs[i].offset, - otf->table_dirs[i].length, "head"); - otf->head = read_head_table (stream); - } - else if (otf->table_dirs[i].tag == cmap_tag) - { - stream_setup (stream, otf->table_dirs[i].offset, - otf->table_dirs[i].length, "cmap"); - otf->cmap = read_cmap_table (stream); - } - else if (otf->table_dirs[i].tag == name_tag) - { - stream_setup (stream, otf->table_dirs[i].offset, - otf->table_dirs[i].length, "name"); - otf->name = read_name_table (stream); - } - else if (otf->table_dirs[i].tag == gdef_tag) - { - stream_setup (stream, otf->table_dirs[i].offset, - otf->table_dirs[i].length, "GDEF"); - otf->gdef = read_gdef_table (stream); - } - else if (otf->table_dirs[i].tag == gsub_tag) - { - stream_setup (stream, otf->table_dirs[i].offset, - otf->table_dirs[i].length, "GSUB"); - otf->gsub = read_gsub_table (stream); - } - else if (otf->table_dirs[i].tag == gpos_tag) + OTF_Tag tag = read_table_directory (stream, otf->table_dirs + i); + + if (! tag) + goto err; + if (tag == head_tag) + otf->head = otf->table_dirs + i; + else if (tag == name_tag) + otf->name = otf->table_dirs + i; + else if (tag == cmap_tag) + otf->cmap = otf->table_dirs + i; + else if (tag == gdef_tag) + otf->gdef = otf->table_dirs + i; + else if (tag == gsub_tag) + otf->gsub = otf->table_dirs + i; + else if (tag == gpos_tag) + otf->gpos = otf->table_dirs + i; + else + tag = 0; + + if (tag) { - stream_setup (stream, otf->table_dirs[i].offset, - otf->table_dirs[i].length, "GPOS"); - otf->gpos = read_gpos_table (stream); + otf->table_dirs[i].stream = make_stream (); + if (setup_stream (otf->table_dirs[i].stream, fp, + otf->table_dirs[i].offset, + otf->table_dirs[i].length, + otf->table_dirs[i].name) < 0) + goto err; } } - stream_close (stream); + free_stream (stream); + fclose (fp); return otf; err: - stream_close (stream); + free_stream (stream); + fclose (fp); otf_close (otf); return NULL; } + void otf_close (OTF *otf) { @@ -1763,4 +1826,53 @@ otf_close (OTF *otf) free (otf->filename); if (otf->table_dirs) free (otf->table_dirs); + if (otf->head) + free_head_table ((OTF_head *) otf->head->table); + if (otf->name) + free_name_table ((OTF_name *) otf->name->table); + if (otf->cmap) + free_cmap_table ((OTF_cmap *) otf->cmap->table); + if (otf->gdef) + free_gdef_table ((OTF_GDEF *) otf->gdef->table); +} + + +void * +otf_get_table (OTF *otf, OTF_Tag tag) +{ + char *errfmt = "OTF Table Read"; + void *errret = NULL; + OTF_TableDirectory *tabledir = NULL; + void *(*reader) (OTF_Stream *stream); + + if (tag == otf_tag ("head")) + tabledir = otf->head, reader = read_head_table; + else if (tag == otf_tag ("name")) + tabledir = otf->name, reader = read_name_table; + else if (tag == otf_tag ("cmap")) + tabledir = otf->cmap, reader = read_cmap_table; + else if (tag == otf_tag ("GDEF")) + tabledir = otf->gdef, reader = read_gdef_table; + else if (tag == otf_tag ("GSUB")) + tabledir = otf->gsub, reader = read_gsub_table; + else if (tag == otf_tag ("GPOS")) + tabledir = otf->gpos, reader = read_gpos_table; + else + OTF_ERROR (OTF_ERROR_TABLE, " (unsupported)"); + + if (! tabledir) + OTF_ERROR (OTF_ERROR_TABLE, " (not found)"); + if (! tabledir->stream) + OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)"); + if (! tabledir->table) + { + tabledir->table = (*reader) (tabledir->stream); + if (! tabledir->table) + { + free_stream (tabledir->stream); + tabledir->stream = NULL; + OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)"); + } + } + return tabledir->table; } diff --git a/src/otf-proc.c b/src/otf-proc.c index c9dee49..8c5a87d 100644 --- a/src/otf-proc.c +++ b/src/otf-proc.c @@ -75,7 +75,7 @@ get_langsys (OTF_ScriptList *script_list, int i, j; for (i = 0; i < script_list->ScriptCount; i++) - if (script_list->ScriptRecord[i].ScriptTag == script_tag) + if (script_list->Script[i].ScriptTag == script_tag) { OTF_Script *script = script_list->Script + i; @@ -272,30 +272,32 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index, } int -otf_gsub (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, +otf_drive_gsub (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, OTF_GlyphString *gstring) { - OTF_GSUB *gsub = otf->gsub; + OTF_GSUB *gsub = (OTF_GSUB *) otf->gsub->table; OTF_LangSys *langsys; int i, j; if (! gsub) + gsub = (OTF_GSUB *) otf_get_table (otf, otf_tag ("GSUB")); + if (! gsub) return -1; - langsys = get_langsys (&gsub->script_list, script_tag, langsys_tag); + langsys = get_langsys (&gsub->ScriptList, script_tag, langsys_tag); if (! langsys) return -1; for (i = 0; i < langsys->FeatureCount; i++) { OTF_Feature *feature - = gsub->feature_list.Feature + langsys->FeatureIndex[i]; + = gsub->FeatureList.Feature + langsys->FeatureIndex[i]; for (j = 0; j < feature->LookupCount; j++) { int gidx = 0; while (gidx < gstring->used) - gidx = lookup_gsub (&gsub->lookup_list, feature->LookupListIndex[j], + gidx = lookup_gsub (&gsub->LookupList, feature->LookupListIndex[j], gstring, gidx); } } @@ -455,30 +457,32 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index, } int -otf_gpos (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, +otf_drive_gpos (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, OTF_GlyphString *gstring) { - OTF_GPOS *gpos = otf->gpos; + OTF_GPOS *gpos = (OTF_GPOS *) otf->gpos->table; OTF_LangSys *langsys; int i, j; if (! gpos) + gpos = (OTF_GPOS *) otf_get_table (otf, otf_tag ("GPOS")); + if (! gpos) return -1; - langsys = get_langsys (&gpos->script_list, script_tag, langsys_tag); + langsys = get_langsys (&gpos->ScriptList, script_tag, langsys_tag); if (! langsys) return -1; for (i = 0; i < langsys->FeatureCount; i++) { OTF_Feature *feature - = gpos->feature_list.Feature + langsys->FeatureIndex[i]; + = gpos->FeatureList.Feature + langsys->FeatureIndex[i]; for (j = 0; j < feature->LookupCount; j++) { int gidx = 0; while (gidx < gstring->used) - gidx = lookup_gpos (&gpos->lookup_list, feature->LookupListIndex[j], + gidx = lookup_gpos (&gpos->LookupList, feature->LookupListIndex[j], gstring, gidx); } } @@ -489,12 +493,14 @@ otf_gpos (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, int -otf_gdef (OTF *otf, OTF_GlyphString *gstring) +otf_drive_gdef (OTF *otf, OTF_GlyphString *gstring) { int i; - OTF_GDEF *gdef = otf->gdef; + OTF_GDEF *gdef = (OTF_GDEF *) otf->gdef->table; if (! gdef) + gdef = (OTF_GDEF *) otf_get_table (otf, otf_tag ("GDEF")); + if (! gdef) return -1; if (gdef->glyph_class_def.offset) @@ -513,9 +519,8 @@ otf_gdef (OTF *otf, OTF_GlyphString *gstring) } int -otf_lookup_cmap (OTF *otf, int c) +lookup_cmap (OTF_cmap *cmap, int c) { - OTF_cmap *cmap = otf->cmap; int i; if (! cmap || ! cmap->Unicode) @@ -547,18 +552,33 @@ otf_lookup_cmap (OTF *otf, int c) } int -otf_cmap (OTF *otf, OTF_GlyphString *gstring) +otf_drive_cmap (OTF *otf, OTF_GlyphString *gstring) { - int unknown = 0; + OTF_cmap *cmap = (OTF_cmap *) otf->cmap->table; int i; + if (! cmap) + cmap = (OTF_cmap *) otf_get_table (otf, otf_tag ("cmap")); + if (! cmap) + return -1; + for (i = 0; i < gstring->used; i++) - { - int glyph_id = otf_lookup_cmap (otf, gstring->glyphs[i].c); + gstring->glyphs[i].glyph_id = lookup_cmap (cmap, gstring->glyphs[i].c); - if (! glyph_id) - unknown++; - gstring->glyphs[i].glyph_id = glyph_id; - } - return unknown; + return 0; +} + +int +otf_drive_table (OTF *otf, OTF_Tag script, OTF_Tag langsys, + OTF_GlyphString *gstring) +{ + if (otf_drive_cmap (otf, gstring) < 0) + return -1; + if (otf_drive_gdef (otf, gstring) < 0) + return -1; + if (otf_drive_gsub (otf, script, langsys, gstring) < 0) + return -1; + if (otf_drive_gpos (otf, script, langsys, gstring) < 0) + return -1; + return 0; } diff --git a/src/otf.h b/src/otf.h index 4e1957d..8d82894 100644 --- a/src/otf.h +++ b/src/otf.h @@ -1,14 +1,95 @@ -/* BASIC */ +/*** + @file otf.h + + @brief This file defines APIs for the OTF library. + + The @e OTF @e library is for reading and processing OpenType font + tables. It can handle the tables of the following names.a + + @li @e head: + + @li @e name: + + @li @e cmap: + + @li @e GDEF: + + @li @e GSUB: + + @li @e GPOS: + +*/ + +#ifndef _OTF_H_ +#define _OTF_H_ + +//// + +/*** + @defgroup Error handling + @brief Handling errors that occur in the OTF library. + */ + +/*** @{ */ + +/*** + @brief Global variable holding an error code. + + The variable otf_error is set to one of OTF_ERROR_XXX when an + error is detected in OTF library. */ +extern int otf_error; + +/*** + @brief Print error message. + + The function otf_perror () prints $PREFIX and an error message to + the standard output according to the value of otf_error. If this + variable is zero, do nothing. */ + +extern void otf_perror (char *prefix); + + +/*** Macros for error codes. */ + +/*** + @brief Memory allocation error. + + When the OTF library fails to allocate memory, the variable + otf_error is set to this value. */ #define OTF_ERROR_MEMORY -1 + +/*** + @brief File read error. + + When the OTF library fails to read a file, the variable otf_error + is set to this value. */ #define OTF_ERROR_FILE -2 + +/*** + @brief OTF table read error. + + When the OTF library detects an invalid data in an OTF table, the + variable otf_error is set to this value. */ #define OTF_ERROR_TABLE -3 + +/*** + @brief CMAP processing error. + + When the OTF library an invalid data in an OTF table, the variable + otf_error is set to this value. */ #define OTF_ERROR_CMAP_PROC -4 #define OTF_ERROR_GDEF_PROC -5 #define OTF_ERROR_GSUB_PROC -6 #define OTF_ERROR_GPOS_PROC -7 -extern int otf_error; +/*** @} */ + +//// + +/*** */ + +/* BASIC */ typedef unsigned OTF_Tag; typedef unsigned OTF_GlyphID; @@ -52,22 +133,6 @@ typedef struct */ -typedef struct OTF_ScriptRecord OTF_ScriptRecord; -typedef struct OTF_Script OTF_Script; - -typedef struct -{ - unsigned ScriptCount; - OTF_ScriptRecord *ScriptRecord; - OTF_Script *Script; -} OTF_ScriptList; - -struct OTF_ScriptRecord -{ - OTF_Tag ScriptTag; - OTF_Offset Script; -}; - typedef struct { OTF_Offset LookupOrder; @@ -82,57 +147,58 @@ typedef struct OTF_Offset LangSys; } OTF_LangSysRecord; -struct OTF_Script +typedef struct { + OTF_Tag ScriptTag; + OTF_Offset offset; OTF_Offset DefaultLangSysOffset; OTF_LangSys DefaultLangSys; unsigned LangSysCount; OTF_LangSysRecord *LangSysRecord; OTF_LangSys *LangSys; -}; - -typedef struct OTF_FeatureRecord OTF_FeatureRecord; -typedef struct OTF_Feature OTF_Feature; +} OTF_Script; typedef struct { - unsigned FeatureCount; - OTF_FeatureRecord *FeatureRecord; - OTF_Feature *Feature; -} OTF_FeatureList; + OTF_Offset offset; + unsigned ScriptCount; + OTF_Script *Script; +} OTF_ScriptList; -struct OTF_FeatureRecord +typedef struct { OTF_Tag FeatureTag; - OTF_Offset Feature; -}; - -struct OTF_Feature -{ + OTF_Offset offset; OTF_Offset FeatureParams; unsigned LookupCount; unsigned *LookupListIndex; -}; - -typedef struct OTF_Lookup OTF_Lookup; +} OTF_Feature; typedef struct { - unsigned LookupCount; - OTF_Offset *LookupOffset; - OTF_Lookup *Lookup; -} OTF_LookupList; + OTF_Offset offset; + unsigned FeatureCount; + OTF_Feature *Feature; +} OTF_FeatureList; typedef struct OTF_LookupSubTable OTF_LookupSubTable; -struct OTF_Lookup +typedef struct { + OTF_Offset offset; unsigned LookupType; unsigned LookupFlag; unsigned SubTableCount; OTF_Offset *SubTableOffset; OTF_LookupSubTable *SubTable; -}; +} OTF_Lookup; + +typedef struct +{ + OTF_Offset offset; + unsigned LookupCount; + OTF_Lookup *Lookup; +} OTF_LookupList; enum OTF_LookupFlagBit { @@ -144,7 +210,12 @@ enum OTF_LookupFlagBit OTF_MarkAttachmentType = 0xFF00 }; -typedef struct OTF_RangeRecord OTF_RangeRecord; +typedef struct +{ + OTF_GlyphID Start; + OTF_GlyphID End; + unsigned StartCoverageIndex; +} OTF_RangeRecord; typedef struct { @@ -157,14 +228,12 @@ typedef struct } table; } OTF_Coverage; -struct OTF_RangeRecord +typedef struct { OTF_GlyphID Start; OTF_GlyphID End; - unsigned StartCoverageIndex; -}; - -typedef struct OTF_ClassRangeRecord OTF_ClassRangeRecord; + unsigned Class; +} OTF_ClassRangeRecord; typedef struct { @@ -183,13 +252,6 @@ typedef struct } f; } OTF_ClassDef; -struct OTF_ClassRangeRecord -{ - OTF_GlyphID Start; - OTF_GlyphID End; - unsigned Class; -}; - typedef struct { OTF_Offset offset; @@ -666,29 +728,20 @@ struct OTF_LookupSubTable typedef struct { OTF_Fixed Version; - OTF_Offset ScriptList; - OTF_Offset FeatureList; - OTF_Offset LookupList; -} OTF_GSUBHeader; - -typedef struct -{ - OTF_GSUBHeader header; - OTF_ScriptList script_list; - OTF_FeatureList feature_list; - OTF_LookupList lookup_list; + OTF_ScriptList ScriptList; + OTF_FeatureList FeatureList; + OTF_LookupList LookupList; } OTF_GSUB; -typedef OTF_GSUBHeader OTF_GPOSHeader; /* GPOS */ typedef struct { - OTF_GPOSHeader header; - OTF_ScriptList script_list; - OTF_FeatureList feature_list; - OTF_LookupList lookup_list; + OTF_Fixed Version; + OTF_ScriptList ScriptList; + OTF_FeatureList FeatureList; + OTF_LookupList LookupList; } OTF_GPOS; @@ -742,7 +795,7 @@ typedef struct typedef struct { OTF_Offset offset; - unsigned CaretValueFormat; /* 1, 2, 3 */ + unsigned CaretValueFormat; /* 1, 2, or 3 */ union { union { int Coordinate; @@ -901,7 +954,7 @@ typedef struct int offset; } OTF_NameRecord; -#define OTF_max_nameID 20 +#define OTF_max_nameID 23 typedef struct { @@ -925,10 +978,23 @@ typedef struct typedef struct { + FILE *fp; + char *name; + long pos; + long bufsize; + long allocated; + unsigned char *buf; +} OTF_Stream; + +typedef struct +{ OTF_Tag tag; + char name[5]; unsigned checkSum; unsigned offset; unsigned length; + void *table; + OTF_Stream *stream; } OTF_TableDirectory; typedef struct @@ -936,15 +1002,15 @@ typedef struct char *filename; OTF_OffsetTable offset_table; OTF_TableDirectory *table_dirs; - OTF_head *head; - OTF_name *name; - OTF_cmap *cmap; - OTF_GDEF *gdef; - OTF_GSUB *gsub; - OTF_GPOS *gpos; + OTF_TableDirectory *head; + OTF_TableDirectory *name; + OTF_TableDirectory *cmap; + OTF_TableDirectory *gdef; + OTF_TableDirectory *gsub; + OTF_TableDirectory *gpos; /* The following tables are not yet supported. */ - // OTF_BASE *base; - // OTF_JSTF *jstf; + // OTF_TableDirectory *base; + // OTF_TableDirectory *jstf; } OTF; typedef struct @@ -1005,16 +1071,35 @@ typedef struct } OTF_GlyphString; +/*** + @brief Convert a string to OTF tag. + + The function otf_tag () converts the string $STR to OTF tag, and + return that tag. If $STR is NULL, return 0. + + If $STR is not NULL, the length should be at least 4, and the + first 4 characters are took into an account. */ + extern OTF_Tag otf_tag (char *str); +/*** + @brief Open an OpenType font file. + + The function otf_open () reads the OpenType font file whose name + is $NAME, and return a pointer to the structure of type OTF. */ + extern OTF *otf_open (char *name); extern void otf_close (OTF *otf); +extern void *otf_get_table (OTF *otf, OTF_Tag tag); + +extern int otf_drive_cmap (OTF *otf, OTF_GlyphString *gstring); +extern int otf_drive_gdef (OTF *otf, OTF_GlyphString *gstring); +extern int otf_drive_gsub (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, + OTF_GlyphString *gstring); +extern int otf_drive_gpos (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, + OTF_GlyphString *gstring); +extern int otf_drive_table (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, + OTF_GlyphString *gstring); -extern int otf_cmap (OTF *otf, OTF_GlyphString *gstring); -extern int otf_gdef (OTF *otf, OTF_GlyphString *gstring); -extern int otf_gsub (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, - OTF_GlyphString *gstring); -extern int otf_gpos (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag, - OTF_GlyphString *gstring); -extern int otf_lookup_cmap (OTF *otf, int c); +#endif /* not _OTF_H_ */ -- 1.7.10.4