[cairo-commit] 3 commits - src/cairo-atsui-font.c src/cairo-font-subset.c src/cairo-ft-font.c src/cairoint.h src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-svg-surface.c src/cairo-truetype-subset.c src/cairo-win32-font.c src/Makefile.am

Kristian Høgsberg krh at kemper.freedesktop.org
Wed Aug 2 16:31:32 PDT 2006


 src/Makefile.am             |    6 
 src/cairo-atsui-font.c      |    1 
 src/cairo-font-subset.c     |  860 ---------------------------------------
 src/cairo-ft-font.c         |   26 +
 src/cairo-pdf-surface.c     |    5 
 src/cairo-ps-surface.c      |    6 
 src/cairo-svg-surface.c     |    1 
 src/cairo-truetype-subset.c |  967 ++++++++++++++++++++++++++++++++++++++++++++
 src/cairo-win32-font.c      |   28 +
 src/cairoint.h              |    6 
 10 files changed, 1041 insertions(+), 865 deletions(-)

New commits:
diff-tree 30f004d55ad7c426e979964a49e7a8c8d8db31f3 (from f664a3b7a087272a27eb893b7ee5a1775eb92c4d)
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Aug 2 19:29:17 2006 -0400

    Rename truetype subset function to _cairo_truetype_*.
    
    Used to be _cairo_pdf_ft_*, a left over from when this code was
    specific to the PDF backend.

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index b024684..fe499ce 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -39,13 +39,13 @@
 #include "cairo-scaled-font-subsets-private.h"
 
 
-typedef struct ft_subset_glyph ft_subset_glyph_t;
-struct ft_subset_glyph {
+typedef struct subset_glyph subset_glyph_t;
+struct subset_glyph {
     int parent_index;
     unsigned long location;
 };
 
-typedef struct _cairo_ft_font {
+typedef struct _cairo_truetype_font {
 
     cairo_scaled_font_subset_t *scaled_font_subset;
 
@@ -57,7 +57,7 @@ typedef struct _cairo_ft_font {
 	long ascent, descent;
     } base;
 
-    ft_subset_glyph_t *glyphs;
+    subset_glyph_t *glyphs;
     const cairo_scaled_font_backend_t *backend;
     int num_glyphs_in_face;
     int checksum_index;
@@ -68,7 +68,7 @@ typedef struct _cairo_ft_font {
     int *parent_to_subset;
     cairo_status_t status;
 
-} cairo_pdf_ft_font_t;
+} cairo_truetype_font_t;
 
 
 
@@ -157,7 +157,7 @@ typedef struct tt_name {
 } tt_name_t;
 
 static int
-cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);
+cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
 
 #define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
 
@@ -200,11 +200,11 @@ be32_to_cpu(unsigned long v)
 #endif
 
 static cairo_status_t
-_cairo_pdf_ft_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
-			   cairo_pdf_ft_font_t        **font_return)
+_cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
+			     cairo_truetype_font_t      **font_return)
 {
     cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
-    cairo_pdf_ft_font_t *font;
+    cairo_truetype_font_t *font;
     const cairo_scaled_font_backend_t *backend;
     tt_head_t head;
     tt_hhea_t hhea;
@@ -213,7 +213,7 @@ _cairo_pdf_ft_font_create (cairo_scaled_
     tt_name_record_t *record;
     unsigned long size;
     int i, j;
-    
+
     backend = scaled_font_subset->scaled_font->backend;
     if (!backend->load_truetype_table)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -255,20 +255,20 @@ _cairo_pdf_ft_font_create (cairo_scaled_
      *   return CAIRO_INT_STATUS_UNSUPPORTED;
      */
 
-    font = malloc (sizeof (cairo_pdf_ft_font_t));
+    font = malloc (sizeof (cairo_truetype_font_t));
     if (font == NULL)
 	goto fail0;
 
     font->backend = backend;
     font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
     font->scaled_font_subset = scaled_font_subset;
-    
+
     font->last_offset = 0;
     font->last_boundary = 0;
     _cairo_array_init (&font->output, sizeof (char));
     if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
 	goto fail1;
-    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (ft_subset_glyph_t));
+    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
     if (font->glyphs == NULL)
 	goto fail2;
 
@@ -284,7 +284,6 @@ _cairo_pdf_ft_font_create (cairo_scaled_
     font->base.ascent = be16_to_cpu (hhea.ascender);
     font->base.descent = be16_to_cpu (hhea.descender);
 
-
     /* Extract the font name from the name table. At present this
      * just looks for the Mac platform/Roman encoded font name. It
      * should be extended to use any suitable font name in the
@@ -356,7 +355,7 @@ _cairo_pdf_ft_font_create (cairo_scaled_
 }
 
 static void
-cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font)
+cairo_truetype_font_destroy (cairo_truetype_font_t *font)
 {
     free (font->base.base_font);
     free (font->parent_to_subset);
@@ -367,9 +366,9 @@ cairo_pdf_ft_font_destroy (cairo_pdf_ft_
 }
 
 static cairo_status_t
-cairo_pdf_ft_font_allocate_write_buffer (cairo_pdf_ft_font_t	 *font,
-					 size_t			  length,
-					 unsigned char		**buffer)
+cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t  *font,
+					   size_t		   length,
+					   unsigned char	 **buffer)
 {
     cairo_status_t status;
 
@@ -381,8 +380,9 @@ cairo_pdf_ft_font_allocate_write_buffer 
 }
 
 static cairo_status_t
-cairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,
-			 const void *data, size_t length)
+cairo_truetype_font_write (cairo_truetype_font_t *font,
+			   const void            *data,
+			   size_t                 length)
 {
     cairo_status_t status;
 
@@ -394,26 +394,27 @@ cairo_pdf_ft_font_write (cairo_pdf_ft_fo
 }
 
 static void
-cairo_pdf_ft_font_write_be16 (cairo_pdf_ft_font_t *font,
-			      unsigned short value)
+cairo_truetype_font_write_be16 (cairo_truetype_font_t *font,
+				unsigned short         value)
 {
     unsigned short be16_value;
 
     be16_value = cpu_to_be16 (value);
-    cairo_pdf_ft_font_write (font, &be16_value, sizeof be16_value);
+    cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
 }
 
 static void
-cairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value)
+cairo_truetype_font_write_be32 (cairo_truetype_font_t *font,
+				unsigned long          value)
 {
     unsigned long be32_value;
 
     be32_value = cpu_to_be32 (value);
-    cairo_pdf_ft_font_write (font, &be32_value, sizeof be32_value);
+    cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
 }
 
 static unsigned long
-cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
+cairo_truetype_font_align_output (cairo_truetype_font_t *font)
 {
     int length, aligned, pad;
     unsigned char *ignored;
@@ -423,15 +424,17 @@ cairo_pdf_ft_font_align_output (cairo_pd
     pad = aligned - length;
 
     if (pad)
-	cairo_pdf_ft_font_allocate_write_buffer (font, pad, &ignored);
+	cairo_truetype_font_allocate_write_buffer (font, pad, &ignored);
 
     return aligned;
 }
 
 static void
-cairo_pdf_ft_font_check_boundary (cairo_pdf_ft_font_t *font, unsigned long boundary)
+cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
+				    unsigned long          boundary)
 {
-    if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) {
+    if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
+    {
         _cairo_array_append(&font->string_offsets, &font->last_boundary);
         font->last_offset = font->last_boundary;
     }
@@ -439,33 +442,34 @@ cairo_pdf_ft_font_check_boundary (cairo_
 }
 
 static int
-cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag)
+cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
+				      unsigned long          tag)
 {
     int i;
 
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 1);
+    cairo_truetype_font_write_be16 (font, 0);
+    cairo_truetype_font_write_be16 (font, 1);
 
-    cairo_pdf_ft_font_write_be16 (font, 1);
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be32 (font, 12);
+    cairo_truetype_font_write_be16 (font, 1);
+    cairo_truetype_font_write_be16 (font, 0);
+    cairo_truetype_font_write_be32 (font, 12);
 
     /* Output a format 6 encoding table. */
 
-    cairo_pdf_ft_font_write_be16 (font, 6);
-    cairo_pdf_ft_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 1); /* First glyph */
-    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs - 1);
+    cairo_truetype_font_write_be16 (font, 6);
+    cairo_truetype_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
+    cairo_truetype_font_write_be16 (font, 0);
+    cairo_truetype_font_write_be16 (font, 1); /* First glyph */
+    cairo_truetype_font_write_be16 (font, font->base.num_glyphs - 1);
     for (i = 1; i < font->base.num_glyphs; i++)
-	cairo_pdf_ft_font_write_be16 (font, i);
+	cairo_truetype_font_write_be16 (font, i);
 
     return font->status;
 }
 
 static int
-cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,
-				       unsigned long tag)
+cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
+					 unsigned long          tag)
 {
     cairo_status_t status;
     unsigned char *buffer;
@@ -474,7 +478,7 @@ cairo_pdf_ft_font_write_generic_table (c
     size = 0;
     font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
                                         tag, 0, NULL, &size);
-    status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
     /* XXX: Need to check status here. */
     font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                         tag, 0, buffer, &size);
@@ -496,15 +500,15 @@ struct glyph_data {
 };
 
 /* composite_glyph_t flags */
-#define ARG_1_AND_2_ARE_WORDS     0x0001
-#define WE_HAVE_A_SCALE           0x0008
-#define MORE_COMPONENTS           0x0020
-#define WE_HAVE_AN_X_AND_Y_SCALE  0x0040
-#define WE_HAVE_A_TWO_BY_TWO      0x0080
+#define TT_ARG_1_AND_2_ARE_WORDS     0x0001
+#define TT_WE_HAVE_A_SCALE           0x0008
+#define TT_MORE_COMPONENTS           0x0020
+#define TT_WE_HAVE_AN_X_AND_Y_SCALE  0x0040
+#define TT_WE_HAVE_A_TWO_BY_TWO      0x0080
 
 static void
-cairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font,
-					 unsigned char *buffer)
+cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
+					   unsigned char         *buffer)
 {
     glyph_data_t *glyph_data;
     composite_glyph_t *composite_glyph;
@@ -520,25 +524,25 @@ cairo_pdf_ft_font_remap_composite_glyph 
     composite_glyph = &glyph_data->glyph;
     do {
         flags = be16_to_cpu (composite_glyph->flags);
-        has_more_components = flags & MORE_COMPONENTS;
-        index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
+        has_more_components = flags & TT_MORE_COMPONENTS;
+        index = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
         composite_glyph->index = cpu_to_be16 (index);
         num_args = 1;
-        if (flags & ARG_1_AND_2_ARE_WORDS)
+        if (flags & TT_ARG_1_AND_2_ARE_WORDS)
             num_args += 1;
-        if (flags & WE_HAVE_A_SCALE)
+        if (flags & TT_WE_HAVE_A_SCALE)
             num_args += 1;
-        else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
+        else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
             num_args += 2;
-        else if (flags & WE_HAVE_A_TWO_BY_TWO)
+        else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
             num_args += 3;
         composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);
     } while (has_more_components);
 }
 
 static int
-cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
+cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
+				      unsigned long          tag)
 {
     cairo_status_t status;
     unsigned long start_offset, index, size, next;
@@ -583,22 +587,22 @@ cairo_pdf_ft_font_write_glyf_table (cair
 
 	size = end - begin;
 
-        next = cairo_pdf_ft_font_align_output (font);
-        cairo_pdf_ft_font_check_boundary (font, next);
+        next = cairo_truetype_font_align_output (font);
+        cairo_truetype_font_check_boundary (font, next);
         font->glyphs[i].location = next - start_offset;
 
-	status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+	status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
 	if (status)
 	    break;
         if (size != 0) {
             font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                 TT_TAG_glyf, begin, buffer, &size);
-            cairo_pdf_ft_font_remap_composite_glyph (font, buffer);
+            cairo_truetype_font_remap_composite_glyph (font, buffer);
         }
     }
 
     font->glyphs[i].location =
-	cairo_pdf_ft_font_align_output (font) - start_offset;
+	cairo_truetype_font_align_output (font) - start_offset;
 
     free (u.bytes);
 
@@ -606,8 +610,8 @@ cairo_pdf_ft_font_write_glyf_table (cair
 }
 
 static int
-cairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,
-                                      unsigned long tag)
+cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
+                                      unsigned long          tag)
 {
     unsigned char *buffer;
     unsigned long size;
@@ -616,19 +620,19 @@ cairo_pdf_ft_font_write_head_table (cair
     font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                         tag, 0, NULL, &size);
     font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
-    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+    font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
     font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
                                         tag, 0, buffer, &size);
     return font->status;
 }
 
-static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag)
+static int cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag)
 {
     tt_hhea_t *hhea;
     unsigned long size;
 
     size = sizeof (tt_hhea_t);
-    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
+    font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
     font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                         tag, 0, (unsigned char *) hhea, &size);
     hhea->num_hmetrics = cpu_to_be16 (font->base.num_glyphs);
@@ -636,8 +640,8 @@ static int cairo_pdf_ft_font_write_hhea_
 }
 
 static int
-cairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
+cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
+				      unsigned long          tag)
 {
     cairo_status_t status;
     unsigned long size;
@@ -656,7 +660,7 @@ cairo_pdf_ft_font_write_hmtx_table (cair
     for (i = 0; i < font->base.num_glyphs; i++) {
         long_entry_size = 2 * sizeof (short);
         short_entry_size = sizeof (short);
-        status = cairo_pdf_ft_font_allocate_write_buffer (font, long_entry_size,
+        status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size,
 							  (unsigned char **) &p);
         if (font->glyphs[i].parent_index < num_hmetrics) {
             font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
@@ -684,8 +688,8 @@ cairo_pdf_ft_font_write_hmtx_table (cair
 }
 
 static int
-cairo_pdf_ft_font_write_loca_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
+cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
+				      unsigned long          tag)
 {
     int i;
     tt_head_t header;
@@ -695,27 +699,27 @@ cairo_pdf_ft_font_write_loca_table (cair
     font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                         TT_TAG_head, 0, (unsigned char*) &header, &size);
 
-    if (be16_to_cpu (header.index_to_loc_format) == 0) {
+    if (be16_to_cpu (header.index_to_loc_format) == 0)
+    {
 	for (i = 0; i < font->base.num_glyphs + 1; i++)
-	    cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);
-    }
-    else {
+	    cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2);
+    } else {
 	for (i = 0; i < font->base.num_glyphs + 1; i++)
-	    cairo_pdf_ft_font_write_be32 (font, font->glyphs[i].location);
+	    cairo_truetype_font_write_be32 (font, font->glyphs[i].location);
     }
 
     return font->status;
 }
 
 static int
-cairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
+cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
+				      unsigned long          tag)
 {
     tt_maxp_t *maxp;
     unsigned long size;
 
     size = sizeof (tt_maxp_t);
-    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
+    font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
     font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                         tag, 0, (unsigned char *) maxp, &size);
     maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
@@ -725,7 +729,7 @@ cairo_pdf_ft_font_write_maxp_table (cair
 typedef struct table table_t;
 struct table {
     unsigned long tag;
-    int (*write) (cairo_pdf_ft_font_t *font, unsigned long tag);
+    int (*write) (cairo_truetype_font_t *font, unsigned long tag);
 };
 
 static const table_t truetype_tables[] = {
@@ -733,21 +737,21 @@ static const table_t truetype_tables[] =
      * Remapping composite glyphs will reference the sub glyphs the
      * composite glyph is made up of.  That needs to be done first so
      * we have all the glyphs in the subset before going further. */
-    { TT_TAG_glyf, cairo_pdf_ft_font_write_glyf_table },
-    { TT_TAG_cmap, cairo_pdf_ft_font_write_cmap_table },
-    { TT_TAG_cvt,  cairo_pdf_ft_font_write_generic_table },
-    { TT_TAG_fpgm, cairo_pdf_ft_font_write_generic_table },
-    { TT_TAG_head, cairo_pdf_ft_font_write_head_table },
-    { TT_TAG_hhea, cairo_pdf_ft_font_write_hhea_table },
-    { TT_TAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
-    { TT_TAG_loca, cairo_pdf_ft_font_write_loca_table },
-    { TT_TAG_maxp, cairo_pdf_ft_font_write_maxp_table },
-    { TT_TAG_name, cairo_pdf_ft_font_write_generic_table },
-    { TT_TAG_prep, cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_glyf, cairo_truetype_font_write_glyf_table },
+    { TT_TAG_cmap, cairo_truetype_font_write_cmap_table },
+    { TT_TAG_cvt,  cairo_truetype_font_write_generic_table },
+    { TT_TAG_fpgm, cairo_truetype_font_write_generic_table },
+    { TT_TAG_head, cairo_truetype_font_write_head_table },
+    { TT_TAG_hhea, cairo_truetype_font_write_hhea_table },
+    { TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table },
+    { TT_TAG_loca, cairo_truetype_font_write_loca_table },
+    { TT_TAG_maxp, cairo_truetype_font_write_maxp_table },
+    { TT_TAG_name, cairo_truetype_font_write_generic_table },
+    { TT_TAG_prep, cairo_truetype_font_write_generic_table },
 };
 
 static cairo_status_t
-cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
+cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
 {
     cairo_status_t status;
     unsigned char *table_buffer;
@@ -765,17 +769,17 @@ cairo_pdf_ft_font_write_offset_table (ca
     search_range *= 16;
     range_shift = num_tables * 16 - search_range;
 
-    cairo_pdf_ft_font_write_be32 (font, SFNT_VERSION);
-    cairo_pdf_ft_font_write_be16 (font, num_tables);
-    cairo_pdf_ft_font_write_be16 (font, search_range);
-    cairo_pdf_ft_font_write_be16 (font, entry_selector);
-    cairo_pdf_ft_font_write_be16 (font, range_shift);
+    cairo_truetype_font_write_be32 (font, SFNT_VERSION);
+    cairo_truetype_font_write_be16 (font, num_tables);
+    cairo_truetype_font_write_be16 (font, search_range);
+    cairo_truetype_font_write_be16 (font, entry_selector);
+    cairo_truetype_font_write_be16 (font, range_shift);
 
     /* Allocate space for the table directory. Each directory entry
-     * will be filled in by cairo_pdf_ft_font_update_entry() after
+     * will be filled in by cairo_truetype_font_update_entry() after
      * the table is written. */
     table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
-    status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,
+    status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
 						      &table_buffer);
     if (status)
 	return status;
@@ -784,8 +788,9 @@ cairo_pdf_ft_font_write_offset_table (ca
 }
 
 static unsigned long
-cairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,
-				      unsigned long start, unsigned long end)
+cairo_truetype_font_calculate_checksum (cairo_truetype_font_t *font,
+					unsigned long          start,
+					unsigned long          end)
 {
     unsigned long *padded_end;
     unsigned long *p;
@@ -803,30 +808,35 @@ cairo_pdf_ft_font_calculate_checksum (ca
 }
 
 static void
-cairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned long tag,
-			unsigned long start, unsigned long end)
+cairo_truetype_font_update_entry (cairo_truetype_font_t *font,
+				  int                    index,
+				  unsigned long          tag,
+				  unsigned long          start,
+				  unsigned long          end)
 {
     unsigned long *entry;
 
     entry = _cairo_array_index (&font->output, 12 + 16 * index);
     entry[0] = cpu_to_be32 (tag);
-    entry[1] = cpu_to_be32 (cairo_pdf_ft_font_calculate_checksum (font, start, end));
+    entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end));
     entry[2] = cpu_to_be32 (start);
     entry[3] = cpu_to_be32 (end - start);
 }
 
 static cairo_status_t
-cairo_pdf_ft_font_generate (cairo_pdf_ft_font_t *font,
-			    const char **data, unsigned long *length,
-			    const unsigned long **string_offsets, unsigned long *num_strings)
+cairo_truetype_font_generate (cairo_truetype_font_t  *font,
+			      const char            **data,
+			      unsigned long          *length,
+			      const unsigned long   **string_offsets,
+			      unsigned long          *num_strings)
 {
     unsigned long start, end, next, checksum, *checksum_location;
     int i;
 
-    if (cairo_pdf_ft_font_write_offset_table (font))
+    if (cairo_truetype_font_write_offset_table (font))
 	goto fail;
 
-    start = cairo_pdf_ft_font_align_output (font);
+    start = cairo_truetype_font_align_output (font);
     end = start;
 
     end = 0;
@@ -835,15 +845,15 @@ cairo_pdf_ft_font_generate (cairo_pdf_ft
 	    goto fail;
 
 	end = _cairo_array_num_elements (&font->output);
-	next = cairo_pdf_ft_font_align_output (font);
-	cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,
+	next = cairo_truetype_font_align_output (font);
+	cairo_truetype_font_update_entry (font, i, truetype_tables[i].tag,
 					start, end);
-        cairo_pdf_ft_font_check_boundary (font, next);
+        cairo_truetype_font_check_boundary (font, next);
 	start = next;
     }
 
     checksum =
-	0xb1b0afba - cairo_pdf_ft_font_calculate_checksum (font, 0, end);
+	0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end);
     checksum_location = _cairo_array_index (&font->output, font->checksum_index);
     *checksum_location = cpu_to_be32 (checksum);
 
@@ -860,7 +870,7 @@ cairo_pdf_ft_font_generate (cairo_pdf_ft
 }
 
 static int
-cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph)
+cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph)
 {
     if (font->parent_to_subset[glyph] == 0) {
 	font->parent_to_subset[glyph] = font->base.num_glyphs;
@@ -875,7 +885,7 @@ cairo_status_t
 _cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
 			     cairo_scaled_font_subset_t	*font_subset)
 {
-    cairo_pdf_ft_font_t *font;
+    cairo_truetype_font_t *font;
     cairo_status_t status;
     const char *data = NULL; /* squelch bogus compiler warning */
     unsigned long length = 0; /* squelch bogus compiler warning */
@@ -884,16 +894,16 @@ _cairo_truetype_subset_init (cairo_truet
     const unsigned long *string_offsets = NULL;
     unsigned long num_strings = 0;
 
-    status = _cairo_pdf_ft_font_create (font_subset, &font);
+    status = _cairo_truetype_font_create (font_subset, &font);
     if (status)
 	return status;
 
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
 	parent_glyph = font->scaled_font_subset->glyphs[i];
-	cairo_pdf_ft_font_use_glyph (font, parent_glyph);
+	cairo_truetype_font_use_glyph (font, parent_glyph);
     }
 
-    status = cairo_pdf_ft_font_generate (font, &data, &length,
+    status = cairo_truetype_font_generate (font, &data, &length,
 					 &string_offsets, &num_strings);
     if (status)
 	goto fail1;
@@ -930,7 +940,7 @@ _cairo_truetype_subset_init (cairo_truet
     memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
     truetype_subset->num_string_offsets = num_strings;
 
-    cairo_pdf_ft_font_destroy (font);
+    cairo_truetype_font_destroy (font);
 
     return CAIRO_STATUS_SUCCESS;
 
@@ -941,7 +951,7 @@ _cairo_truetype_subset_init (cairo_truet
  fail2:
     free (truetype_subset->base_font);
  fail1:
-    cairo_pdf_ft_font_destroy (font);
+    cairo_truetype_font_destroy (font);
 
     return status;
 }
diff-tree f664a3b7a087272a27eb893b7ee5a1775eb92c4d (from a0989f427be87c60415963dd6822b3c5c3781691)
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Aug 2 19:14:19 2006 -0400

    Renamed cairo-font-subset.c to cairo-truetype-subset.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 624f979..d94fe53 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
 font_subset_sources =				\
-	cairo-font-subset.c			\
+	cairo-truetype-subset.c			\
 	cairo-scaled-font-subsets.c		\
 	cairo-scaled-font-subsets-private.h
 if CAIRO_HAS_FT_FONT
diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c
deleted file mode 100644
index b024684..0000000
--- a/src/cairo-font-subset.c
+++ /dev/null
@@ -1,957 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2004 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Kristian Høgsberg <krh at redhat.com>
- *	Adrian Johnson <ajohnson at redneon.com>
- */
-
-#include <string.h>
-#include "cairoint.h"
-#include "cairo-scaled-font-subsets-private.h"
-
-
-typedef struct ft_subset_glyph ft_subset_glyph_t;
-struct ft_subset_glyph {
-    int parent_index;
-    unsigned long location;
-};
-
-typedef struct _cairo_ft_font {
-
-    cairo_scaled_font_subset_t *scaled_font_subset;
-
-    struct {
-	char *base_font;
-	int num_glyphs;
-	int *widths;
-	long x_min, y_min, x_max, y_max;
-	long ascent, descent;
-    } base;
-
-    ft_subset_glyph_t *glyphs;
-    const cairo_scaled_font_backend_t *backend;
-    int num_glyphs_in_face;
-    int checksum_index;
-    cairo_array_t output;
-    cairo_array_t string_offsets;
-    unsigned long last_offset;
-    unsigned long last_boundary;
-    int *parent_to_subset;
-    cairo_status_t status;
-
-} cairo_pdf_ft_font_t;
-
-
-
-#define MAKE_TT_TAG(a, b, c, d)    (a<<24 | b<<16 | c<<8 | d)
-#define TT_TAG_cmap   MAKE_TT_TAG('c','m','a','p')
-#define TT_TAG_cvt    MAKE_TT_TAG('c','v','t',' ')
-#define TT_TAG_fpgm   MAKE_TT_TAG('f','p','g','m')
-#define TT_TAG_glyf   MAKE_TT_TAG('g','l','y','f')
-#define TT_TAG_head   MAKE_TT_TAG('h','e','a','d')
-#define TT_TAG_hhea   MAKE_TT_TAG('h','h','e','a')
-#define TT_TAG_hmtx   MAKE_TT_TAG('h','m','t','x')
-#define TT_TAG_loca   MAKE_TT_TAG('l','o','c','a')
-#define TT_TAG_maxp   MAKE_TT_TAG('m','a','x','p')
-#define TT_TAG_name   MAKE_TT_TAG('n','a','m','e')
-#define TT_TAG_prep   MAKE_TT_TAG('p','r','e','p')
-
-/* All tt_* structs are big-endian */
-typedef struct tt_head {
-    long           version;      /* FIXED */
-    long           revision;     /* FIXED */
-    unsigned long  checksum;
-    unsigned long  magic;
-    unsigned short flags;
-    unsigned short units_per_em;
-    long long      created;
-    long long      modified;
-    short          x_min;         /* FWORD */
-    short          y_min;         /* FWORD */
-    short          x_max;         /* FWORD */
-    short          y_max;         /* FWORD */
-    unsigned short mac_style;
-    unsigned short lowest_rec_pppem;
-    short          font_direction_hint;
-    short          index_to_loc_format;
-    short          glyph_data_format;
-} tt_head_t;
-
-typedef struct tt_hhea {
-    long           version;                /* FIXED */
-    short          ascender;               /* FWORD */
-    short          descender;              /* FWORD */
-    short          line_gap;               /* FWORD */
-    unsigned short advance_max_width;      /* UFWORD */
-    short          min_left_side_bearing;  /* FWORD */
-    short          min_right_side_bearing; /* FWORD */
-    short          x_max_extent;           /* FWORD */
-    short          caret_slope_rise;
-    short          caret_slope_run; 
-    short          reserved[5];
-    short          metric_data_format;
-    unsigned short num_hmetrics;
-} tt_hhea_t;
-
-typedef struct tt_maxp {
-    long           version;      /* FIXED */
-    unsigned short num_glyphs;
-    unsigned short max_points;
-    unsigned short max_contours;
-    unsigned short max_composite_points;
-    unsigned short max_composite_contours;
-    unsigned short max_zones;
-    unsigned short max_twilight_points;
-    unsigned short max_storage;
-    unsigned short max_function_defs;
-    unsigned short max_instruction_defs;
-    unsigned short max_stack_elements;
-    unsigned short max_size_of_instructions;
-    unsigned short max_component_elements;
-    unsigned short max_component_depth;
-} tt_maxp_t;
-
-typedef struct tt_name_record {
-    unsigned short platform;
-    unsigned short encoding;
-    unsigned short language;
-    unsigned short name;
-    unsigned short length;
-    unsigned short offset;
-} tt_name_record_t;
-
-typedef struct tt_name {
-    unsigned short   format;
-    unsigned short   num_records;
-    unsigned short   strings_offset;
-    tt_name_record_t records[1];
-} tt_name_t;
-
-static int
-cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);
-
-#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
-
-#define SFNT_VERSION			0x00010000
-#define SFNT_STRING_MAX_LENGTH  65535
-
-#ifdef WORDS_BIGENDIAN
-
-#define cpu_to_be16(v) (v)
-#define be16_to_cpu(v) (v)
-#define cpu_to_be32(v) (v)
-#define be32_to_cpu(v) (v)
-
-#else
-
-static inline unsigned short
-cpu_to_be16(unsigned short v)
-{
-    return (v << 8) | (v >> 8);
-}
-
-static inline unsigned short
-be16_to_cpu(unsigned short v)
-{
-    return cpu_to_be16 (v);
-}
-
-static inline unsigned long
-cpu_to_be32(unsigned long v)
-{
-    return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
-}
-
-static inline unsigned long
-be32_to_cpu(unsigned long v)
-{
-    return cpu_to_be32 (v);
-}
-
-#endif
-
-static cairo_status_t
-_cairo_pdf_ft_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
-			   cairo_pdf_ft_font_t        **font_return)
-{
-    cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
-    cairo_pdf_ft_font_t *font;
-    const cairo_scaled_font_backend_t *backend;
-    tt_head_t head;
-    tt_hhea_t hhea;
-    tt_maxp_t maxp;
-    tt_name_t *name;
-    tt_name_record_t *record;
-    unsigned long size;
-    int i, j;
-    
-    backend = scaled_font_subset->scaled_font->backend;
-    if (!backend->load_truetype_table)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    size = sizeof (tt_head_t);
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_head, 0, (unsigned char *) &head,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    size = sizeof (tt_maxp_t);
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_maxp, 0, (unsigned char *) &maxp,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    size = sizeof (tt_hhea_t);
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_hhea, 0, (unsigned char *) &hhea,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    size = 0;
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_name, 0, NULL,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    name = malloc(size);
-    if (name == NULL)
-        return CAIRO_STATUS_NO_MEMORY;
-    backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                 TT_TAG_name, 0, (unsigned char *) name,
-                                 &size);
-
-    /* FIXME: Figure out how to determine if the font is vertical without
-     *  requiring freetype.
-     *
-     *  if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
-     *   return CAIRO_INT_STATUS_UNSUPPORTED;
-     */
-
-    font = malloc (sizeof (cairo_pdf_ft_font_t));
-    if (font == NULL)
-	goto fail0;
-
-    font->backend = backend;
-    font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
-    font->scaled_font_subset = scaled_font_subset;
-    
-    font->last_offset = 0;
-    font->last_boundary = 0;
-    _cairo_array_init (&font->output, sizeof (char));
-    if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
-	goto fail1;
-    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (ft_subset_glyph_t));
-    if (font->glyphs == NULL)
-	goto fail2;
-
-    font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
-    if (font->parent_to_subset == NULL)
-	goto fail3;
-
-    font->base.num_glyphs = 0;
-    font->base.x_min = be16_to_cpu (head.x_min);
-    font->base.y_min = be16_to_cpu (head.y_min);
-    font->base.x_max = be16_to_cpu (head.x_max);
-    font->base.y_max = be16_to_cpu (head.y_max);
-    font->base.ascent = be16_to_cpu (hhea.ascender);
-    font->base.descent = be16_to_cpu (hhea.descender);
-
-
-    /* Extract the font name from the name table. At present this
-     * just looks for the Mac platform/Roman encoded font name. It
-     * should be extended to use any suitable font name in the
-     * name table. If the mac/roman font name is not found a
-     * CairoFont-x-y name is created.
-     */
-    font->base.base_font = NULL;
-    for (i = 0; i < be16_to_cpu(name->num_records); i++) {
-        record = &(name->records[i]);
-        if ((be16_to_cpu (record->platform) == 1) &&
-            (be16_to_cpu (record->encoding) == 0) &&
-            (be16_to_cpu (record->name) == 4)) { 
-            font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
-            if (font->base.base_font) {
-                strncpy(font->base.base_font,
-                        ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
-                        be16_to_cpu (record->length));
-                font->base.base_font[be16_to_cpu (record->length)] = 0;
-            }
-            break;
-        }
-    }
-
-    if (font->base.base_font == NULL) {
-        font->base.base_font = malloc (30);
-        if (font->base.base_font == NULL)
-            goto fail4; 
-        snprintf(font->base.base_font, 30, "CairoFont-%u-%u",
-                 scaled_font_subset->font_id,
-                 scaled_font_subset->subset_id);
-    }
-
-    for (i = 0, j = 0; font->base.base_font[j]; j++) {
-	if (font->base.base_font[j] == ' ')
-	    continue;
-	font->base.base_font[i++] = font->base.base_font[j];
-    }
-    font->base.base_font[i] = '\0';
-
-    font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
-    if (font->base.widths == NULL)
-	goto fail5;
-
-    _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
-    if (_cairo_array_grow_by (&font->string_offsets, 10) != CAIRO_STATUS_SUCCESS)
-	goto fail6;
-
-    font->status = CAIRO_STATUS_SUCCESS;
-
-    *font_return = font;
-
-    return CAIRO_STATUS_SUCCESS;
-
- fail6:
-    free (font->base.widths);
- fail5:
-    free (font->base.base_font);
- fail4:
-    free (font->parent_to_subset);
- fail3:
-    free (font->glyphs);
- fail2:
-    _cairo_array_fini (&font->output);
- fail1:
-    free (font);
- fail0:
-    free (name);
-    return status;
-}
-
-static void
-cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font)
-{
-    free (font->base.base_font);
-    free (font->parent_to_subset);
-    free (font->glyphs);
-    _cairo_array_fini (&font->output);
-    _cairo_array_fini (&font->string_offsets);
-    free (font);
-}
-
-static cairo_status_t
-cairo_pdf_ft_font_allocate_write_buffer (cairo_pdf_ft_font_t	 *font,
-					 size_t			  length,
-					 unsigned char		**buffer)
-{
-    cairo_status_t status;
-
-    status = _cairo_array_allocate (&font->output, length, (void **) buffer);
-    if (status)
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-cairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,
-			 const void *data, size_t length)
-{
-    cairo_status_t status;
-
-    status = _cairo_array_append_multiple (&font->output, data, length);
-    if (status)
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-cairo_pdf_ft_font_write_be16 (cairo_pdf_ft_font_t *font,
-			      unsigned short value)
-{
-    unsigned short be16_value;
-
-    be16_value = cpu_to_be16 (value);
-    cairo_pdf_ft_font_write (font, &be16_value, sizeof be16_value);
-}
-
-static void
-cairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value)
-{
-    unsigned long be32_value;
-
-    be32_value = cpu_to_be32 (value);
-    cairo_pdf_ft_font_write (font, &be32_value, sizeof be32_value);
-}
-
-static unsigned long
-cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
-{
-    int length, aligned, pad;
-    unsigned char *ignored;
-
-    length = _cairo_array_num_elements (&font->output);
-    aligned = (length + 3) & ~3;
-    pad = aligned - length;
-
-    if (pad)
-	cairo_pdf_ft_font_allocate_write_buffer (font, pad, &ignored);
-
-    return aligned;
-}
-
-static void
-cairo_pdf_ft_font_check_boundary (cairo_pdf_ft_font_t *font, unsigned long boundary)
-{
-    if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) {
-        _cairo_array_append(&font->string_offsets, &font->last_boundary);
-        font->last_offset = font->last_boundary;
-    }
-    font->last_boundary = boundary;
-}
-
-static int
-cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag)
-{
-    int i;
-
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 1);
-
-    cairo_pdf_ft_font_write_be16 (font, 1);
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be32 (font, 12);
-
-    /* Output a format 6 encoding table. */
-
-    cairo_pdf_ft_font_write_be16 (font, 6);
-    cairo_pdf_ft_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 1); /* First glyph */
-    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs - 1);
-    for (i = 1; i < font->base.num_glyphs; i++)
-	cairo_pdf_ft_font_write_be16 (font, i);
-
-    return font->status;
-}
-
-static int
-cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,
-				       unsigned long tag)
-{
-    cairo_status_t status;
-    unsigned char *buffer;
-    unsigned long size;
-
-    size = 0;
-    font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
-                                        tag, 0, NULL, &size);
-    status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
-    /* XXX: Need to check status here. */
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        tag, 0, buffer, &size);
-    return 0;
-}
-
-typedef struct composite_glyph composite_glyph_t;
-struct composite_glyph {
-    unsigned short flags;
-    unsigned short index;
-    unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */
-};
-
-typedef struct glyph_data glyph_data_t;
-struct glyph_data {
-    short             num_contours;
-    char              data[8];
-    composite_glyph_t glyph;
-};
-
-/* composite_glyph_t flags */
-#define ARG_1_AND_2_ARE_WORDS     0x0001
-#define WE_HAVE_A_SCALE           0x0008
-#define MORE_COMPONENTS           0x0020
-#define WE_HAVE_AN_X_AND_Y_SCALE  0x0040
-#define WE_HAVE_A_TWO_BY_TWO      0x0080
-
-static void
-cairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font,
-					 unsigned char *buffer)
-{
-    glyph_data_t *glyph_data;
-    composite_glyph_t *composite_glyph;
-    int num_args;
-    int has_more_components;
-    unsigned short flags;
-    unsigned short index;
-
-    glyph_data = (glyph_data_t *) buffer;
-    if ((short)be16_to_cpu (glyph_data->num_contours) >= 0)
-        return;
-
-    composite_glyph = &glyph_data->glyph;
-    do {
-        flags = be16_to_cpu (composite_glyph->flags);
-        has_more_components = flags & MORE_COMPONENTS;
-        index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
-        composite_glyph->index = cpu_to_be16 (index);
-        num_args = 1;
-        if (flags & ARG_1_AND_2_ARE_WORDS)
-            num_args += 1;
-        if (flags & WE_HAVE_A_SCALE)
-            num_args += 1;
-        else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
-            num_args += 2;
-        else if (flags & WE_HAVE_A_TWO_BY_TWO)
-            num_args += 3;
-        composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);
-    } while (has_more_components);
-}
-
-static int
-cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
-{
-    cairo_status_t status;
-    unsigned long start_offset, index, size, next;
-    tt_head_t header;
-    unsigned long begin, end;
-    unsigned char *buffer;
-    int i;
-    union {
-	unsigned char *bytes;
-	unsigned short *short_offsets;
-	unsigned long *long_offsets;
-    } u;
-
-    size = sizeof (tt_head_t);
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        TT_TAG_head, 0, (unsigned char*) &header, &size);
-    
-    if (be16_to_cpu (header.index_to_loc_format) == 0)
-	size = sizeof (short) * (font->num_glyphs_in_face + 1);
-    else
-	size = sizeof (long) * (font->num_glyphs_in_face + 1);
-
-    u.bytes = malloc (size);
-    if (u.bytes == NULL) {
-	font->status = CAIRO_STATUS_NO_MEMORY;
-	return font->status;
-    }
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        TT_TAG_loca, 0, u.bytes, &size);
-
-    start_offset = _cairo_array_num_elements (&font->output);
-    for (i = 0; i < font->base.num_glyphs; i++) {
-	index = font->glyphs[i].parent_index;
-	if (be16_to_cpu (header.index_to_loc_format) == 0) {
-	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
-	    end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
-	}
-	else {
-	    begin = be32_to_cpu (u.long_offsets[index]);
-	    end = be32_to_cpu (u.long_offsets[index + 1]);
-	}
-
-	size = end - begin;
-
-        next = cairo_pdf_ft_font_align_output (font);
-        cairo_pdf_ft_font_check_boundary (font, next);
-        font->glyphs[i].location = next - start_offset;
-
-	status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
-	if (status)
-	    break;
-        if (size != 0) {
-            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                                TT_TAG_glyf, begin, buffer, &size);
-            cairo_pdf_ft_font_remap_composite_glyph (font, buffer);
-        }
-    }
-
-    font->glyphs[i].location =
-	cairo_pdf_ft_font_align_output (font) - start_offset;
-
-    free (u.bytes);
-
-    return font->status;
-}
-
-static int
-cairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,
-                                      unsigned long tag)
-{
-    unsigned char *buffer;
-    unsigned long size;
-
-    size = 0;
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        tag, 0, NULL, &size);
-    font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
-    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
-    font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
-                                        tag, 0, buffer, &size);
-    return font->status;
-}
-
-static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag)
-{
-    tt_hhea_t *hhea;
-    unsigned long size;
-
-    size = sizeof (tt_hhea_t);
-    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        tag, 0, (unsigned char *) hhea, &size);
-    hhea->num_hmetrics = cpu_to_be16 (font->base.num_glyphs);
-    return font->status;
-}
-
-static int
-cairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
-{
-    cairo_status_t status;
-    unsigned long size;
-    unsigned long long_entry_size;
-    unsigned long short_entry_size;
-    short *p;
-    int i;
-    tt_hhea_t hhea;
-    int num_hmetrics;
-
-    size = sizeof (tt_hhea_t);
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        TT_TAG_hhea, 0, (unsigned char*) &hhea, &size);
-    num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
-
-    for (i = 0; i < font->base.num_glyphs; i++) {
-        long_entry_size = 2 * sizeof (short);
-        short_entry_size = sizeof (short);
-        status = cairo_pdf_ft_font_allocate_write_buffer (font, long_entry_size,
-							  (unsigned char **) &p);
-        if (font->glyphs[i].parent_index < num_hmetrics) {
-            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                                TT_TAG_hmtx,
-                                                font->glyphs[i].parent_index * long_entry_size,
-                                                (unsigned char *) p, &long_entry_size);
-        }
-        else
-        {
-            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                                TT_TAG_hmtx,
-                                                (num_hmetrics - 1) * long_entry_size,
-                                                (unsigned char *) p, &short_entry_size);
-            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                                TT_TAG_hmtx,
-                                                (num_hmetrics - 1) * long_entry_size +
-                                                (font->glyphs[i].parent_index - num_hmetrics)
-                                                                          * short_entry_size,
-                                                (unsigned char *) (p+1), &short_entry_size);
-        }
-        font->base.widths[i] = be16_to_cpu (p[0]);
-    }
-
-    return font->status;
-}
-
-static int
-cairo_pdf_ft_font_write_loca_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
-{
-    int i;
-    tt_head_t header;
-    unsigned long size;
-
-    size = sizeof(tt_head_t);
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        TT_TAG_head, 0, (unsigned char*) &header, &size);
-
-    if (be16_to_cpu (header.index_to_loc_format) == 0) {
-	for (i = 0; i < font->base.num_glyphs + 1; i++)
-	    cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);
-    }
-    else {
-	for (i = 0; i < font->base.num_glyphs + 1; i++)
-	    cairo_pdf_ft_font_write_be32 (font, font->glyphs[i].location);
-    }
-
-    return font->status;
-}
-
-static int
-cairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
-{
-    tt_maxp_t *maxp;
-    unsigned long size;
-
-    size = sizeof (tt_maxp_t);
-    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
-    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                        tag, 0, (unsigned char *) maxp, &size);
-    maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
-    return font->status;
-}
-
-typedef struct table table_t;
-struct table {
-    unsigned long tag;
-    int (*write) (cairo_pdf_ft_font_t *font, unsigned long tag);
-};
-
-static const table_t truetype_tables[] = {
-    /* As we write out the glyf table we remap composite glyphs.
-     * Remapping composite glyphs will reference the sub glyphs the
-     * composite glyph is made up of.  That needs to be done first so
-     * we have all the glyphs in the subset before going further. */
-    { TT_TAG_glyf, cairo_pdf_ft_font_write_glyf_table },
-    { TT_TAG_cmap, cairo_pdf_ft_font_write_cmap_table },
-    { TT_TAG_cvt,  cairo_pdf_ft_font_write_generic_table },
-    { TT_TAG_fpgm, cairo_pdf_ft_font_write_generic_table },
-    { TT_TAG_head, cairo_pdf_ft_font_write_head_table },
-    { TT_TAG_hhea, cairo_pdf_ft_font_write_hhea_table },
-    { TT_TAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
-    { TT_TAG_loca, cairo_pdf_ft_font_write_loca_table },
-    { TT_TAG_maxp, cairo_pdf_ft_font_write_maxp_table },
-    { TT_TAG_name, cairo_pdf_ft_font_write_generic_table },
-    { TT_TAG_prep, cairo_pdf_ft_font_write_generic_table },
-};
-
-static cairo_status_t
-cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
-{
-    cairo_status_t status;
-    unsigned char *table_buffer;
-    size_t table_buffer_length;
-    unsigned short search_range, entry_selector, range_shift;
-    int num_tables;
-
-    num_tables = ARRAY_LENGTH (truetype_tables);
-    search_range = 1;
-    entry_selector = 0;
-    while (search_range * 2 <= num_tables) {
-	search_range *= 2;
-	entry_selector++;
-    }
-    search_range *= 16;
-    range_shift = num_tables * 16 - search_range;
-
-    cairo_pdf_ft_font_write_be32 (font, SFNT_VERSION);
-    cairo_pdf_ft_font_write_be16 (font, num_tables);
-    cairo_pdf_ft_font_write_be16 (font, search_range);
-    cairo_pdf_ft_font_write_be16 (font, entry_selector);
-    cairo_pdf_ft_font_write_be16 (font, range_shift);
-
-    /* Allocate space for the table directory. Each directory entry
-     * will be filled in by cairo_pdf_ft_font_update_entry() after
-     * the table is written. */
-    table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
-    status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,
-						      &table_buffer);
-    if (status)
-	return status;
-
-    return font->status;
-}
-
-static unsigned long
-cairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,
-				      unsigned long start, unsigned long end)
-{
-    unsigned long *padded_end;
-    unsigned long *p;
-    unsigned long checksum;
-    char *data;
-
-    checksum = 0;
-    data = _cairo_array_index (&font->output, 0);
-    p = (unsigned long *) (data + start);
-    padded_end = (unsigned long *) (data + ((end + 3) & ~3));
-    while (p < padded_end)
-	checksum += *p++;
-
-    return checksum;
-}
-
-static void
-cairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned long tag,
-			unsigned long start, unsigned long end)
-{
-    unsigned long *entry;
-
-    entry = _cairo_array_index (&font->output, 12 + 16 * index);
-    entry[0] = cpu_to_be32 (tag);
-    entry[1] = cpu_to_be32 (cairo_pdf_ft_font_calculate_checksum (font, start, end));
-    entry[2] = cpu_to_be32 (start);
-    entry[3] = cpu_to_be32 (end - start);
-}
-
-static cairo_status_t
-cairo_pdf_ft_font_generate (cairo_pdf_ft_font_t *font,
-			    const char **data, unsigned long *length,
-			    const unsigned long **string_offsets, unsigned long *num_strings)
-{
-    unsigned long start, end, next, checksum, *checksum_location;
-    int i;
-
-    if (cairo_pdf_ft_font_write_offset_table (font))
-	goto fail;
-
-    start = cairo_pdf_ft_font_align_output (font);
-    end = start;
-
-    end = 0;
-    for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
-	if (truetype_tables[i].write (font, truetype_tables[i].tag))
-	    goto fail;
-
-	end = _cairo_array_num_elements (&font->output);
-	next = cairo_pdf_ft_font_align_output (font);
-	cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,
-					start, end);
-        cairo_pdf_ft_font_check_boundary (font, next);
-	start = next;
-    }
-
-    checksum =
-	0xb1b0afba - cairo_pdf_ft_font_calculate_checksum (font, 0, end);
-    checksum_location = _cairo_array_index (&font->output, font->checksum_index);
-    *checksum_location = cpu_to_be32 (checksum);
-
-    *data = _cairo_array_index (&font->output, 0);
-    *length = _cairo_array_num_elements (&font->output);
-    *num_strings = _cairo_array_num_elements (&font->string_offsets);
-    if (*num_strings != 0)
-	*string_offsets = _cairo_array_index (&font->string_offsets, 0);
-    else
-	*string_offsets = NULL;
-
- fail:
-    return font->status;
-}
-
-static int
-cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph)
-{
-    if (font->parent_to_subset[glyph] == 0) {
-	font->parent_to_subset[glyph] = font->base.num_glyphs;
-	font->glyphs[font->base.num_glyphs].parent_index = glyph;
-	font->base.num_glyphs++;
-    }
-
-    return font->parent_to_subset[glyph];
-}
-
-cairo_status_t
-_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
-			     cairo_scaled_font_subset_t	*font_subset)
-{
-    cairo_pdf_ft_font_t *font;
-    cairo_status_t status;
-    const char *data = NULL; /* squelch bogus compiler warning */
-    unsigned long length = 0; /* squelch bogus compiler warning */
-    unsigned long parent_glyph, offsets_length;
-    int i;
-    const unsigned long *string_offsets = NULL;
-    unsigned long num_strings = 0;
-
-    status = _cairo_pdf_ft_font_create (font_subset, &font);
-    if (status)
-	return status;
-
-    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
-	parent_glyph = font->scaled_font_subset->glyphs[i];
-	cairo_pdf_ft_font_use_glyph (font, parent_glyph);
-    }
-
-    status = cairo_pdf_ft_font_generate (font, &data, &length,
-					 &string_offsets, &num_strings);
-    if (status)
-	goto fail1;
-
-    truetype_subset->base_font = strdup (font->base.base_font);
-    if (truetype_subset->base_font == NULL)
-	goto fail1;
-
-    truetype_subset->widths = calloc (sizeof (int), font->base.num_glyphs);
-    if (truetype_subset->widths == NULL)
-	goto fail2;
-    for (i = 0; i < font->base.num_glyphs; i++)
-	truetype_subset->widths[i] = font->base.widths[i];
-
-    truetype_subset->x_min = font->base.x_min;
-    truetype_subset->y_min = font->base.y_min;
-    truetype_subset->x_max = font->base.x_max;
-    truetype_subset->y_max = font->base.y_max;
-    truetype_subset->ascent = font->base.ascent;
-    truetype_subset->descent = font->base.descent;
-
-    truetype_subset->data = malloc (length);
-    if (truetype_subset->data == NULL)
-	goto fail3;
-
-    memcpy (truetype_subset->data, data, length);
-    truetype_subset->data_length = length;
-
-    offsets_length = num_strings * sizeof (unsigned long);
-    truetype_subset->string_offsets = malloc (offsets_length);
-    if (truetype_subset->string_offsets == NULL)
-	goto fail4;
-
-    memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
-    truetype_subset->num_string_offsets = num_strings;
-
-    cairo_pdf_ft_font_destroy (font);
-
-    return CAIRO_STATUS_SUCCESS;
-
- fail4:
-    free (truetype_subset->data);
- fail3:
-    free (truetype_subset->widths);
- fail2:
-    free (truetype_subset->base_font);
- fail1:
-    cairo_pdf_ft_font_destroy (font);
-
-    return status;
-}
-
-void
-_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
-{
-    free (subset->base_font);
-    free (subset->widths);
-    free (subset->data);
-    free (subset->string_offsets);
-}
-
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
new file mode 100644
index 0000000..b024684
--- /dev/null
+++ b/src/cairo-truetype-subset.c
@@ -0,0 +1,957 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2004 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Kristian Høgsberg <krh at redhat.com>
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include <string.h>
+#include "cairoint.h"
+#include "cairo-scaled-font-subsets-private.h"
+
+
+typedef struct ft_subset_glyph ft_subset_glyph_t;
+struct ft_subset_glyph {
+    int parent_index;
+    unsigned long location;
+};
+
+typedef struct _cairo_ft_font {
+
+    cairo_scaled_font_subset_t *scaled_font_subset;
+
+    struct {
+	char *base_font;
+	int num_glyphs;
+	int *widths;
+	long x_min, y_min, x_max, y_max;
+	long ascent, descent;
+    } base;
+
+    ft_subset_glyph_t *glyphs;
+    const cairo_scaled_font_backend_t *backend;
+    int num_glyphs_in_face;
+    int checksum_index;
+    cairo_array_t output;
+    cairo_array_t string_offsets;
+    unsigned long last_offset;
+    unsigned long last_boundary;
+    int *parent_to_subset;
+    cairo_status_t status;
+
+} cairo_pdf_ft_font_t;
+
+
+
+#define MAKE_TT_TAG(a, b, c, d)    (a<<24 | b<<16 | c<<8 | d)
+#define TT_TAG_cmap   MAKE_TT_TAG('c','m','a','p')
+#define TT_TAG_cvt    MAKE_TT_TAG('c','v','t',' ')
+#define TT_TAG_fpgm   MAKE_TT_TAG('f','p','g','m')
+#define TT_TAG_glyf   MAKE_TT_TAG('g','l','y','f')
+#define TT_TAG_head   MAKE_TT_TAG('h','e','a','d')
+#define TT_TAG_hhea   MAKE_TT_TAG('h','h','e','a')
+#define TT_TAG_hmtx   MAKE_TT_TAG('h','m','t','x')
+#define TT_TAG_loca   MAKE_TT_TAG('l','o','c','a')
+#define TT_TAG_maxp   MAKE_TT_TAG('m','a','x','p')
+#define TT_TAG_name   MAKE_TT_TAG('n','a','m','e')
+#define TT_TAG_prep   MAKE_TT_TAG('p','r','e','p')
+
+/* All tt_* structs are big-endian */
+typedef struct tt_head {
+    long           version;      /* FIXED */
+    long           revision;     /* FIXED */
+    unsigned long  checksum;
+    unsigned long  magic;
+    unsigned short flags;
+    unsigned short units_per_em;
+    long long      created;
+    long long      modified;
+    short          x_min;         /* FWORD */
+    short          y_min;         /* FWORD */
+    short          x_max;         /* FWORD */
+    short          y_max;         /* FWORD */
+    unsigned short mac_style;
+    unsigned short lowest_rec_pppem;
+    short          font_direction_hint;
+    short          index_to_loc_format;
+    short          glyph_data_format;
+} tt_head_t;
+
+typedef struct tt_hhea {
+    long           version;                /* FIXED */
+    short          ascender;               /* FWORD */
+    short          descender;              /* FWORD */
+    short          line_gap;               /* FWORD */
+    unsigned short advance_max_width;      /* UFWORD */
+    short          min_left_side_bearing;  /* FWORD */
+    short          min_right_side_bearing; /* FWORD */
+    short          x_max_extent;           /* FWORD */
+    short          caret_slope_rise;
+    short          caret_slope_run; 
+    short          reserved[5];
+    short          metric_data_format;
+    unsigned short num_hmetrics;
+} tt_hhea_t;
+
+typedef struct tt_maxp {
+    long           version;      /* FIXED */
+    unsigned short num_glyphs;
+    unsigned short max_points;
+    unsigned short max_contours;
+    unsigned short max_composite_points;
+    unsigned short max_composite_contours;
+    unsigned short max_zones;
+    unsigned short max_twilight_points;
+    unsigned short max_storage;
+    unsigned short max_function_defs;
+    unsigned short max_instruction_defs;
+    unsigned short max_stack_elements;
+    unsigned short max_size_of_instructions;
+    unsigned short max_component_elements;
+    unsigned short max_component_depth;
+} tt_maxp_t;
+
+typedef struct tt_name_record {
+    unsigned short platform;
+    unsigned short encoding;
+    unsigned short language;
+    unsigned short name;
+    unsigned short length;
+    unsigned short offset;
+} tt_name_record_t;
+
+typedef struct tt_name {
+    unsigned short   format;
+    unsigned short   num_records;
+    unsigned short   strings_offset;
+    tt_name_record_t records[1];
+} tt_name_t;
+
+static int
+cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);
+
+#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
+
+#define SFNT_VERSION			0x00010000
+#define SFNT_STRING_MAX_LENGTH  65535
+
+#ifdef WORDS_BIGENDIAN
+
+#define cpu_to_be16(v) (v)
+#define be16_to_cpu(v) (v)
+#define cpu_to_be32(v) (v)
+#define be32_to_cpu(v) (v)
+
+#else
+
+static inline unsigned short
+cpu_to_be16(unsigned short v)
+{
+    return (v << 8) | (v >> 8);
+}
+
+static inline unsigned short
+be16_to_cpu(unsigned short v)
+{
+    return cpu_to_be16 (v);
+}
+
+static inline unsigned long
+cpu_to_be32(unsigned long v)
+{
+    return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
+}
+
+static inline unsigned long
+be32_to_cpu(unsigned long v)
+{
+    return cpu_to_be32 (v);
+}
+
+#endif
+
+static cairo_status_t
+_cairo_pdf_ft_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
+			   cairo_pdf_ft_font_t        **font_return)
+{
+    cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
+    cairo_pdf_ft_font_t *font;
+    const cairo_scaled_font_backend_t *backend;
+    tt_head_t head;
+    tt_hhea_t hhea;
+    tt_maxp_t maxp;
+    tt_name_t *name;
+    tt_name_record_t *record;
+    unsigned long size;
+    int i, j;
+    
+    backend = scaled_font_subset->scaled_font->backend;
+    if (!backend->load_truetype_table)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    size = sizeof (tt_head_t);
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_head, 0, (unsigned char *) &head,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    size = sizeof (tt_maxp_t);
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_maxp, 0, (unsigned char *) &maxp,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    size = sizeof (tt_hhea_t);
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_hhea, 0, (unsigned char *) &hhea,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    size = 0;
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_name, 0, NULL,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+    name = malloc(size);
+    if (name == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+    backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                 TT_TAG_name, 0, (unsigned char *) name,
+                                 &size);
+
+    /* FIXME: Figure out how to determine if the font is vertical without
+     *  requiring freetype.
+     *
+     *  if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
+     *   return CAIRO_INT_STATUS_UNSUPPORTED;
+     */
+
+    font = malloc (sizeof (cairo_pdf_ft_font_t));
+    if (font == NULL)
+	goto fail0;
+
+    font->backend = backend;
+    font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
+    font->scaled_font_subset = scaled_font_subset;
+    
+    font->last_offset = 0;
+    font->last_boundary = 0;
+    _cairo_array_init (&font->output, sizeof (char));
+    if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
+	goto fail1;
+    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (ft_subset_glyph_t));
+    if (font->glyphs == NULL)
+	goto fail2;
+
+    font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
+    if (font->parent_to_subset == NULL)
+	goto fail3;
+
+    font->base.num_glyphs = 0;
+    font->base.x_min = be16_to_cpu (head.x_min);
+    font->base.y_min = be16_to_cpu (head.y_min);
+    font->base.x_max = be16_to_cpu (head.x_max);
+    font->base.y_max = be16_to_cpu (head.y_max);
+    font->base.ascent = be16_to_cpu (hhea.ascender);
+    font->base.descent = be16_to_cpu (hhea.descender);
+
+
+    /* Extract the font name from the name table. At present this
+     * just looks for the Mac platform/Roman encoded font name. It
+     * should be extended to use any suitable font name in the
+     * name table. If the mac/roman font name is not found a
+     * CairoFont-x-y name is created.
+     */
+    font->base.base_font = NULL;
+    for (i = 0; i < be16_to_cpu(name->num_records); i++) {
+        record = &(name->records[i]);
+        if ((be16_to_cpu (record->platform) == 1) &&
+            (be16_to_cpu (record->encoding) == 0) &&
+            (be16_to_cpu (record->name) == 4)) { 
+            font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
+            if (font->base.base_font) {
+                strncpy(font->base.base_font,
+                        ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
+                        be16_to_cpu (record->length));
+                font->base.base_font[be16_to_cpu (record->length)] = 0;
+            }
+            break;
+        }
+    }
+
+    if (font->base.base_font == NULL) {
+        font->base.base_font = malloc (30);
+        if (font->base.base_font == NULL)
+            goto fail4; 
+        snprintf(font->base.base_font, 30, "CairoFont-%u-%u",
+                 scaled_font_subset->font_id,
+                 scaled_font_subset->subset_id);
+    }
+
+    for (i = 0, j = 0; font->base.base_font[j]; j++) {
+	if (font->base.base_font[j] == ' ')
+	    continue;
+	font->base.base_font[i++] = font->base.base_font[j];
+    }
+    font->base.base_font[i] = '\0';
+
+    font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
+    if (font->base.widths == NULL)
+	goto fail5;
+
+    _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
+    if (_cairo_array_grow_by (&font->string_offsets, 10) != CAIRO_STATUS_SUCCESS)
+	goto fail6;
+
+    font->status = CAIRO_STATUS_SUCCESS;
+
+    *font_return = font;
+
+    return CAIRO_STATUS_SUCCESS;
+
+ fail6:
+    free (font->base.widths);
+ fail5:
+    free (font->base.base_font);
+ fail4:
+    free (font->parent_to_subset);
+ fail3:
+    free (font->glyphs);
+ fail2:
+    _cairo_array_fini (&font->output);
+ fail1:
+    free (font);
+ fail0:
+    free (name);
+    return status;
+}
+
+static void
+cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font)
+{
+    free (font->base.base_font);
+    free (font->parent_to_subset);
+    free (font->glyphs);
+    _cairo_array_fini (&font->output);
+    _cairo_array_fini (&font->string_offsets);
+    free (font);
+}
+
+static cairo_status_t
+cairo_pdf_ft_font_allocate_write_buffer (cairo_pdf_ft_font_t	 *font,
+					 size_t			  length,
+					 unsigned char		**buffer)
+{
+    cairo_status_t status;
+
+    status = _cairo_array_allocate (&font->output, length, (void **) buffer);
+    if (status)
+	return status;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+cairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,
+			 const void *data, size_t length)
+{
+    cairo_status_t status;
+
+    status = _cairo_array_append_multiple (&font->output, data, length);
+    if (status)
+	return status;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+cairo_pdf_ft_font_write_be16 (cairo_pdf_ft_font_t *font,
+			      unsigned short value)
+{
+    unsigned short be16_value;
+
+    be16_value = cpu_to_be16 (value);
+    cairo_pdf_ft_font_write (font, &be16_value, sizeof be16_value);
+}
+
+static void
+cairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value)
+{
+    unsigned long be32_value;
+
+    be32_value = cpu_to_be32 (value);
+    cairo_pdf_ft_font_write (font, &be32_value, sizeof be32_value);
+}
+
+static unsigned long
+cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
+{
+    int length, aligned, pad;
+    unsigned char *ignored;
+
+    length = _cairo_array_num_elements (&font->output);
+    aligned = (length + 3) & ~3;
+    pad = aligned - length;
+
+    if (pad)
+	cairo_pdf_ft_font_allocate_write_buffer (font, pad, &ignored);
+
+    return aligned;
+}
+
+static void
+cairo_pdf_ft_font_check_boundary (cairo_pdf_ft_font_t *font, unsigned long boundary)
+{
+    if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) {
+        _cairo_array_append(&font->string_offsets, &font->last_boundary);
+        font->last_offset = font->last_boundary;
+    }
+    font->last_boundary = boundary;
+}
+
+static int
+cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag)
+{
+    int i;
+
+    cairo_pdf_ft_font_write_be16 (font, 0);
+    cairo_pdf_ft_font_write_be16 (font, 1);
+
+    cairo_pdf_ft_font_write_be16 (font, 1);
+    cairo_pdf_ft_font_write_be16 (font, 0);
+    cairo_pdf_ft_font_write_be32 (font, 12);
+
+    /* Output a format 6 encoding table. */
+
+    cairo_pdf_ft_font_write_be16 (font, 6);
+    cairo_pdf_ft_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
+    cairo_pdf_ft_font_write_be16 (font, 0);
+    cairo_pdf_ft_font_write_be16 (font, 1); /* First glyph */
+    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs - 1);
+    for (i = 1; i < font->base.num_glyphs; i++)
+	cairo_pdf_ft_font_write_be16 (font, i);
+
+    return font->status;
+}
+
+static int
+cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,
+				       unsigned long tag)
+{
+    cairo_status_t status;
+    unsigned char *buffer;
+    unsigned long size;
+
+    size = 0;
+    font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
+                                        tag, 0, NULL, &size);
+    status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+    /* XXX: Need to check status here. */
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, buffer, &size);
+    return 0;
+}
+
+typedef struct composite_glyph composite_glyph_t;
+struct composite_glyph {
+    unsigned short flags;
+    unsigned short index;
+    unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */
+};
+
+typedef struct glyph_data glyph_data_t;
+struct glyph_data {
+    short             num_contours;
+    char              data[8];
+    composite_glyph_t glyph;
+};
+
+/* composite_glyph_t flags */
+#define ARG_1_AND_2_ARE_WORDS     0x0001
+#define WE_HAVE_A_SCALE           0x0008
+#define MORE_COMPONENTS           0x0020
+#define WE_HAVE_AN_X_AND_Y_SCALE  0x0040
+#define WE_HAVE_A_TWO_BY_TWO      0x0080
+
+static void
+cairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font,
+					 unsigned char *buffer)
+{
+    glyph_data_t *glyph_data;
+    composite_glyph_t *composite_glyph;
+    int num_args;
+    int has_more_components;
+    unsigned short flags;
+    unsigned short index;
+
+    glyph_data = (glyph_data_t *) buffer;
+    if ((short)be16_to_cpu (glyph_data->num_contours) >= 0)
+        return;
+
+    composite_glyph = &glyph_data->glyph;
+    do {
+        flags = be16_to_cpu (composite_glyph->flags);
+        has_more_components = flags & MORE_COMPONENTS;
+        index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
+        composite_glyph->index = cpu_to_be16 (index);
+        num_args = 1;
+        if (flags & ARG_1_AND_2_ARE_WORDS)
+            num_args += 1;
+        if (flags & WE_HAVE_A_SCALE)
+            num_args += 1;
+        else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
+            num_args += 2;
+        else if (flags & WE_HAVE_A_TWO_BY_TWO)
+            num_args += 3;
+        composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);
+    } while (has_more_components);
+}
+
+static int
+cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
+				    unsigned long tag)
+{
+    cairo_status_t status;
+    unsigned long start_offset, index, size, next;
+    tt_head_t header;
+    unsigned long begin, end;
+    unsigned char *buffer;
+    int i;
+    union {
+	unsigned char *bytes;
+	unsigned short *short_offsets;
+	unsigned long *long_offsets;
+    } u;
+
+    size = sizeof (tt_head_t);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_head, 0, (unsigned char*) &header, &size);
+    
+    if (be16_to_cpu (header.index_to_loc_format) == 0)
+	size = sizeof (short) * (font->num_glyphs_in_face + 1);
+    else
+	size = sizeof (long) * (font->num_glyphs_in_face + 1);
+
+    u.bytes = malloc (size);
+    if (u.bytes == NULL) {
+	font->status = CAIRO_STATUS_NO_MEMORY;
+	return font->status;
+    }
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_loca, 0, u.bytes, &size);
+
+    start_offset = _cairo_array_num_elements (&font->output);
+    for (i = 0; i < font->base.num_glyphs; i++) {
+	index = font->glyphs[i].parent_index;
+	if (be16_to_cpu (header.index_to_loc_format) == 0) {
+	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
+	    end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
+	}
+	else {
+	    begin = be32_to_cpu (u.long_offsets[index]);
+	    end = be32_to_cpu (u.long_offsets[index + 1]);
+	}
+
+	size = end - begin;
+
+        next = cairo_pdf_ft_font_align_output (font);
+        cairo_pdf_ft_font_check_boundary (font, next);
+        font->glyphs[i].location = next - start_offset;
+
+	status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+	if (status)
+	    break;
+        if (size != 0) {
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_glyf, begin, buffer, &size);
+            cairo_pdf_ft_font_remap_composite_glyph (font, buffer);
+        }
+    }
+
+    font->glyphs[i].location =
+	cairo_pdf_ft_font_align_output (font) - start_offset;
+
+    free (u.bytes);
+
+    return font->status;
+}
+
+static int
+cairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,
+                                      unsigned long tag)
+{
+    unsigned char *buffer;
+    unsigned long size;
+
+    size = 0;
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, NULL, &size);
+    font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
+    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+    font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
+                                        tag, 0, buffer, &size);
+    return font->status;
+}
+
+static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag)
+{
+    tt_hhea_t *hhea;
+    unsigned long size;
+
+    size = sizeof (tt_hhea_t);
+    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, (unsigned char *) hhea, &size);
+    hhea->num_hmetrics = cpu_to_be16 (font->base.num_glyphs);
+    return font->status;
+}
+
+static int
+cairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,
+				    unsigned long tag)
+{
+    cairo_status_t status;
+    unsigned long size;
+    unsigned long long_entry_size;
+    unsigned long short_entry_size;
+    short *p;
+    int i;
+    tt_hhea_t hhea;
+    int num_hmetrics;
+
+    size = sizeof (tt_hhea_t);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_hhea, 0, (unsigned char*) &hhea, &size);
+    num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
+
+    for (i = 0; i < font->base.num_glyphs; i++) {
+        long_entry_size = 2 * sizeof (short);
+        short_entry_size = sizeof (short);
+        status = cairo_pdf_ft_font_allocate_write_buffer (font, long_entry_size,
+							  (unsigned char **) &p);
+        if (font->glyphs[i].parent_index < num_hmetrics) {
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_hmtx,
+                                                font->glyphs[i].parent_index * long_entry_size,
+                                                (unsigned char *) p, &long_entry_size);
+        }
+        else
+        {
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_hmtx,
+                                                (num_hmetrics - 1) * long_entry_size,
+                                                (unsigned char *) p, &short_entry_size);
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_hmtx,
+                                                (num_hmetrics - 1) * long_entry_size +
+                                                (font->glyphs[i].parent_index - num_hmetrics)
+                                                                          * short_entry_size,
+                                                (unsigned char *) (p+1), &short_entry_size);
+        }
+        font->base.widths[i] = be16_to_cpu (p[0]);
+    }
+
+    return font->status;
+}
+
+static int
+cairo_pdf_ft_font_write_loca_table (cairo_pdf_ft_font_t *font,
+				    unsigned long tag)
+{
+    int i;
+    tt_head_t header;
+    unsigned long size;
+
+    size = sizeof(tt_head_t);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_head, 0, (unsigned char*) &header, &size);
+
+    if (be16_to_cpu (header.index_to_loc_format) == 0) {
+	for (i = 0; i < font->base.num_glyphs + 1; i++)
+	    cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);
+    }
+    else {
+	for (i = 0; i < font->base.num_glyphs + 1; i++)
+	    cairo_pdf_ft_font_write_be32 (font, font->glyphs[i].location);
+    }
+
+    return font->status;
+}
+
+static int
+cairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,
+				    unsigned long tag)
+{
+    tt_maxp_t *maxp;
+    unsigned long size;
+
+    size = sizeof (tt_maxp_t);
+    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, (unsigned char *) maxp, &size);
+    maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
+    return font->status;
+}
+
+typedef struct table table_t;
+struct table {
+    unsigned long tag;
+    int (*write) (cairo_pdf_ft_font_t *font, unsigned long tag);
+};
+
+static const table_t truetype_tables[] = {
+    /* As we write out the glyf table we remap composite glyphs.
+     * Remapping composite glyphs will reference the sub glyphs the
+     * composite glyph is made up of.  That needs to be done first so
+     * we have all the glyphs in the subset before going further. */
+    { TT_TAG_glyf, cairo_pdf_ft_font_write_glyf_table },
+    { TT_TAG_cmap, cairo_pdf_ft_font_write_cmap_table },
+    { TT_TAG_cvt,  cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_fpgm, cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_head, cairo_pdf_ft_font_write_head_table },
+    { TT_TAG_hhea, cairo_pdf_ft_font_write_hhea_table },
+    { TT_TAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
+    { TT_TAG_loca, cairo_pdf_ft_font_write_loca_table },
+    { TT_TAG_maxp, cairo_pdf_ft_font_write_maxp_table },
+    { TT_TAG_name, cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_prep, cairo_pdf_ft_font_write_generic_table },
+};
+
+static cairo_status_t
+cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
+{
+    cairo_status_t status;
+    unsigned char *table_buffer;
+    size_t table_buffer_length;
+    unsigned short search_range, entry_selector, range_shift;
+    int num_tables;
+
+    num_tables = ARRAY_LENGTH (truetype_tables);
+    search_range = 1;
+    entry_selector = 0;
+    while (search_range * 2 <= num_tables) {
+	search_range *= 2;
+	entry_selector++;
+    }
+    search_range *= 16;
+    range_shift = num_tables * 16 - search_range;
+
+    cairo_pdf_ft_font_write_be32 (font, SFNT_VERSION);
+    cairo_pdf_ft_font_write_be16 (font, num_tables);
+    cairo_pdf_ft_font_write_be16 (font, search_range);
+    cairo_pdf_ft_font_write_be16 (font, entry_selector);
+    cairo_pdf_ft_font_write_be16 (font, range_shift);
+
+    /* Allocate space for the table directory. Each directory entry
+     * will be filled in by cairo_pdf_ft_font_update_entry() after
+     * the table is written. */
+    table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
+    status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,
+						      &table_buffer);
+    if (status)
+	return status;
+
+    return font->status;
+}
+
+static unsigned long
+cairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,
+				      unsigned long start, unsigned long end)
+{
+    unsigned long *padded_end;
+    unsigned long *p;
+    unsigned long checksum;
+    char *data;
+
+    checksum = 0;
+    data = _cairo_array_index (&font->output, 0);
+    p = (unsigned long *) (data + start);
+    padded_end = (unsigned long *) (data + ((end + 3) & ~3));
+    while (p < padded_end)
+	checksum += *p++;
+
+    return checksum;
+}
+
+static void
+cairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned long tag,
+			unsigned long start, unsigned long end)
+{
+    unsigned long *entry;
+
+    entry = _cairo_array_index (&font->output, 12 + 16 * index);
+    entry[0] = cpu_to_be32 (tag);
+    entry[1] = cpu_to_be32 (cairo_pdf_ft_font_calculate_checksum (font, start, end));
+    entry[2] = cpu_to_be32 (start);
+    entry[3] = cpu_to_be32 (end - start);
+}
+
+static cairo_status_t
+cairo_pdf_ft_font_generate (cairo_pdf_ft_font_t *font,
+			    const char **data, unsigned long *length,
+			    const unsigned long **string_offsets, unsigned long *num_strings)
+{
+    unsigned long start, end, next, checksum, *checksum_location;
+    int i;
+
+    if (cairo_pdf_ft_font_write_offset_table (font))
+	goto fail;
+
+    start = cairo_pdf_ft_font_align_output (font);
+    end = start;
+
+    end = 0;
+    for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
+	if (truetype_tables[i].write (font, truetype_tables[i].tag))
+	    goto fail;
+
+	end = _cairo_array_num_elements (&font->output);
+	next = cairo_pdf_ft_font_align_output (font);
+	cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,
+					start, end);
+        cairo_pdf_ft_font_check_boundary (font, next);
+	start = next;
+    }
+
+    checksum =
+	0xb1b0afba - cairo_pdf_ft_font_calculate_checksum (font, 0, end);
+    checksum_location = _cairo_array_index (&font->output, font->checksum_index);
+    *checksum_location = cpu_to_be32 (checksum);
+
+    *data = _cairo_array_index (&font->output, 0);
+    *length = _cairo_array_num_elements (&font->output);
+    *num_strings = _cairo_array_num_elements (&font->string_offsets);
+    if (*num_strings != 0)
+	*string_offsets = _cairo_array_index (&font->string_offsets, 0);
+    else
+	*string_offsets = NULL;
+
+ fail:
+    return font->status;
+}
+
+static int
+cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph)
+{
+    if (font->parent_to_subset[glyph] == 0) {
+	font->parent_to_subset[glyph] = font->base.num_glyphs;
+	font->glyphs[font->base.num_glyphs].parent_index = glyph;
+	font->base.num_glyphs++;
+    }
+
+    return font->parent_to_subset[glyph];
+}
+
+cairo_status_t
+_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
+			     cairo_scaled_font_subset_t	*font_subset)
+{
+    cairo_pdf_ft_font_t *font;
+    cairo_status_t status;
+    const char *data = NULL; /* squelch bogus compiler warning */
+    unsigned long length = 0; /* squelch bogus compiler warning */
+    unsigned long parent_glyph, offsets_length;
+    int i;
+    const unsigned long *string_offsets = NULL;
+    unsigned long num_strings = 0;
+
+    status = _cairo_pdf_ft_font_create (font_subset, &font);
+    if (status)
+	return status;
+
+    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
+	parent_glyph = font->scaled_font_subset->glyphs[i];
+	cairo_pdf_ft_font_use_glyph (font, parent_glyph);
+    }
+
+    status = cairo_pdf_ft_font_generate (font, &data, &length,
+					 &string_offsets, &num_strings);
+    if (status)
+	goto fail1;
+
+    truetype_subset->base_font = strdup (font->base.base_font);
+    if (truetype_subset->base_font == NULL)
+	goto fail1;
+
+    truetype_subset->widths = calloc (sizeof (int), font->base.num_glyphs);
+    if (truetype_subset->widths == NULL)
+	goto fail2;
+    for (i = 0; i < font->base.num_glyphs; i++)
+	truetype_subset->widths[i] = font->base.widths[i];
+
+    truetype_subset->x_min = font->base.x_min;
+    truetype_subset->y_min = font->base.y_min;
+    truetype_subset->x_max = font->base.x_max;
+    truetype_subset->y_max = font->base.y_max;
+    truetype_subset->ascent = font->base.ascent;
+    truetype_subset->descent = font->base.descent;
+
+    truetype_subset->data = malloc (length);
+    if (truetype_subset->data == NULL)
+	goto fail3;
+
+    memcpy (truetype_subset->data, data, length);
+    truetype_subset->data_length = length;
+
+    offsets_length = num_strings * sizeof (unsigned long);
+    truetype_subset->string_offsets = malloc (offsets_length);
+    if (truetype_subset->string_offsets == NULL)
+	goto fail4;
+
+    memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
+    truetype_subset->num_string_offsets = num_strings;
+
+    cairo_pdf_ft_font_destroy (font);
+
+    return CAIRO_STATUS_SUCCESS;
+
+ fail4:
+    free (truetype_subset->data);
+ fail3:
+    free (truetype_subset->widths);
+ fail2:
+    free (truetype_subset->base_font);
+ fail1:
+    cairo_pdf_ft_font_destroy (font);
+
+    return status;
+}
+
+void
+_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
+{
+    free (subset->base_font);
+    free (subset->widths);
+    free (subset->data);
+    free (subset->string_offsets);
+}
+
diff-tree a0989f427be87c60415963dd6822b3c5c3781691 (from c05dd48ac1afe0e4f3ec0c24797a9fbc3f98ce85)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Wed Aug 2 19:12:51 2006 -0400

    Remove freetype dependency for truetype subsetting code.
    
    Add a load_truetype_table function to cairo_scaled_font_backend_t and
    use it to load the truetype sfnt tables.  Implement this with freetype
    for the freetype font backend and use GetFontData for win32.  Atsui
    remains unimplemented, and still falls back to type3 fonts.

