[cairo-commit] 2 commits - src/cairo-font-subset.c src/cairo-font-subset-private.h src/cairo-ps-surface.c src/cairo-scaled-font-subsets-private.h src/Makefile.am

Kristian Høgsberg krh at kemper.freedesktop.org
Wed Aug 2 12:19:21 PDT 2006


 src/Makefile.am                         |    1 
 src/cairo-font-subset-private.h         |   67 --------------------------------
 src/cairo-font-subset.c                 |   60 +++++++++++++++++++++++++---
 src/cairo-ps-surface.c                  |   27 +++++++++---
 src/cairo-scaled-font-subsets-private.h |    2 
 5 files changed, 75 insertions(+), 82 deletions(-)

New commits:
diff-tree 0da4b9319f53379e0ae61b90337f49bd0f0fc9c5 (from 067d97eb1793a6b0d0dddfbd0b54117844511a94)
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Aug 2 15:18:56 2006 -0400

    Drop unused src/cairo-font-subset-private.h.

diff --git a/src/Makefile.am b/src/Makefile.am
index f490607..59c3222 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,5 @@
 font_subset_sources =				\
 	cairo-font-subset.c			\
-	cairo-font-subset-private.h		\
 	cairo-type1-subset.c			\
 	cairo-scaled-font-subsets.c		\
 	cairo-scaled-font-subsets-private.h
diff --git a/src/cairo-font-subset-private.h b/src/cairo-font-subset-private.h
deleted file mode 100644
index b423ccc..0000000
--- a/src/cairo-font-subset-private.h
+++ /dev/null
@@ -1,68 +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>
- */
-
-#include "cairoint.h"
-
-#ifndef CAIRO_FONT_SUBSET_PRIVATE_H
-#define CAIRO_FONT_SUBSET_PRIVATE_H
-
-typedef struct cairo_font_subset_backend cairo_font_subset_backend_t;
-typedef struct cairo_font_subset cairo_font_subset_t;
-struct cairo_font_subset {
-    cairo_font_subset_backend_t *backend;
-    cairo_unscaled_font_t *unscaled_font;
-    unsigned int font_id;
-    char *base_font;
-    int num_glyphs;
-    int *widths;
-    long x_min, y_min, x_max, y_max;
-    long ascent, descent;
-};
-
-cairo_private int
-_cairo_font_subset_use_glyph (cairo_font_subset_t *font, int glyph);
-
-cairo_private cairo_status_t
-_cairo_font_subset_generate (cairo_font_subset_t *font,
-			     const char **data, unsigned long *length,
-                             const unsigned long **string_offsets, unsigned long *num_strings);
-
-cairo_private void
-_cairo_font_subset_destroy (cairo_font_subset_t *font);
-
-cairo_private cairo_font_subset_t *
-_cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font);
-
-#endif /* CAIRO_FONT_SUBSET_PRIVATE_H */
diff-tree 067d97eb1793a6b0d0dddfbd0b54117844511a94 (from 226178539ad72ffa414925e094297e12c566083d)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Wed Aug 2 15:17:09 2006 -0400

    This patch fixes the problem where the postscript output
    does not print when the size of the embedded truetype font
    exceeds 64k.

diff --git a/src/cairo-font-subset-private.h b/src/cairo-font-subset-private.h
index 4b9235b..b423ccc 100644
--- a/src/cairo-font-subset-private.h
+++ b/src/cairo-font-subset-private.h
@@ -56,7 +56,8 @@ _cairo_font_subset_use_glyph (cairo_font
 
 cairo_private cairo_status_t
 _cairo_font_subset_generate (cairo_font_subset_t *font,
-			    const char **data, unsigned long *length);
+			     const char **data, unsigned long *length,
+                             const unsigned long **string_offsets, unsigned long *num_strings);
 
 cairo_private void
 _cairo_font_subset_destroy (cairo_font_subset_t *font);
diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c
index dc21d14..b64e4dd 100644
--- a/src/cairo-font-subset.c
+++ b/src/cairo-font-subset.c
@@ -31,6 +31,7 @@
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh at redhat.com>
+ *	Adrian Johnson <ajohnson at redneon.com>
  */
 
 #include "cairoint.h"
