[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