diff --git a/src/Makefile.am b/src/Makefile.am
index 59c3222..624f979 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,8 +1,10 @@
 font_subset_sources =				\
 	cairo-font-subset.c			\
-	cairo-type1-subset.c			\
 	cairo-scaled-font-subsets.c		\
 	cairo-scaled-font-subsets-private.h
+if CAIRO_HAS_FT_FONT
+font_subset_sources += cairo-type1-subset.c
+endif
 
 backend_pkgconfigs =
 
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 41a7f89..ff57eab 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -711,4 +711,5 @@ const cairo_scaled_font_backend_t cairo_
     _cairo_atsui_font_text_to_glyphs,
     NULL, /* ucs4_to_index */
     _cairo_atsui_font_old_show_glyphs,
+    NULL, /* load_truetype_table */
 };
diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c
index b64e4dd..b024684 100644
--- a/src/cairo-font-subset.c
+++ b/src/cairo-font-subset.c
@@ -34,17 +34,10 @@
  *	Adrian Johnson <ajohnson at redneon.com>
  */
 
+#include <string.h>
 #include "cairoint.h"
 #include "cairo-scaled-font-subsets-private.h"
 
-/* XXX: Eventually, we need to handle other font backends */
-#include "cairo-ft-private.h"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_OUTLINE_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_TRUETYPE_TABLES_H
 
 typedef struct ft_subset_glyph ft_subset_glyph_t;
 struct ft_subset_glyph {
@@ -57,8 +50,6 @@ typedef struct _cairo_ft_font {
     cairo_scaled_font_subset_t *scaled_font_subset;
 
     struct {
-	cairo_unscaled_font_t *unscaled_font;
-	unsigned int font_id;
 	char *base_font;
 	int num_glyphs;
 	int *widths;
@@ -67,7 +58,8 @@ typedef struct _cairo_ft_font {
     } base;
 
     ft_subset_glyph_t *glyphs;
-    FT_Face face;
+    const cairo_scaled_font_backend_t *backend;
+    int num_glyphs_in_face;
     int checksum_index;
     cairo_array_t output;
     cairo_array_t string_offsets;
@@ -78,6 +70,92 @@ typedef struct _cairo_ft_font {
 
 } cairo_pdf_ft_font_t;
 
+
+
+#define MAKE_TT_TAG(a, b, c, d)    (a<<24 | b<<16 | c<<8 | d)
+#define TT_TAG_cmap   MAKE_TT_TAG('c','m','a','p')
+#define TT_TAG_cvt    MAKE_TT_TAG('c','v','t',' ')
+#define TT_TAG_fpgm   MAKE_TT_TAG('f','p','g','m')
+#define TT_TAG_glyf   MAKE_TT_TAG('g','l','y','f')
+#define TT_TAG_head   MAKE_TT_TAG('h','e','a','d')
+#define TT_TAG_hhea   MAKE_TT_TAG('h','h','e','a')
+#define TT_TAG_hmtx   MAKE_TT_TAG('h','m','t','x')
+#define TT_TAG_loca   MAKE_TT_TAG('l','o','c','a')
+#define TT_TAG_maxp   MAKE_TT_TAG('m','a','x','p')
+#define TT_TAG_name   MAKE_TT_TAG('n','a','m','e')
+#define TT_TAG_prep   MAKE_TT_TAG('p','r','e','p')
+
+/* All tt_* structs are big-endian */
+typedef struct tt_head {
+    long           version;      /* FIXED */
+    long           revision;     /* FIXED */
+    unsigned long  checksum;
+    unsigned long  magic;
+    unsigned short flags;
+    unsigned short units_per_em;
+    long long      created;
+    long long      modified;
+    short          x_min;         /* FWORD */
+    short          y_min;         /* FWORD */
+    short          x_max;         /* FWORD */
+    short          y_max;         /* FWORD */
+    unsigned short mac_style;
+    unsigned short lowest_rec_pppem;
+    short          font_direction_hint;
+    short          index_to_loc_format;
+    short          glyph_data_format;
+} tt_head_t;
+
+typedef struct tt_hhea {
+    long           version;                /* FIXED */
+    short          ascender;               /* FWORD */
+    short          descender;              /* FWORD */
+    short          line_gap;               /* FWORD */
+    unsigned short advance_max_width;      /* UFWORD */
+    short          min_left_side_bearing;  /* FWORD */
+    short          min_right_side_bearing; /* FWORD */
+    short          x_max_extent;           /* FWORD */
+    short          caret_slope_rise;
+    short          caret_slope_run; 
+    short          reserved[5];
+    short          metric_data_format;
+    unsigned short num_hmetrics;
+} tt_hhea_t;
+
+typedef struct tt_maxp {
+    long           version;      /* FIXED */
+    unsigned short num_glyphs;
+    unsigned short max_points;
+    unsigned short max_contours;
+    unsigned short max_composite_points;
+    unsigned short max_composite_contours;
+    unsigned short max_zones;
+    unsigned short max_twilight_points;
+    unsigned short max_storage;
+    unsigned short max_function_defs;
+    unsigned short max_instruction_defs;
+    unsigned short max_stack_elements;
+    unsigned short max_size_of_instructions;
+    unsigned short max_component_elements;
+    unsigned short max_component_depth;
+} tt_maxp_t;
+
+typedef struct tt_name_record {
+    unsigned short platform;
+    unsigned short encoding;
+    unsigned short language;
+    unsigned short name;
+    unsigned short length;
+    unsigned short offset;
+} tt_name_record_t;
+
+typedef struct tt_name {
+    unsigned short   format;
+    unsigned short   num_records;
+    unsigned short   strings_offset;
+    tt_name_record_t records[1];
+} tt_name_t;
+
 static int
 cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);
 
@@ -125,68 +203,119 @@ static cairo_status_t
 _cairo_pdf_ft_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
 			   cairo_pdf_ft_font_t        **font_return)
 {
-    cairo_unscaled_font_t *unscaled_font;
-    cairo_ft_unscaled_font_t *ft_unscaled_font;
     cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
     cairo_pdf_ft_font_t *font;
-    FT_Face face;
+    const cairo_scaled_font_backend_t *backend;
+    tt_head_t head;
+    tt_hhea_t hhea;
+    tt_maxp_t maxp;
+    tt_name_t *name;
+    tt_name_record_t *record;
     unsigned long size;
     int i, j;
-
-    /* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */
-    if (!_cairo_scaled_font_is_ft (scaled_font_subset->scaled_font))
+    
+    backend = scaled_font_subset->scaled_font->backend;
+    if (!backend->load_truetype_table)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
-	return CAIRO_INT_STATUS_UNSUPPORTED;    
-
-    unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
+    size = sizeof (tt_head_t);
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_head, 0, (unsigned char *) &head,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
+    size = sizeof (tt_maxp_t);
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_maxp, 0, (unsigned char *) &maxp,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
-    if (face == NULL)
-	/* Assume out of memory */
-	return CAIRO_STATUS_NO_MEMORY;
+    size = sizeof (tt_hhea_t);
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_hhea, 0, (unsigned char *) &hhea,
+                                      &size) != CAIRO_STATUS_SUCCESS)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    /* We currently only support freetype truetype fonts. */
     size = 0;
