From 61d2fe06e82a3f29f7c140c63615a00258616b2b Mon Sep 17 00:00:00 2001 From: handa Date: Fri, 14 Jul 2006 12:49:49 +0000 Subject: [PATCH] Include FT_TRUETYPE_TABLES_H. (make_stream): New arg name. Caller changed. (setup_stream): Delete arg name. (make_stream_from_ft_face): New function. (read_cmap_table): Fix typo (`i'->`j'). (read_header_part): New arg face. Caller changed. (OTF_open_ft_face): New function. --- src/otfopen.c | 200 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 139 insertions(+), 61 deletions(-) diff --git a/src/otfopen.c b/src/otfopen.c index 90ca408..cbadb2c 100644 --- a/src/otfopen.c +++ b/src/otfopen.c @@ -29,6 +29,8 @@ write to the Free Software Foundation, Inc., 59 Temple Place, Suite #include "otf.h" #include "otferror.h" +#include FT_TRUETYPE_TABLES_H + /*** Table of contents (almost parallel to otf.h): @@ -80,7 +82,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place, Suite typedef struct { - FILE *fp; char *name; long pos; long bufsize; @@ -91,7 +92,7 @@ typedef struct typedef long OTF_StreamState; OTF_Stream * -make_stream () +make_stream (char *name) { OTF_Stream *stream; char *errfmt = "stream creation%s"; @@ -100,17 +101,16 @@ make_stream () stream = calloc (1, sizeof (OTF_Stream)); if (! stream) OTF_ERROR (OTF_ERROR_MEMORY, ""); + stream->name = name; return stream; } int -setup_stream (OTF_Stream *stream, FILE *fp, long offset, int nbytes, - char *name) +setup_stream (OTF_Stream *stream, FILE *fp, long offset, int nbytes) { char *errfmt = "stream setup for %s"; int errret = -1; - stream->name = name; stream->pos = 0; if (stream->allocated < nbytes) { @@ -131,6 +131,35 @@ setup_stream (OTF_Stream *stream, FILE *fp, long offset, int nbytes, return 0; } +OTF_Stream * +make_stream_from_ft_face (FT_Face face, char *name) +{ + char *errfmt = "FT_Face stream creation for %s"; + void *errret = NULL; + FT_ULong nbytes = 0; + unsigned char *buf; + OTF_Stream *stream; + FT_ULong tag = FT_MAKE_TAG (name[0], name[1], name[2], name[3]); + + if (FT_Load_Sfnt_Table (face, tag, 0, NULL, &nbytes)) + return NULL; + buf = malloc (nbytes); + if (! buf) + OTF_ERROR (OTF_ERROR_MEMORY, name); + if (FT_Load_Sfnt_Table (face, tag, 0, buf, &nbytes)) + { + free (buf); + OTF_ERROR (OTF_ERROR_FT_FACE, name); + } + stream = make_stream (name); + if (! stream) + return NULL; + stream->pos = 0; + stream->buf = buf; + stream->allocated = nbytes; + stream->bufsize = nbytes; + return stream; +} void free_stream (OTF_Stream *stream) @@ -669,9 +698,9 @@ read_cmap_table (OTF *otf, OTF_TableInfo *table, enum OTF_ReaderFlag flag) OTF_MALLOC (sub12->Groups, sub12->nGroups, " (Groups)"); for (j = 0; j < sub12->nGroups; j++) { - READ_ULONG (stream, sub12->Groups[i].startCharCode); - READ_ULONG (stream, sub12->Groups[i].endCharCode); - READ_ULONG (stream, sub12->Groups[i].startGlyphID); + READ_ULONG (stream, sub12->Groups[j].startCharCode); + READ_ULONG (stream, sub12->Groups[j].endCharCode); + READ_ULONG (stream, sub12->Groups[j].startGlyphID); } } break; @@ -2608,12 +2637,10 @@ read_table_directory (OTF_Stream *stream, OTF_TableDirectory *table) } static int -read_header_part (OTF *otf, FILE *fp) +read_header_part (OTF *otf, FILE *fp, FT_Face face) { char *errfmt = "otf header%s"; int errret = -1; - OTF_Tag head_tag, name_tag, cmap_tag, gdef_tag, gsub_tag, gpos_tag; - OTF_Stream *stream; int i; OTF_InternalData *internal_data = (OTF_InternalData *) otf->internal_data; @@ -2630,64 +2657,84 @@ read_header_part (OTF *otf, FILE *fp) internal_data->table_info[OTF_TABLE_TYPE_GPOS].address = (void *) &otf->gpos; internal_data->table_info[OTF_TABLE_TYPE_GPOS].reader = read_gpos_table; - head_tag = OTF_tag ("head"); - 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"); - - stream = make_stream (); - if (! stream) - return -1; - - internal_data->header_stream = stream; - - /* Size of Offset Table is 12 bytes. */ - if (setup_stream (stream, fp, 0, 12, "Offset Table") < 0) - return -1; - if (read_offset_table (otf, stream, &otf->offset_table) < 0) - return -1; + if (fp) + { + OTF_Tag head_tag = OTF_tag ("head"); + OTF_Tag name_tag = OTF_tag ("name"); + OTF_Tag cmap_tag = OTF_tag ("cmap"); + OTF_Tag gdef_tag = OTF_tag ("GDEF"); + OTF_Tag gsub_tag = OTF_tag ("GSUB"); + OTF_Tag gpos_tag = OTF_tag ("GPOS"); + OTF_Stream *stream = make_stream ("Offset Table"); - /* Size of each Table Directory is 16 bytes. */ - if (setup_stream (stream, fp, 12, 16 * otf->offset_table.numTables, - "Table Directory") < 0) - return -1; + if (! stream) + return -1; + internal_data->header_stream = stream; - OTF_CALLOC (otf->table_dirs, 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; + /* Size of Offset Table is 12 bytes. */ + if (setup_stream (stream, fp, 0, 12) < 0) + return -1; + if (read_offset_table (otf, stream, &otf->offset_table) < 0) + return -1; - if (! tag) + /* Size of each Table Directory is 16 bytes. */ + if (setup_stream (stream, fp, 12, 16 * otf->offset_table.numTables) < 0) return -1; - if (tag == head_tag) - table_info = internal_data->table_info + OTF_TABLE_TYPE_HEAD; - else if (tag == name_tag) - table_info = internal_data->table_info + OTF_TABLE_TYPE_NAME; - else if (tag == cmap_tag) - table_info = internal_data->table_info + OTF_TABLE_TYPE_CMAP; - else if (tag == gdef_tag) - table_info = internal_data->table_info + OTF_TABLE_TYPE_GDEF; - else if (tag == gsub_tag) - table_info = internal_data->table_info + OTF_TABLE_TYPE_GSUB; - else if (tag == gpos_tag) - table_info = internal_data->table_info + OTF_TABLE_TYPE_GPOS; - - if (table_info) + + OTF_CALLOC (otf->table_dirs, otf->offset_table.numTables, + " (OffsetTable)"); + for (i = 0; i < otf->offset_table.numTables; i++) { - 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) + OTF_Tag tag = read_table_directory (stream, otf->table_dirs + i); + OTF_TableInfo *table_info = NULL; + + if (! tag) return -1; + if (tag == head_tag) + table_info = internal_data->table_info + OTF_TABLE_TYPE_HEAD; + else if (tag == name_tag) + table_info = internal_data->table_info + OTF_TABLE_TYPE_NAME; + else if (tag == cmap_tag) + table_info = internal_data->table_info + OTF_TABLE_TYPE_CMAP; + else if (tag == gdef_tag) + table_info = internal_data->table_info + OTF_TABLE_TYPE_GDEF; + else if (tag == gsub_tag) + table_info = internal_data->table_info + OTF_TABLE_TYPE_GSUB; + else if (tag == gpos_tag) + table_info = internal_data->table_info + OTF_TABLE_TYPE_GPOS; + + if (table_info) + { + table_info->stream = make_stream (otf->table_dirs[i].name); + if (setup_stream (table_info->stream, fp, + otf->table_dirs[i].offset, + otf->table_dirs[i].length) < 0) + return -1; + } } + + internal_data->header_stream = NULL; + free_stream (stream); + } + else + { + OTF_Stream *stream; + + internal_data->header_stream = NULL; + if ((stream = make_stream_from_ft_face (face, "head"))) + internal_data->table_info[OTF_TABLE_TYPE_HEAD].stream = stream; + if ((stream = make_stream_from_ft_face (face, "name"))) + internal_data->table_info[OTF_TABLE_TYPE_NAME].stream = stream; + if ((stream = make_stream_from_ft_face (face, "cmap"))) + internal_data->table_info[OTF_TABLE_TYPE_CMAP].stream = stream; + if ((stream = make_stream_from_ft_face (face, "GDEF"))) + internal_data->table_info[OTF_TABLE_TYPE_GDEF].stream = stream; + if ((stream = make_stream_from_ft_face (face, "GSUB"))) + internal_data->table_info[OTF_TABLE_TYPE_GSUB].stream = stream; + if ((stream = make_stream_from_ft_face (face, "GPOS"))) + internal_data->table_info[OTF_TABLE_TYPE_GPOS].stream = stream; } - internal_data->header_stream = NULL; - free_stream (stream); return 0; } @@ -2780,7 +2827,7 @@ OTF_open (char *otf_name) otf->internal_data->memory_record except for what allocated by the functions allocate_memory_record and make_stream. */ - if (read_header_part (otf, fp) < 0) + if (read_header_part (otf, fp, NULL) < 0) { OTF_close (otf); fclose (fp); @@ -2791,6 +2838,37 @@ OTF_open (char *otf_name) return otf; } +OTF * +OTF_open_ft_face (FT_Face face) +{ + char *errfmt = "opening otf from Freetype (%s)"; + void *errret = NULL; + OTF *otf; + OTF_InternalData *internal_data; + + if (! FT_IS_SFNT (face)) + OTF_ERROR (OTF_ERROR_FILE, (char *) face->family_name); + otf = calloc (1, sizeof (OTF)); + if (! otf) + OTF_ERROR (OTF_ERROR_MEMORY, "body allocation"); + otf->filename = NULL; + + internal_data = calloc (1, sizeof (OTF_InternalData)); + if (! internal_data) + OTF_ERROR (OTF_ERROR_MEMORY, " (InternalData"); + otf->internal_data = internal_data; + if (! allocate_memory_record (otf)) + OTF_ERROR (OTF_ERROR_MEMORY, " (InternalData)"); + + if (read_header_part (otf, NULL, face) < 0) + { + OTF_close (otf); + return NULL; + } + + return otf; +} + /*** (2-2) OTF_close() */ void -- 1.7.10.4