[cairo-commit] 2 commits - src/cairo-cff-subset.c src/cairo-pdf-surface.c src/cairo-scaled-font-subsets-private.h src/cairo-type1-fallback.c src/cairo-type1-subset.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Sun May 16 04:24:35 PDT 2010


 src/cairo-cff-subset.c                  |   38 ++++++++++++++++------------
 src/cairo-pdf-surface.c                 |   42 ++++++++++++++++----------------
 src/cairo-scaled-font-subsets-private.h |   12 ++++-----
 src/cairo-type1-fallback.c              |   18 ++++++-------
 src/cairo-type1-subset.c                |    6 ++--
 5 files changed, 61 insertions(+), 55 deletions(-)

New commits:
commit 562c323ae8689907d7a62a7c2f5c10fb8d055608
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun May 16 17:47:13 2010 +0930

    cff: Use correct glyph advance when subsetting cff fonts
    
    Previously the glyph advance in font units was used for the widths in
    the PDF font dictionary. This only works for cff fonts that use a
    [0.001 0 0 0.001 0 0] font matrix.

diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 1978bf0..a4a434f 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -118,6 +118,7 @@ typedef struct _cairo_cff_font {
     cairo_array_t        local_sub_index;
     int                  num_glyphs;
     cairo_bool_t         is_cid;
+    int  		 units_per_em;
 
     /* CID Font Data */
     int                 *fdselect;
@@ -1773,6 +1774,9 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
     font->y_max = (int16_t) be16_to_cpu (head.y_max);
     font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
     font->descent = (int16_t) be16_to_cpu (hhea.descender);
+    font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
+    if (font->units_per_em == 0)
+        font->units_per_em = 1000;
 
     font->font_name = NULL;
     status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
@@ -1956,20 +1960,20 @@ _cairo_cff_subset_init (cairo_cff_subset_t          *cff_subset,
 	cff_subset->font_name = NULL;
     }
 
-    cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
+    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
     if (unlikely (cff_subset->widths == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
-        cff_subset->widths[i] = font->widths[i];
+        cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
 
-    cff_subset->x_min = font->x_min;
-    cff_subset->y_min = font->y_min;
-    cff_subset->x_max = font->x_max;
-    cff_subset->y_max = font->y_max;
-    cff_subset->ascent = font->ascent;
-    cff_subset->descent = font->descent;
+    cff_subset->x_min = (double)font->x_min/font->units_per_em;
+    cff_subset->y_min = (double)font->y_min/font->units_per_em;
+    cff_subset->x_max = (double)font->x_max/font->units_per_em;
+    cff_subset->y_max = (double)font->y_max/font->units_per_em;
+    cff_subset->ascent = (double)font->ascent/font->units_per_em;
+    cff_subset->descent = (double)font->descent/font->units_per_em;
 
     cff_subset->data = malloc (length);
     if (unlikely (cff_subset->data == NULL)) {
@@ -2213,21 +2217,21 @@ _cairo_cff_fallback_init (cairo_cff_subset_t          *cff_subset,
 	goto fail2;
     }
 
-    cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
+    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
     if (unlikely (cff_subset->widths == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
 
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
-        cff_subset->widths[i] = type2_subset.widths[i];
-
-    cff_subset->x_min = type2_subset.x_min;
-    cff_subset->y_min = type2_subset.y_min;
-    cff_subset->x_max = type2_subset.x_max;
-    cff_subset->y_max = type2_subset.y_max;
-    cff_subset->ascent = type2_subset.y_max;
-    cff_subset->descent = type2_subset.y_min;
+        cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
+
+    cff_subset->x_min = (double)type2_subset.x_min/1000;
+    cff_subset->y_min = (double)type2_subset.y_min/1000;
+    cff_subset->x_max = (double)type2_subset.x_max/1000;
+    cff_subset->y_max = (double)type2_subset.y_max/1000;
+    cff_subset->ascent = (double)type2_subset.y_max/1000;
+    cff_subset->descent = (double)type2_subset.y_min/1000;
 
     cff_subset->data = malloc (length);
     if (unlikely (cff_subset->data == NULL)) {
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 038b94c..2fc0150 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3915,18 +3915,19 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t		*surface,
 				 "   /ItalicAngle 0\n"
 				 "   /Ascent %ld\n"
 				 "   /Descent %ld\n"
-				 "   /CapHeight 500\n"
+				 "   /CapHeight %ld\n"
 				 "   /StemV 80\n"
 				 "   /StemH 80\n"
 				 "   /FontFile3 %u 0 R\n"
 				 ">>\n"
 				 "endobj\n",
-				 subset->x_min,
-				 subset->y_min,
-				 subset->x_max,
-				 subset->y_max,
-				 subset->ascent,
-				 subset->descent,
+				 (long)(subset->x_min*PDF_UNITS_PER_EM),
+				 (long)(subset->y_min*PDF_UNITS_PER_EM),
+				 (long)(subset->x_max*PDF_UNITS_PER_EM),
+				 (long)(subset->y_max*PDF_UNITS_PER_EM),
+				 (long)(subset->ascent*PDF_UNITS_PER_EM),
+				 (long)(subset->descent*PDF_UNITS_PER_EM),
+				 (long)(subset->y_max*PDF_UNITS_PER_EM),
 				 stream.id);
 
     cidfont_dict = _cairo_pdf_surface_new_object (surface);
@@ -3952,8 +3953,8 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t		*surface,
 
     for (i = 0; i < font_subset->num_glyphs; i++)
 	_cairo_output_stream_printf (surface->output,
-				     " %d",
-				     subset->widths[i]);
+				     " %ld",
+                                     (long)(subset->widths[i]*PDF_UNITS_PER_EM));
 
     _cairo_output_stream_printf (surface->output,
                                  " ]]\n"
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 35c1e71..b165d9a 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -334,9 +334,9 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
 typedef struct _cairo_cff_subset {
     char *font_name;
     char *ps_name;
-    int *widths;
-    long x_min, y_min, x_max, y_max;
-    long ascent, descent;
+    double *widths;
+    double x_min, y_min, x_max, y_max;
+    double ascent, descent;
     char *data;
     unsigned long data_length;
 } cairo_cff_subset_t;
commit edcefa87ed0a8ff59b54ef9251182ce68f9158ba
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Wed May 12 23:12:55 2010 +0930

    type1: Use correct glyph advance when subsetting type 1 fonts
    
    Previously the glyph advance in font units was used for the widths in
    the PDF font dictionary. This only works for Type 1 fonts that use a
    [0.001 0 0 0.001 0 0] font matrix.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=28061

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 091ed58..038b94c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3849,6 +3849,8 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t		*surface,
     return _cairo_pdf_surface_close_stream (surface);
 }
 
+#define PDF_UNITS_PER_EM 1000
+
 static cairo_status_t
 _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t		*surface,
                                   cairo_scaled_font_subset_t	*font_subset,
@@ -4088,7 +4090,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
 				 "   /ItalicAngle 0\n"
 				 "   /Ascent %ld\n"
 				 "   /Descent %ld\n"
-				 "   /CapHeight 500\n"
+				 "   /CapHeight %ld\n"
 				 "   /StemV 80\n"
 				 "   /StemH 80\n"
 				 "   /FontFile %u 0 R\n"
@@ -4097,12 +4099,13 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
 				 descriptor.id,
 				 tag,
 				 subset->base_font,
-				 subset->x_min,
-				 subset->y_min,
-				 subset->x_max,
-				 subset->y_max,
-				 subset->ascent,
-				 subset->descent,
+				 (long)(subset->x_min*PDF_UNITS_PER_EM),
+				 (long)(subset->y_min*PDF_UNITS_PER_EM),
+				 (long)(subset->x_max*PDF_UNITS_PER_EM),
+				 (long)(subset->y_max*PDF_UNITS_PER_EM),
+				 (long)(subset->ascent*PDF_UNITS_PER_EM),
+				 (long)(subset->descent*PDF_UNITS_PER_EM),
+				 (long)(subset->y_max*PDF_UNITS_PER_EM),
 				 stream.id);
 
     _cairo_pdf_surface_update_object (surface, subset_resource);
@@ -4123,8 +4126,8 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
 
     for (i = 0; i < font_subset->num_glyphs; i++)
 	_cairo_output_stream_printf (surface->output,
-				     " %d",
-				     subset->widths[i]);
+				     " %ld",
+                                     (long)(subset->widths[i]*PDF_UNITS_PER_EM));
 
     _cairo_output_stream_printf (surface->output,
 				 " ]\n");
@@ -4186,8 +4189,6 @@ _cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t	*surface,
     return status;
 }
 
-#define PDF_UNITS_PER_EM 1000
-
 static cairo_status_t
 _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t		*surface,
 					      cairo_scaled_font_subset_t	*font_subset)
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 9e12a91..35c1e71 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -451,9 +451,9 @@ _cairo_truetype_subset_fini (cairo_truetype_subset_t *truetype_subset);
 
 typedef struct _cairo_type1_subset {
     char *base_font;
-    int *widths;
-    long x_min, y_min, x_max, y_max;
-    long ascent, descent;
+    double *widths;
+    double x_min, y_min, x_max, y_max;
+    double ascent, descent;
     char *data;
     unsigned long header_length;
     unsigned long data_length;
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 7894f7e..b93c423 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -727,20 +727,20 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t	*type1_subset,
         goto fail1;
     }
 
-    type1_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
+    type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
     if (unlikely (type1_subset->widths == NULL)) {
         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail2;
     }
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
-	type1_subset->widths[i] = font->widths[i];
-
-    type1_subset->x_min   = (int) font->x_min;
-    type1_subset->y_min   = (int) font->y_min;
-    type1_subset->x_max   = (int) font->x_max;
-    type1_subset->y_max   = (int) font->y_max;
-    type1_subset->ascent  = (int) font->y_max;
-    type1_subset->descent = (int) font->y_min;
+	type1_subset->widths[i] = (double)font->widths[i]/1000;
+
+    type1_subset->x_min   = (double)font->x_min/1000;
+    type1_subset->y_min   = (double)font->y_min/1000;
+    type1_subset->x_max   = (double)font->x_max/1000;
+    type1_subset->y_max   = (double)font->y_max/1000;
+    type1_subset->ascent  = (double)font->y_max/1000;
+    type1_subset->descent = (double)font->y_min/1000;
 
     length = font->header_size + font->data_size +
 	font->trailer_size;
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index 3757fff..d92c860 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -83,7 +83,7 @@ typedef struct _cairo_type1_font_subset {
 
     struct {
 	int subset_index;
-	int width;
+	double width;
 	char *name;
     } *glyphs;
 
@@ -566,7 +566,7 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 
-	font->glyphs[i].width = font->face->glyph->metrics.horiAdvance;
+	font->glyphs[i].width = font->face->glyph->linearHoriAdvance / 65536.0; /* 16.16 format */
 
 	error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
 	if (error != FT_Err_Ok) {
@@ -1346,7 +1346,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t		*type1_subset,
     if (unlikely (type1_subset->base_font == NULL))
 	goto fail1;
 
-    type1_subset->widths = calloc (sizeof (int), font.num_glyphs);
+    type1_subset->widths = calloc (sizeof (double), font.num_glyphs);
     if (unlikely (type1_subset->widths == NULL))
 	goto fail2;
     for (i = 0; i < font.base.num_glyphs; i++) {


More information about the cairo-commit mailing list