-    if (!FT_IS_SFNT (face) ||
-	FT_Load_Sfnt_Table (face, TTAG_glyf, 0, NULL, &size) != 0)
+    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                      TT_TAG_name, 0, NULL,
+                                      &size) != CAIRO_STATUS_SUCCESS)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
+    name = malloc(size);
+    if (name == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+    backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                 TT_TAG_name, 0, (unsigned char *) name,
+                                 &size);
+
+    /* FIXME: Figure out how to determine if the font is vertical without
+     *  requiring freetype.
+     *
+     *  if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
+     *   return CAIRO_INT_STATUS_UNSUPPORTED;
+     */
 
     font = malloc (sizeof (cairo_pdf_ft_font_t));
     if (font == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	goto fail0;
 
+    font->backend = backend;
+    font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
     font->scaled_font_subset = scaled_font_subset;
-
-    font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
-
+    
     font->last_offset = 0;
     font->last_boundary = 0;
     _cairo_array_init (&font->output, sizeof (char));
     if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
 	goto fail1;
-
-    font->glyphs = calloc (face->num_glyphs + 1, sizeof (ft_subset_glyph_t));
+    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (ft_subset_glyph_t));
     if (font->glyphs == NULL)
 	goto fail2;
 
-    font->parent_to_subset = calloc (face->num_glyphs, sizeof (int));
+    font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
     if (font->parent_to_subset == NULL)
 	goto fail3;
 
     font->base.num_glyphs = 0;