@@ -69,6 +70,9 @@ typedef struct _cairo_ft_font {
     FT_Face 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;
 
@@ -80,6 +84,7 @@ cairo_pdf_ft_font_use_glyph (cairo_pdf_f
 #define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
 
 #define SFNT_VERSION			0x00010000
+#define SFNT_STRING_MAX_LENGTH  65535
 
 #ifdef WORDS_BIGENDIAN
 
@@ -158,6 +163,8 @@ _cairo_pdf_ft_font_create (cairo_scaled_
 
     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;
@@ -192,6 +199,10 @@ _cairo_pdf_ft_font_create (cairo_scaled_
     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;
+
     _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
 
     font->status = CAIRO_STATUS_SUCCESS;
@@ -200,6 +211,8 @@ _cairo_pdf_ft_font_create (cairo_scaled_
 
     return CAIRO_STATUS_SUCCESS;
 
+ fail6:
+    free (font->base.widths);
  fail5:
     free (font->base.base_font);
  fail4:
@@ -222,6 +235,7 @@ cairo_pdf_ft_font_destroy (cairo_pdf_ft_
     free (font->parent_to_subset);
     free (font->glyphs);
     _cairo_array_fini (&font->output);
+    _cairo_array_fini (&font->string_offsets);
     free (font);
 }
 
@@ -287,6 +301,16 @@ cairo_pdf_ft_font_align_output (cairo_pd
     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)
 {
@@ -389,7 +413,7 @@ cairo_pdf_ft_font_write_glyf_table (cair
 				    unsigned long tag)
 {
     cairo_status_t status;
-    unsigned long start_offset, index, size;
+    unsigned long start_offset, index, size, next;
     TT_Header *header;
     unsigned long begin, end;
     unsigned char *buffer;
@@ -427,8 +451,10 @@ cairo_pdf_ft_font_write_glyf_table (cair
 
 	size = end - begin;
 
-	font->glyphs[i].location =
-	    cairo_pdf_ft_font_align_output (font) - start_offset;
+        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;
@@ -681,7 +707,8 @@ cairo_pdf_ft_font_update_entry (cairo_pd
 
 static cairo_status_t
 cairo_pdf_ft_font_generate (void *abstract_font,
-			    const char **data, unsigned long *length)
+			    const char **data, unsigned long *length,
+                            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;
@@ -711,6 +738,7 @@ cairo_pdf_ft_font_generate (void *abstra
 	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;
     }
 
@@ -721,6 +749,11 @@ cairo_pdf_ft_font_generate (void *abstra
 
     *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:
     _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
@@ -748,8 +781,11 @@ _cairo_truetype_subset_init (cairo_truet
     cairo_pdf_ft_font_t *font;
     cairo_status_t status;
     const char *data = NULL; /* squelch bogus compiler warning */
-    unsigned long parent_glyph, length = 0; /* 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)
@@ -760,7 +796,8 @@ _cairo_truetype_subset_init (cairo_truet
 	cairo_pdf_ft_font_use_glyph (font, parent_glyph);
     }
 
-    status = cairo_pdf_ft_font_generate (font, &data, &length);
+    status = cairo_pdf_ft_font_generate (font, &data, &length,
+					 &string_offsets, &num_strings);
     if (status)
 	goto fail1;
 
@@ -788,10 +825,20 @@ _cairo_truetype_subset_init (cairo_truet
     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:
@@ -808,5 +855,6 @@ _cairo_truetype_subset_fini (cairo_truet
     free (subset->base_font);
     free (subset->widths);
     free (subset->data);
+    free (subset->string_offsets);
 }
 
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 3856aa2..59d8db0 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -424,6 +424,7 @@ _cairo_ps_surface_emit_truetype_font_sub
     cairo_truetype_subset_t subset;
     cairo_status_t status;
     int i;
+    unsigned int begin, end;
 
     status = _cairo_truetype_subset_init (&subset, font_subset);
     if (status)
@@ -464,17 +465,27 @@ _cairo_ps_surface_emit_truetype_font_sub
     _cairo_output_stream_printf (surface->final_stream,
 				 "end readonly def\n");
 
-    /* FIXME: We need to break up fonts bigger than 64k so we don't
-     * exceed string size limitation.  At glyph boundaries.  Stupid
-     * postscript. */
     _cairo_output_stream_printf (surface->final_stream,
-				 "/sfnts [<");
-
-    _cairo_output_stream_write_hex_string (surface->final_stream,
-					   subset.data, subset.data_length);
+				 "/sfnts [\n");
+    begin = 0;
+    end = 0;
+    for (i = 0; i < subset.num_string_offsets; i++) {
+        end = subset.string_offsets[i];
+        _cairo_output_stream_printf (surface->final_stream,"<");
+        _cairo_output_stream_write_hex_string (surface->final_stream,
+                                               subset.data + begin, end - begin);
+        _cairo_output_stream_printf (surface->final_stream,"00>\n");
+        begin = end;
+    } 
+    if (subset.data_length > end) {
+        _cairo_output_stream_printf (surface->final_stream,"<");
+        _cairo_output_stream_write_hex_string (surface->final_stream,
+                                               subset.data + end, subset.data_length - end);
+        _cairo_output_stream_printf (surface->final_stream,"00>\n");
+    }
 
     _cairo_output_stream_printf (surface->final_stream,
-				 ">] def\n"
+				 "] def\n"
 				 "FontName currentdict end definefont pop\n");
 
     _cairo_truetype_subset_fini (&subset);
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index facbed8..08c8996 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -187,6 +187,8 @@ typedef struct _cairo_truetype_subset {
     long ascent, descent;
     char *data;
     unsigned long data_length;
+    unsigned long *string_offsets;
+    unsigned long num_string_offsets;
 } cairo_truetype_subset_t;
 
 /**


More information about the cairo-commit mailing list