\f
+enum OTF_TableType
+ {
+ OTF_TABLE_TYPE_HEAD,
+ OTF_TABLE_TYPE_NAME,
+ OTF_TABLE_TYPE_CMAP,
+ OTF_TABLE_TYPE_GDEF,
+ OTF_TABLE_TYPE_GSUB,
+ OTF_TABLE_TYPE_GPOS,
+ OTF_TABLE_TYPE_MAX
+ };
+
#define OTF_MEMORY_RECORD_SIZE 1024
struct OTF_MemoryRecord
typedef struct OTF_MemoryRecord OTF_MemoryRecord;
-struct OTF_InternalData {
- int head_index;
- int name_index;
- int cmap_index;
- int gdef_index;
- int gsub_index;
- int gpos_index;
- OTF_Stream *work_stream;
- OTF_Stream **streams;
+typedef struct
+{
+ /* 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);
+ /* Stream given to <reader>. */
+ OTF_Stream *stream;
+} OTF_TableInfo;
+
+struct OTF_InternalData
+{
+ /* Information about each OTF table. */
+ OTF_TableInfo table_info[OTF_TABLE_TYPE_MAX];
+
+ /* Stream used to read the header part of OTF. */
+ OTF_Stream *header_stream;
+
+ /* Records of allocated memories. */
OTF_MemoryRecord *memory_record;
};
}
static int
-read_otf_header (OTF *otf, FILE *fp)
+read_header_part (OTF *otf, FILE *fp)
{
char *errfmt = "otf header%s";
int errret = -1;
OTF_CALLOC (internal_data, 1, " (InternalData");
otf->internal_data = internal_data;
+ internal_data->table_info[OTF_TABLE_TYPE_HEAD].address = &otf->head;
+ internal_data->table_info[OTF_TABLE_TYPE_HEAD].reader = read_head_table;
+ internal_data->table_info[OTF_TABLE_TYPE_NAME].address = &otf->name;
+ internal_data->table_info[OTF_TABLE_TYPE_NAME].reader = read_name_table;
+ internal_data->table_info[OTF_TABLE_TYPE_CMAP].address = &otf->cmap;
+ internal_data->table_info[OTF_TABLE_TYPE_CMAP].reader = read_cmap_table;
+ internal_data->table_info[OTF_TABLE_TYPE_GDEF].address = &otf->gdef;
+ internal_data->table_info[OTF_TABLE_TYPE_GDEF].reader = read_gdef_table;
+ internal_data->table_info[OTF_TABLE_TYPE_GSUB].address = &otf->gsub;
+ internal_data->table_info[OTF_TABLE_TYPE_GSUB].reader = read_gsub_table;
+ internal_data->table_info[OTF_TABLE_TYPE_GPOS].address = &otf->gpos;
+ internal_data->table_info[OTF_TABLE_TYPE_GPOS].reader = read_gpos_table;
if (allocate_memory_record (otf) < 0)
OTF_ERROR (OTF_ERROR_MEMORY, " (InternalData)");
if (! stream)
return -1;
- internal_data->work_stream = stream;
+ internal_data->header_stream = stream;
/* Size of Offset Table is 12 bytes. */
if (setup_stream (stream, fp, 0, 12, "Offset Table") < 0)
return -1;
OTF_CALLOC (otf->table_dirs, otf->offset_table.numTables, " (OffsetTable)");
- OTF_CALLOC (internal_data->streams, otf->offset_table.numTables,
- " (OffsetTable)");
for (i = 0; i < otf->offset_table.numTables; i++)
{
OTF_Tag tag = read_table_directory (stream, otf->table_dirs + i);
+ OTF_TableInfo *table_info = NULL;
if (! tag)
return -1;
if (tag == head_tag)
- otf->head = otf->table_dirs + i;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_HEAD;
else if (tag == name_tag)
- otf->name = otf->table_dirs + i;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_NAME;
else if (tag == cmap_tag)
- otf->cmap = otf->table_dirs + i;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_CMAP;
else if (tag == gdef_tag)
- otf->gdef = otf->table_dirs + i;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_GDEF;
else if (tag == gsub_tag)
- otf->gsub = otf->table_dirs + i;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_GSUB;
else if (tag == gpos_tag)
- otf->gpos = otf->table_dirs + i;
- else
- tag = 0;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_GPOS;
- if (tag)
+ if (table_info)
{
- internal_data->streams[i] = make_stream ();
- if (setup_stream (internal_data->streams[i], fp,
+ table_info->stream = make_stream ();
+ if (setup_stream (table_info->stream, fp,
otf->table_dirs[i].offset,
otf->table_dirs[i].length,
otf->table_dirs[i].name) < 0)
}
}
- internal_data->work_stream = NULL;
+ internal_data->header_stream = NULL;
free_stream (stream);
return 0;
}
OTF_ERROR (OTF_ERROR_MEMORY, "filename allocation");
}
- if (read_otf_header (otf, fp) < 0)
+ if (read_header_part (otf, fp) < 0)
{
otf_close (otf);
fclose (fp);
{
OTF_MemoryRecord *memrec = internal_data->memory_record;
- if (internal_data->work_stream)
- free_stream (internal_data->work_stream);
+ if (internal_data->header_stream)
+ free_stream (internal_data->header_stream);
if (internal_data->streams)
for (i = 0; i < otf->offset_table.numTables; i++)
}
-void *
+int
otf_get_table (OTF *otf, OTF_Tag tag)
{
char *errfmt = "OTF Table Read";
- void *errret = NULL;
+ int errret = -1;
OTF_InternalData *internal_data = otf->internal_data;
- OTF_TableDirectory *tabledir = NULL;
- void *(*reader) (OTF *otf, OTF_Stream *stream);
+ OTF_TableInfo *table_info;
if (tag == otf_tag ("head"))
- tabledir = otf->head, reader = read_head_table;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_HEAD;
else if (tag == otf_tag ("name"))
- tabledir = otf->name, reader = read_name_table;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_NAME;
else if (tag == otf_tag ("cmap"))
- tabledir = otf->cmap, reader = read_cmap_table;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_CMAP;
else if (tag == otf_tag ("GDEF"))
- tabledir = otf->gdef, reader = read_gdef_table;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_GDEF;
else if (tag == otf_tag ("GSUB"))
- tabledir = otf->gsub, reader = read_gsub_table;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_GSUB;
else if (tag == otf_tag ("GPOS"))
- tabledir = otf->gpos, reader = read_gpos_table;
+ table_info = internal_data->table_info + OTF_TABLE_TYPE_GPOS;
else
OTF_ERROR (OTF_ERROR_TABLE, " (unsupported)");
- if (! tabledir)
+ if (*table_info->address)
+ return 0;
+ if (! table_info->stream)
OTF_ERROR (OTF_ERROR_TABLE, " (not found)");
- if (! tabledir->stream)
+ if (! table_info->reader)
OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)");
- if (! tabledir->table)
+
+ *table_info->address = (*table_info->reader) (otf, table_info->stream);
+ free_stream (table_info->stream);
+ table_info->stream = NULL;
+ if (! *table_info->address)
{
- tabledir->table = (*reader) (otf, tabledir->stream);
- if (! tabledir->table)
- {
- free_stream (tabledir->stream);
- tabledir->stream = NULL;
- OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)");
- }
+ table_info->reader = NULL;
+ OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)");
}
- return tabledir->table;
+
+ return 0;
}