-    font->base.x_min = face->bbox.xMin;
-    font->base.y_min = face->bbox.yMin;
-    font->base.x_max = face->bbox.xMax;
-    font->base.y_max = face->bbox.yMax;
-    font->base.ascent = face->ascender;
-    font->base.descent = face->descender;
-    font->base.base_font = strdup (face->family_name);
-    if (font->base.base_font == NULL)
-	goto fail4;
+    font->base.x_min = be16_to_cpu (head.x_min);
+    font->base.y_min = be16_to_cpu (head.y_min);
+    font->base.x_max = be16_to_cpu (head.x_max);
+    font->base.y_max = be16_to_cpu (head.y_max);
+    font->base.ascent = be16_to_cpu (hhea.ascender);
+    font->base.descent = be16_to_cpu (hhea.descender);
+
+
+    /* Extract the font name from the name table. At present this
+     * just looks for the Mac platform/Roman encoded font name. It
+     * should be extended to use any suitable font name in the
+     * name table. If the mac/roman font name is not found a
+     * CairoFont-x-y name is created.
+     */
+    font->base.base_font = NULL;
+    for (i = 0; i < be16_to_cpu(name->num_records); i++) {
+        record = &(name->records[i]);
+        if ((be16_to_cpu (record->platform) == 1) &&
+            (be16_to_cpu (record->encoding) == 0) &&
+            (be16_to_cpu (record->name) == 4)) { 
+            font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
+            if (font->base.base_font) {
+                strncpy(font->base.base_font,
+                        ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
+                        be16_to_cpu (record->length));
+                font->base.base_font[be16_to_cpu (record->length)] = 0;
+            }
+            break;
+        }
+    }
+
+    if (font->base.base_font == NULL) {
+        font->base.base_font = malloc (30);
+        if (font->base.base_font == NULL)
+            goto fail4; 
+        snprintf(font->base.base_font, 30, "CairoFont-%u-%u",
+                 scaled_font_subset->font_id,
+                 scaled_font_subset->subset_id);
+    }
 
     for (i = 0, j = 0; font->base.base_font[j]; j++) {
 	if (font->base.base_font[j] == ' ')
@@ -195,7 +324,7 @@ _cairo_pdf_ft_font_create (cairo_scaled_
     }
     font->base.base_font[i] = '\0';
 
-    font->base.widths = calloc (face->num_glyphs, sizeof (int));
+    font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
     if (font->base.widths == NULL)
 	goto fail5;
 
@@ -203,8 +332,6 @@ _cairo_pdf_ft_font_create (cairo_scaled_
     if (_cairo_array_grow_by (&font->string_offsets, 10) != CAIRO_STATUS_SUCCESS)
 	goto fail6;
 
-    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
-
     font->status = CAIRO_STATUS_SUCCESS;
 
     *font_return = font;
@@ -223,14 +350,14 @@ _cairo_pdf_ft_font_create (cairo_scaled_
     _cairo_array_fini (&font->output);
  fail1:
     free (font);
-
+ fail0:
+    free (name);
     return status;
 }
 
 static void
 cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font)
 {
-    _cairo_unscaled_font_destroy (font->base.unscaled_font);
     free (font->base.base_font);
     free (font->parent_to_subset);
     free (font->glyphs);
@@ -345,11 +472,12 @@ cairo_pdf_ft_font_write_generic_table (c
     unsigned long size;
 
     size = 0;
-    FT_Load_Sfnt_Table (font->face, tag, 0, NULL, &size);
+    font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
+                                        tag, 0, NULL, &size);
     status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
     /* XXX: Need to check status here. */
-    FT_Load_Sfnt_Table (font->face, tag, 0, buffer, &size);
-
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, buffer, &size);
     return 0;
 }
 
