Include FT_TRUETYPE_TABLES_H.
authorhanda <handa>
Fri, 14 Jul 2006 12:49:49 +0000 (12:49 +0000)
committerhanda <handa>
Fri, 14 Jul 2006 12:49:49 +0000 (12:49 +0000)
(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

index 90ca408..cbadb2c 100644 (file)
@@ -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