@@ -414,7 +542,7 @@ cairo_pdf_ft_font_write_glyf_table (cair
 {
     cairo_status_t status;
     unsigned long start_offset, index, size, next;
-    TT_Header *header;
+    tt_head_t header;
     unsigned long begin, end;
     unsigned char *buffer;
     int i;
@@ -424,23 +552,27 @@ cairo_pdf_ft_font_write_glyf_table (cair
 	unsigned long *long_offsets;
     } u;
 
-    header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
-    if (header->Index_To_Loc_Format == 0)
-	size = sizeof (short) * (font->face->num_glyphs + 1);
+    size = sizeof (tt_head_t);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_head, 0, (unsigned char*) &header, &size);
+    
+    if (be16_to_cpu (header.index_to_loc_format) == 0)
+	size = sizeof (short) * (font->num_glyphs_in_face + 1);
     else
-	size = sizeof (long) * (font->face->num_glyphs + 1);
+	size = sizeof (long) * (font->num_glyphs_in_face + 1);
 
     u.bytes = malloc (size);
     if (u.bytes == NULL) {
 	font->status = CAIRO_STATUS_NO_MEMORY;
 	return font->status;
     }
-    FT_Load_Sfnt_Table (font->face, TTAG_loca, 0, u.bytes, &size);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_loca, 0, u.bytes, &size);
 
     start_offset = _cairo_array_num_elements (&font->output);
     for (i = 0; i < font->base.num_glyphs; i++) {
 	index = font->glyphs[i].parent_index;
-	if (header->Index_To_Loc_Format == 0) {
+	if (be16_to_cpu (header.index_to_loc_format) == 0) {
 	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
 	    end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
 	}
@@ -459,7 +591,8 @@ cairo_pdf_ft_font_write_glyf_table (cair
 	if (status)
 	    break;
         if (size != 0) {
-            FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_glyf, begin, buffer, &size);
             cairo_pdf_ft_font_remap_composite_glyph (font, buffer);
         }
     }
@@ -474,70 +607,31 @@ cairo_pdf_ft_font_write_glyf_table (cair
 
 static int
 cairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,
-				    unsigned long tag)
+                                      unsigned long tag)
 {
-    TT_Header *head;
-
-    head = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
-
-    cairo_pdf_ft_font_write_be32 (font, head->Table_Version);
-    cairo_pdf_ft_font_write_be32 (font, head->Font_Revision);
-
-    font->checksum_index = _cairo_array_num_elements (&font->output);
-    cairo_pdf_ft_font_write_be32 (font, 0);
-    cairo_pdf_ft_font_write_be32 (font, head->Magic_Number);
-
-    cairo_pdf_ft_font_write_be16 (font, head->Flags);
-    cairo_pdf_ft_font_write_be16 (font, head->Units_Per_EM);
-
-    cairo_pdf_ft_font_write_be32 (font, head->Created[0]);
-    cairo_pdf_ft_font_write_be32 (font, head->Created[1]);
-    cairo_pdf_ft_font_write_be32 (font, head->Modified[0]);
-    cairo_pdf_ft_font_write_be32 (font, head->Modified[1]);
-
-    cairo_pdf_ft_font_write_be16 (font, head->xMin);
-    cairo_pdf_ft_font_write_be16 (font, head->yMin);
-    cairo_pdf_ft_font_write_be16 (font, head->xMax);
-    cairo_pdf_ft_font_write_be16 (font, head->yMax);
-
-    cairo_pdf_ft_font_write_be16 (font, head->Mac_Style);
-    cairo_pdf_ft_font_write_be16 (font, head->Lowest_Rec_PPEM);
-
-    cairo_pdf_ft_font_write_be16 (font, head->Font_Direction);
-    cairo_pdf_ft_font_write_be16 (font, head->Index_To_Loc_Format);
-    cairo_pdf_ft_font_write_be16 (font, head->Glyph_Data_Format);
+    unsigned char *buffer;
+    unsigned long size;
 
+    size = 0;
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, NULL, &size);
+    font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
+    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
+    font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
+                                        tag, 0, buffer, &size);
     return font->status;
 }
 
 static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag)
 {
-    TT_HoriHeader *hhea;
-
-    hhea = FT_Get_Sfnt_Table (font->face, ft_sfnt_hhea);
-
-    cairo_pdf_ft_font_write_be32 (font, hhea->Version);
-    cairo_pdf_ft_font_write_be16 (font, hhea->Ascender);
-    cairo_pdf_ft_font_write_be16 (font, hhea->Descender);
-    cairo_pdf_ft_font_write_be16 (font, hhea->Line_Gap);
-
-    cairo_pdf_ft_font_write_be16 (font, hhea->advance_Width_Max);
-
-    cairo_pdf_ft_font_write_be16 (font, hhea->min_Left_Side_Bearing);
-    cairo_pdf_ft_font_write_be16 (font, hhea->min_Right_Side_Bearing);
-    cairo_pdf_ft_font_write_be16 (font, hhea->xMax_Extent);
-    cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Rise);
-    cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Run);
-    cairo_pdf_ft_font_write_be16 (font, hhea->caret_Offset);
-
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 0);
-    cairo_pdf_ft_font_write_be16 (font, 0);
-
-    cairo_pdf_ft_font_write_be16 (font, hhea->metric_Data_Format);
-    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);
+    tt_hhea_t *hhea;
+    unsigned long size;
 
+    size = sizeof (tt_hhea_t);
+    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, (unsigned char *) hhea, &size);
+    hhea->num_hmetrics = cpu_to_be16 (font->base.num_glyphs);
     return font->status;
 }
 
@@ -546,19 +640,44 @@ cairo_pdf_ft_font_write_hmtx_table (cair
 				    unsigned long tag)
 {
     cairo_status_t status;
-    unsigned long entry_size;
+    unsigned long size;
+    unsigned long long_entry_size;
+    unsigned long short_entry_size;
     short *p;
     int i;
+    tt_hhea_t hhea;
+    int num_hmetrics;
+
+    size = sizeof (tt_hhea_t);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_hhea, 0, (unsigned char*) &hhea, &size);
+    num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
 
     for (i = 0; i < font->base.num_glyphs; i++) {
-	entry_size = 2 * sizeof (short);
-	status = cairo_pdf_ft_font_allocate_write_buffer (font, entry_size,
+        long_entry_size = 2 * sizeof (short);
+        short_entry_size = sizeof (short);
+        status = cairo_pdf_ft_font_allocate_write_buffer (font, long_entry_size,
 							  (unsigned char **) &p);
-	/* XXX: Need to check status here. */
-	FT_Load_Sfnt_Table (font->face, TTAG_hmtx,
-			    font->glyphs[i].parent_index * entry_size,
-			    (FT_Byte *) p, &entry_size);
-	font->base.widths[i] = be16_to_cpu (p[0]);
+        if (font->glyphs[i].parent_index < num_hmetrics) {
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_hmtx,
+                                                font->glyphs[i].parent_index * long_entry_size,
+                                                (unsigned char *) p, &long_entry_size);
+        }
+        else
+        {
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_hmtx,
+                                                (num_hmetrics - 1) * long_entry_size,
+                                                (unsigned char *) p, &short_entry_size);
+            font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                TT_TAG_hmtx,
+                                                (num_hmetrics - 1) * long_entry_size +
+                                                (font->glyphs[i].parent_index - num_hmetrics)
+                                                                          * short_entry_size,
+                                                (unsigned char *) (p+1), &short_entry_size);
+        }
+        font->base.widths[i] = be16_to_cpu (p[0]);
     }
 
     return font->status;
@@ -569,11 +688,14 @@ cairo_pdf_ft_font_write_loca_table (cair
 				    unsigned long tag)
 {
     int i;
-    TT_Header *header;
+    tt_head_t header;
+    unsigned long size;
 
-    header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
+    size = sizeof(tt_head_t);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        TT_TAG_head, 0, (unsigned char*) &header, &size);
 
-    if (header->Index_To_Loc_Format == 0) {
+    if (be16_to_cpu (header.index_to_loc_format) == 0) {
 	for (i = 0; i < font->base.num_glyphs + 1; i++)
 	    cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);
     }
@@ -589,26 +711,14 @@ static int
 cairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,
 				    unsigned long tag)
 {
-    TT_MaxProfile *maxp;
-
-    maxp = FT_Get_Sfnt_Table (font->face, ft_sfnt_maxp);
-
-    cairo_pdf_ft_font_write_be32 (font, maxp->version);
-    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxPoints);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxContours);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositePoints);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositeContours);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxZones);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxTwilightPoints);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxStorage);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxFunctionDefs);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxInstructionDefs);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxStackElements);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxSizeOfInstructions);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentElements);
-    cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentDepth);
+    tt_maxp_t *maxp;
+    unsigned long size;
 
+    size = sizeof (tt_maxp_t);
+    font->status = cairo_pdf_ft_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
+    font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                        tag, 0, (unsigned char *) maxp, &size);
+    maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
     return font->status;
 }
 
@@ -623,17 +733,17 @@ static const table_t truetype_tables[] =
      * Remapping composite glyphs will reference the sub glyphs the
      * composite glyph is made up of.  That needs to be done first so
      * we have all the glyphs in the subset before going further. */
-    { TTAG_glyf, cairo_pdf_ft_font_write_glyf_table },
-    { TTAG_cmap, cairo_pdf_ft_font_write_cmap_table },
-    { TTAG_cvt,  cairo_pdf_ft_font_write_generic_table },
-    { TTAG_fpgm, cairo_pdf_ft_font_write_generic_table },
-    { TTAG_head, cairo_pdf_ft_font_write_head_table },
-    { TTAG_hhea, cairo_pdf_ft_font_write_hhea_table },
-    { TTAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
-    { TTAG_loca, cairo_pdf_ft_font_write_loca_table },
-    { TTAG_maxp, cairo_pdf_ft_font_write_maxp_table },
-    { TTAG_name, cairo_pdf_ft_font_write_generic_table },
-    { TTAG_prep, cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_glyf, cairo_pdf_ft_font_write_glyf_table },
+    { TT_TAG_cmap, cairo_pdf_ft_font_write_cmap_table },
+    { TT_TAG_cvt,  cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_fpgm, cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_head, cairo_pdf_ft_font_write_head_table },
+    { TT_TAG_hhea, cairo_pdf_ft_font_write_hhea_table },
+    { TT_TAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
+    { TT_TAG_loca, cairo_pdf_ft_font_write_loca_table },
+    { TT_TAG_maxp, cairo_pdf_ft_font_write_maxp_table },
+    { TT_TAG_name, cairo_pdf_ft_font_write_generic_table },
+    { TT_TAG_prep, cairo_pdf_ft_font_write_generic_table },
 };
 
 static cairo_status_t
@@ -661,9 +771,9 @@ cairo_pdf_ft_font_write_offset_table (ca
     cairo_pdf_ft_font_write_be16 (font, entry_selector);
     cairo_pdf_ft_font_write_be16 (font, range_shift);
 
-    /* XXX: Why are we allocating a table here and then ignoring the
-     * returned buffer? This should result in garbage in the output
-     * file, correct? Is this just unfinished code? -cworth. */
+    /* Allocate space for the table directory. Each directory entry
+     * will be filled in by cairo_pdf_ft_font_update_entry() after
+     * the table is written. */
     table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
     status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,
 						      &table_buffer);
@@ -675,7 +785,7 @@ cairo_pdf_ft_font_write_offset_table (ca
 
 static unsigned long
 cairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,
-			   unsigned long start, unsigned long end)
+				      unsigned long start, unsigned long end)
 {
     unsigned long *padded_end;
     unsigned long *p;
@@ -706,23 +816,13 @@ cairo_pdf_ft_font_update_entry (cairo_pd
 }
 
 static cairo_status_t
-cairo_pdf_ft_font_generate (void *abstract_font,
+cairo_pdf_ft_font_generate (cairo_pdf_ft_font_t *font,
 			    const char **data, unsigned long *length,
-                            const unsigned long **string_offsets, unsigned long *num_strings)
+			    const unsigned long **string_offsets, unsigned long *num_strings)
 {
-    cairo_ft_unscaled_font_t *ft_unscaled_font;
-    cairo_pdf_ft_font_t *font = abstract_font;
     unsigned long start, end, next, checksum, *checksum_location;
     int i;
 
-    /* XXX: It would be cleaner to do something besides this cast
-     * here. Perhaps cairo_pdf_ft_font_t should just have the
-     * cairo_ft_unscaled_font_t rather than having the generic
-     * cairo_unscaled_font_t in the base class? */
-    ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
-
-    font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
-
     if (cairo_pdf_ft_font_write_offset_table (font))
 	goto fail;
 
@@ -756,9 +856,6 @@ cairo_pdf_ft_font_generate (void *abstra
 	*string_offsets = NULL;
 
  fail:
-    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
-    font->face = NULL;
-
     return font->status;
 }
 
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 18aa68c..002c322 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -48,6 +48,7 @@
 #include FT_FREETYPE_H
 #include FT_OUTLINE_H
 #include FT_IMAGE_H
+#include FT_TRUETYPE_TABLES_H
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 #include FT_SYNTHESIS_H
 #endif
@@ -1990,6 +1991,30 @@ _cairo_ft_show_glyphs (void		       *abs
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
 
+static cairo_int_status_t
+_cairo_ft_load_truetype_table (void	       *abstract_font,
+                              unsigned long     tag,
+                              long              offset,
+                              unsigned char    *buffer,
+                              unsigned long    *length)
+{
+    cairo_ft_scaled_font_t *scaled_font = abstract_font;
+    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
+    FT_Face face;
+    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
+
+    face = _cairo_ft_unscaled_font_lock_face (unscaled);
+    if (!face)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    if (FT_IS_SFNT (face) &&
+	FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
+        status = CAIRO_STATUS_SUCCESS;
+
+    _cairo_ft_unscaled_font_unlock_face (unscaled);
+    return status;
+}
+
 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
     CAIRO_FONT_TYPE_FT,
     _cairo_ft_scaled_font_create_toy,
@@ -1998,6 +2023,7 @@ const cairo_scaled_font_backend_t cairo_
     NULL,			/* text_to_glyphs */
     _cairo_ft_ucs4_to_index,
     _cairo_ft_show_glyphs,
+    _cairo_ft_load_truetype_table,
 };
 
 /* cairo_ft_font_face_t */
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index aaf71c7..ef5126e 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -40,7 +40,6 @@
 #include "cairo-pdf.h"
 #include "cairo-pdf-test.h"
 #include "cairo-scaled-font-subsets-private.h"
-#include "cairo-ft-private.h"
 #include "cairo-paginated-surface-private.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-output-stream-private.h"
@@ -1586,6 +1585,7 @@ _cairo_pdf_surface_write_pages (cairo_pd
 				 "endobj\r\n");
 }
 
+#if CAIRO_HAS_FT_FONT
 static cairo_status_t
 _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t		*surface,
 					   cairo_scaled_font_subset_t	*font_subset)
@@ -1694,6 +1694,7 @@ _cairo_pdf_surface_emit_type1_font_subse
 
     return CAIRO_STATUS_SUCCESS;
 }
+#endif
 
 static cairo_status_t
 _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t		*surface,
@@ -2026,9 +2027,11 @@ _cairo_pdf_surface_emit_font_subset (cai
     cairo_pdf_surface_t *surface = closure;
     cairo_status_t status;
 
+#if CAIRO_HAS_FT_FONT
     status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return;
+#endif
 
     status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 59d8db0..6467501 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -43,9 +43,9 @@
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-paginated-surface-private.h"
 #include "cairo-meta-surface-private.h"
-#include "cairo-ft-private.h"
 #include "cairo-output-stream-private.h"
 
+#include <ctype.h>
 #include <time.h>
 #include <zlib.h>
 
@@ -385,6 +385,7 @@ _cairo_ps_surface_emit_header (cairo_ps_
     }
 }
 
+#if CAIRO_HAS_FT_FONT
 static cairo_status_t
 _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t		*surface,
 					  cairo_scaled_font_subset_t	*font_subset)
@@ -414,6 +415,7 @@ _cairo_ps_surface_emit_type1_font_subset
 
     return CAIRO_STATUS_SUCCESS;
 }
+#endif
 
 static cairo_status_t
 _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t		*surface,
@@ -674,9 +676,11 @@ _cairo_ps_surface_emit_font_subset (cair
     cairo_ps_surface_t *surface = closure;
     cairo_status_t status;
 
+#if CAIRO_HAS_FT_FONT
     status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return;
+#endif
 
     status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index b391506..efb8ae4 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -42,7 +42,6 @@
 #include "cairo-svg.h"
 #include "cairo-svg-test.h"
 #include "cairo-path-fixed-private.h"
-#include "cairo-ft-private.h"
 #include "cairo-meta-surface-private.h"
 #include "cairo-paginated-surface-private.h"
 #include "cairo-scaled-font-subsets-private.h"
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 39c9522..5ca5653 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1220,6 +1220,33 @@ _cairo_win32_scaled_font_show_glyphs (vo
     }
 }
 
+static cairo_int_status_t
+_cairo_win32_scaled_font_load_truetype_table (void	       *abstract_font,
+                                             unsigned long      tag,
+                                             long               offset,
+                                             unsigned char     *buffer,
+                                             unsigned long     *length)
+{
+    HDC hdc;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+
+    cairo_win32_scaled_font_t *scaled_font = abstract_font;
+    hdc = _get_global_font_dc ();
+    if (!hdc)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    tag = (tag&0x000000ff)<<24 | (tag&0x0000ff00)<<8 | (tag&0x00ff0000)>>8 | (tag&0xff000000)>>24;
+    status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
+
+    *length = GetFontData (hdc, tag, offset, buffer, *length);
+    if (*length == GDI_ERROR) {
+        status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_load_truetype_table:GetFontData");
+    }
+    _cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
+
+    return status;
+}
+
 static cairo_fixed_t
 _cairo_fixed_from_FIXED (FIXED f)
 {
@@ -1363,6 +1390,7 @@ const cairo_scaled_font_backend_t cairo_
     _cairo_win32_scaled_font_text_to_glyphs,
     NULL,			/* ucs4_to_index */
     _cairo_win32_scaled_font_show_glyphs,
+    _cairo_win32_scaled_font_load_truetype_table,
 };
 
 /* cairo_win32_font_face_t */
diff --git a/src/cairoint.h b/src/cairoint.h
index 4eb0c3c..447c1ac 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -574,6 +574,12 @@ struct _cairo_scaled_font_backend {
 			 const cairo_glyph_t	*glyphs,
 			 int			 num_glyphs);
 
+    cairo_int_status_t
+    (*load_truetype_table)(void		        *scaled_font,
+                           unsigned long         tag,
+                           long                  offset,
+                           unsigned char        *buffer,
+                           unsigned long        *length);
 };
 
 struct _cairo_font_face_backend {


More information about the cairo-commit mailing list