diff --git a/ROADMAP b/ROADMAP index 9120f7afa..65a45db55 100644 --- a/ROADMAP +++ b/ROADMAP @@ -51,24 +51,26 @@ cairo-1.4 (October 2006): Better performance cairo 1.2.0 essential features We don't expect to release without these being complete. ======================================================== - PDF backend +✓PDF backend ✓1. Mark PDF backend as supported ✓a. Incorporate into test suite ✓b. Correct output for the entire test suite - 2. Reasonable, native output for common uses + ✓2. Reasonable, native output for common uses ✓a. Switch to using cairo_paginated_surface_t ✓b. Opaque text and images are all native ✓c. Translucent objects (using OVER) are also native - d. Text output uses PDF font features + ✓d. Text output uses PDF font features (type 3) + + Bug fixes with API implications + cairo_{ps,pdf}_surface_set_dpi have no effect (replace with cairo_surface_set_fallback_resolution) + cairo_set_line_width should immediately use CTM (see line-width-scale test case) Bug fixes (For each XXXX, see: https://bugs.freedesktop.org/show_bug.cgi?id=XXXX ) 4630 Fonts too large when drawing to image surface while printing 4863 stroking problems with wide dashed lines FC_GLOBAL_ADVANCE (http://lists.freedesktop.org/archives/cairo/2005-August/004893.html) ✓4705 crash at XRenderAddGlyphs - cairo_{ps,pdf}_surface_set_dpi have no effect - cairo_set_line_width should immediately use CTM _transform_glyph_bitmap http://lists.freedesktop.org/archives/cairo/2005-October/005564.html 6759 fontconfig option AntiAlias doesn't work in cairo 1.1.2 SVG/PS/PDF emit_glyph functions need to support bitmapped glyphs diff --git a/configure.in b/configure.in index bcdb50db9..1335e4ce9 100644 --- a/configure.in +++ b/configure.in @@ -586,6 +586,8 @@ if test "x$GCC" = "xyes"; then -Wnested-externs -fno-strict-aliasing" fi +AC_SUBST(WARN_CFLAGS) + CAIRO_CFLAGS="$CAIRO_CFLAGS $WARN_CFLAGS" CAIRO_LIBS="$CAIRO_LIBS" diff --git a/pixman/src/Makefile.am b/pixman/src/Makefile.am index 376d69654..179c557bc 100644 --- a/pixman/src/Makefile.am +++ b/pixman/src/Makefile.am @@ -36,8 +36,8 @@ noinst_LTLIBRARIES += libpixman-mmx.la libpixman_mmx_la_SOURCES = \ fbmmx.c \ fbmmx.h -libpixman_mmx_la_CFLAGS = @MMX_CFLAGS@ +libpixman_mmx_la_CFLAGS = @MMX_CFLAGS@ $(WARN_CFLAGS) libpixman_la_LIBADD = libpixman-mmx.la endif -INCLUDES = -I$(top_srcdir) -I$(srcdir) $(WARN_CFLAGS) +INCLUDES = -I$(top_srcdir) -I$(srcdir) @WARN_CFLAGS@ diff --git a/pixman/src/fbpict.c b/pixman/src/fbpict.c index a09174009..bdf6a4cf7 100644 --- a/pixman/src/fbpict.c +++ b/pixman/src/fbpict.c @@ -72,20 +72,6 @@ fbIn (CARD32 x, CARD8 y) return m|n|o|p; } -static CARD32 -fbIn24 (CARD32 x, CARD8 y) -{ - CARD16 a = y; - CARD16 t; - CARD32 m,n,o,p; - - m = FbInU(x,0,a,t); - n = FbInU(x,8,a,t); - o = FbInU(x,16,a,t); - p = (y << 24); - return m|n|o|p; -} - #define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d))) /* @@ -1816,6 +1802,9 @@ pixman_composite (pixman_operator_t op, } } break; + default: + /* For any operator not specifically handled above we default out to the general code. */ + func = NULL; } if (!func) { diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c index 90b1bcafa..c166cfbe2 100644 --- a/pixman/src/icimage.c +++ b/pixman/src/icimage.c @@ -154,72 +154,6 @@ pixman_gradient_color (pixman_gradient_stop_t *stop1, next_color, dist)); } -static int -pixman_init_gradient_color_table (pixman_gradient_image_t *gradient, - int tableSize) -{ - int begin_pos, end_pos; - xFixed incr, dpos; - int pos, current_stop; - pixman_gradient_stop_t *stops = gradient->stops; - int nstops = gradient->nstops; - - if (gradient->colorTableSize < tableSize) - { - uint32_t *newColorTable; - - newColorTable = realloc (gradient->colorTable, - tableSize * sizeof (uint32_t)); - if (!newColorTable) - return 1; - - gradient->colorTable = newColorTable; - gradient->colorTableSize = tableSize; - } - - gradient->stopRange = tableSize; - - /* The position where the gradient begins and ends */ - begin_pos = (stops[0].x * gradient->colorTableSize) >> 16; - end_pos = (stops[nstops - 1].x * gradient->colorTableSize) >> 16; - - pos = 0; /* The position in the color table. */ - - /* Up to first point */ - while (pos <= begin_pos) { - gradient->colorTable[pos] = xRenderColorToCard32(stops[0].color); - ++pos; - } - - incr = (1<<16)/ gradient->colorTableSize; /* the double increment. */ - dpos = incr * pos; /* The position in terms of 0-1. */ - - current_stop = 0; /* We always interpolate between current and current + 1. */ - - /* Gradient area */ - while (pos < end_pos) { - gradient->colorTable[pos] = - pixman_gradient_color (&stops[current_stop], - &stops[current_stop + 1], - dpos); - - ++pos; - dpos += incr; - - if (dpos > stops[current_stop + 1].x) - ++current_stop; - } - - /* After last point */ - while (pos < gradient->colorTableSize) { - gradient->colorTable[pos] = - xRenderColorToCard32 (stops[nstops - 1].color); - ++pos; - } - - return 0; -} - static int _pixman_init_gradient (pixman_gradient_image_t *gradient, const pixman_gradient_stop_t *stops, diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 2746cd07c..a48182d28 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -38,7 +38,7 @@ #include "cairoint.h" #include "cairo-pdf.h" -#include "cairo-font-subset-private.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" @@ -86,19 +86,21 @@ * instead of outputting the cm operator in every page. */ -typedef struct cairo_pdf_object cairo_pdf_object_t; -typedef struct cairo_pdf_resource cairo_pdf_resource_t; -typedef struct cairo_pdf_surface cairo_pdf_surface_t; - -struct cairo_pdf_object { +typedef struct _cairo_pdf_object { long offset; -}; +} cairo_pdf_object_t; -struct cairo_pdf_resource { +typedef struct _cairo_pdf_resource { unsigned int id; -}; +} cairo_pdf_resource_t; -struct cairo_pdf_surface { +typedef struct _cairo_pdf_font { + unsigned int font_id; + unsigned int subset_id; + cairo_pdf_resource_t subset_resource; +} cairo_pdf_font_t; + +typedef struct _cairo_pdf_surface { cairo_surface_t base; /* Prefer the name "output" here to avoid confusion over the @@ -117,6 +119,9 @@ struct cairo_pdf_surface { cairo_array_t streams; cairo_array_t alphas; + cairo_scaled_font_subsets_t *font_subsets; + cairo_array_t fonts; + cairo_pdf_resource_t next_available_resource; cairo_pdf_resource_t pages_resource; @@ -130,9 +135,10 @@ struct cairo_pdf_surface { cairo_bool_t has_clip; cairo_paginated_mode_t paginated_mode; -}; +} cairo_pdf_surface_t; -#define DEFAULT_DPI 300 +#define PDF_SURFACE_DPI_DEFAULT 300 +#define PDF_SURFACE_MAX_GLYPHS_PER_FONT 256 static cairo_pdf_resource_t _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface); @@ -166,6 +172,9 @@ _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface); static cairo_status_t _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface); +static cairo_status_t +_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface); + static const cairo_surface_backend_t cairo_pdf_surface_backend; static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend; @@ -258,8 +267,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, surface->width = width; surface->height = height; - surface->x_dpi = DEFAULT_DPI; - surface->y_dpi = DEFAULT_DPI; + surface->x_dpi = PDF_SURFACE_DPI_DEFAULT; + surface->y_dpi = PDF_SURFACE_DPI_DEFAULT; _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t)); _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t)); @@ -268,6 +277,15 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, _cairo_array_init (&surface->streams, sizeof (cairo_pdf_resource_t)); _cairo_array_init (&surface->alphas, sizeof (double)); + surface->font_subsets = _cairo_scaled_font_subsets_create (PDF_SURFACE_MAX_GLYPHS_PER_FONT); + if (! surface->font_subsets) { + _cairo_error (CAIRO_STATUS_NO_MEMORY); + free (surface); + return (cairo_surface_t*) &_cairo_surface_nil; + } + + _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_font_t)); + surface->next_available_resource.id = 1; surface->pages_resource = _cairo_pdf_surface_new_object (surface); @@ -459,9 +477,6 @@ static void _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface) { _cairo_array_truncate (&surface->streams, 0); - _cairo_array_truncate (&surface->patterns, 0); - _cairo_array_truncate (&surface->xobjects, 0); - _cairo_array_truncate (&surface->alphas, 0); } static cairo_surface_t * @@ -545,6 +560,8 @@ _cairo_pdf_surface_finish (void *abstract_surface) _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_emit_font_subsets (surface); + _cairo_pdf_surface_write_pages (surface); info = _cairo_pdf_surface_write_info (surface); @@ -577,6 +594,13 @@ _cairo_pdf_surface_finish (void *abstract_surface) _cairo_array_fini (&surface->streams); _cairo_array_fini (&surface->alphas); + if (surface->font_subsets) { + _cairo_scaled_font_subsets_destroy (surface->font_subsets); + surface->font_subsets = NULL; + } + + _cairo_array_fini (&surface->fonts); + return status; } @@ -1547,8 +1571,11 @@ _cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface) static void _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) { - cairo_pdf_resource_t page; - int num_pages, i; + cairo_pdf_resource_t page, *res; + cairo_pdf_font_t font; + int num_pages, num_fonts, i; + int num_alphas, num_resources; + double alpha; _cairo_pdf_surface_update_object (surface, surface->pages_resource); _cairo_output_stream_printf (surface->output, @@ -1566,6 +1593,69 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) _cairo_output_stream_printf (surface->output, "]\r\n"); _cairo_output_stream_printf (surface->output, " /Count %d\r\n", num_pages); + _cairo_output_stream_printf (surface->output, " /Resources <<\r\n"); + + num_alphas = _cairo_array_num_elements (&surface->alphas); + if (num_alphas > 0) { + _cairo_output_stream_printf (surface->output, + " /ExtGState <<\r\n"); + + for (i = 0; i < num_alphas; i++) { + /* With some work, we could separate the stroking + * or non-stroking alpha here as actually needed. */ + _cairo_array_copy_element (&surface->alphas, i, &alpha); + _cairo_output_stream_printf (surface->output, + " /a%d << /CA %f /ca %f >>\r\n", + i, alpha, alpha); + } + + _cairo_output_stream_printf (surface->output, + " >>\r\n"); + } + + num_resources = _cairo_array_num_elements (&surface->patterns); + if (num_resources > 0) { + _cairo_output_stream_printf (surface->output, + " /Pattern <<"); + for (i = 0; i < num_resources; i++) { + res = _cairo_array_index (&surface->patterns, i); + _cairo_output_stream_printf (surface->output, + " /res%d %d 0 R", + res->id, res->id); + } + + _cairo_output_stream_printf (surface->output, + " >>\r\n"); + } + + num_resources = _cairo_array_num_elements (&surface->xobjects); + if (num_resources > 0) { + _cairo_output_stream_printf (surface->output, + " /XObject <<"); + + for (i = 0; i < num_resources; i++) { + res = _cairo_array_index (&surface->xobjects, i); + _cairo_output_stream_printf (surface->output, + " /res%d %d 0 R", + res->id, res->id); + } + + _cairo_output_stream_printf (surface->output, + " >>\r\n"); + } + + _cairo_output_stream_printf (surface->output," /Font <<\r\n"); + num_fonts = _cairo_array_num_elements (&surface->fonts); + for (i = 0; i < num_fonts; i++) { + _cairo_array_copy_element (&surface->fonts, i, &font); + _cairo_output_stream_printf (surface->output, " /CairoFont-%d-%d %d 0 R\r\n", + font.font_id, font.subset_id, font.subset_resource.id); + } + _cairo_output_stream_printf (surface->output, " >>\r\n"); + + _cairo_output_stream_printf (surface->output, + " >>\r\n"); + /* TODO: Figure out wich other defaults to be inherited by /Page * objects. */ _cairo_output_stream_printf (surface->output, @@ -1576,6 +1666,162 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) surface->height); } +static void +_cairo_pdf_surface_emit_glyph (cairo_pdf_surface_t *surface, + cairo_scaled_font_t *scaled_font, + unsigned long scaled_font_glyph_index, + unsigned int subset_glyph_index, + cairo_pdf_resource_t *glyph_ret) +{ + cairo_scaled_glyph_t *scaled_glyph; + cairo_status_t status; + + status = _cairo_scaled_glyph_lookup (scaled_font, + scaled_font_glyph_index, + CAIRO_SCALED_GLYPH_INFO_METRICS| + CAIRO_SCALED_GLYPH_INFO_PATH, + &scaled_glyph); + /* + * If that fails, try again but ask for an image instead + */ + if (status) + status = _cairo_scaled_glyph_lookup (scaled_font, + scaled_font_glyph_index, + CAIRO_SCALED_GLYPH_INFO_METRICS| + CAIRO_SCALED_GLYPH_INFO_SURFACE, + &scaled_glyph); + if (status) { + _cairo_surface_set_error (&surface->base, status); + return; + } + + /* XXX: Need to actually use the image not the path if that's all + * we could get... */ + + *glyph_ret = _cairo_pdf_surface_open_stream (surface, NULL); + + _cairo_output_stream_printf (surface->output, + "0 0 %f %f %f %f d1\r\n" + " \r\n", + _cairo_fixed_to_double (scaled_glyph->bbox.p1.x), + -_cairo_fixed_to_double (scaled_glyph->bbox.p2.y), + _cairo_fixed_to_double (scaled_glyph->bbox.p2.x), + -_cairo_fixed_to_double (scaled_glyph->bbox.p1.y)); + + status = _cairo_path_fixed_interpret (scaled_glyph->path, + CAIRO_DIRECTION_FORWARD, + _cairo_pdf_path_move_to, + _cairo_pdf_path_line_to, + _cairo_pdf_path_curve_to, + _cairo_pdf_path_close_path, + surface->output); + + _cairo_output_stream_printf (surface->output, + " f"); + + _cairo_pdf_surface_close_stream (surface); + + if (status) + _cairo_surface_set_error (&surface->base, status); +} + +static void +_cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, + void *closure) +{ + cairo_pdf_surface_t *surface = closure; + cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource; + cairo_pdf_font_t font; + int i; + + glyphs = malloc (font_subset->num_glyphs * sizeof (cairo_pdf_resource_t)); + if (glyphs == NULL) { + _cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY); + return; + } + + for (i = 0; i < font_subset->num_glyphs; i++) { + _cairo_pdf_surface_emit_glyph (surface, + font_subset->scaled_font, + font_subset->glyphs[i], i, + &glyphs[i]); + } + + encoding = _cairo_pdf_surface_new_object (surface); + _cairo_output_stream_printf (surface->output, + "%d 0 obj\r\n" + "<< /Type /Encoding\r\n" + " /Differences [0", encoding.id); + for (i = 0; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->output, + " /%d", i); + _cairo_output_stream_printf (surface->output, + "]\r\n" + ">>\r\n" + "endobj\r\n"); + + char_procs = _cairo_pdf_surface_new_object (surface); + _cairo_output_stream_printf (surface->output, + "%d 0 obj\r\n" + "<<\r\n", char_procs.id); + for (i = 0; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->output, + " /%d %d 0 R\r\n", + i, glyphs[i].id); + _cairo_output_stream_printf (surface->output, + ">>\r\n" + "endobj\r\n"); + + subset_resource = _cairo_pdf_surface_new_object (surface); + _cairo_output_stream_printf (surface->output, + "%d 0 obj\r\n" + "<< /Type /Font\r\n" + " /Subtype /Type3\r\n" + " /FontBBox [0 0 0 0]\r\n" + " /FontMatrix\t[1 0 0 1 0 0]\r\n" + " /Encoding %d 0 R\r\n" + " /CharProcs %d 0 R\r\n" + " /FirstChar 0\r\n" + " /LastChar %d\r\n", + subset_resource.id, + encoding.id, + char_procs.id, + font_subset->num_glyphs - 1); + + _cairo_output_stream_printf (surface->output, + " /Widths ["); + for (i = 0; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->output, " 0"); + _cairo_output_stream_printf (surface->output, + "]\r\n"); + + _cairo_output_stream_printf (surface->output, + ">>\r\n" + "endobj\r\n"); + + font.font_id = font_subset->font_id; + font.subset_id = font_subset->subset_id; + font.subset_resource = subset_resource; + _cairo_array_append (&surface->fonts, &font); +} + +static cairo_status_t +_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface) +{ + cairo_status_t status; + + status = _cairo_scaled_font_subsets_foreach (surface->font_subsets, + _cairo_pdf_surface_emit_font_subset, + surface); + _cairo_scaled_font_subsets_destroy (surface->font_subsets); + surface->font_subsets = NULL; + + if (status) + return status; + + return CAIRO_STATUS_SUCCESS; +} + #if 0 static cairo_status_t _cairo_pdf_surface_write_fonts (cairo_pdf_surface_t *surface) @@ -1734,11 +1980,9 @@ static cairo_status_t _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) { cairo_status_t status; - cairo_pdf_resource_t *res; cairo_pdf_resource_t page; - double alpha; cairo_pdf_resource_t stream; - int num_streams, num_alphas, num_resources, i; + int num_streams, i; if (surface->has_clip) { _cairo_output_stream_printf (surface->output, "Q\r\n"); @@ -1777,59 +2021,6 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) " ]\r\n"); _cairo_output_stream_printf (surface->output, - " /Resources <<\r\n"); - - num_alphas = _cairo_array_num_elements (&surface->alphas); - if (num_alphas > 0) { - _cairo_output_stream_printf (surface->output, - " /ExtGState <<\r\n"); - - for (i = 0; i < num_alphas; i++) { - /* With some work, we could separate the stroking - * or non-stroking alpha here as actually needed. */ - _cairo_array_copy_element (&surface->alphas, i, &alpha); - _cairo_output_stream_printf (surface->output, - " /a%d << /CA %f /ca %f >>\r\n", - i, alpha, alpha); - } - - _cairo_output_stream_printf (surface->output, - " >>\r\n"); - } - - num_resources = _cairo_array_num_elements (&surface->patterns); - if (num_resources > 0) { - _cairo_output_stream_printf (surface->output, - " /Pattern <<"); - for (i = 0; i < num_resources; i++) { - res = _cairo_array_index (&surface->patterns, i); - _cairo_output_stream_printf (surface->output, - " /res%d %d 0 R", - res->id, res->id); - } - - _cairo_output_stream_printf (surface->output, - " >>\r\n"); - } - - num_resources = _cairo_array_num_elements (&surface->xobjects); - if (num_resources > 0) { - _cairo_output_stream_printf (surface->output, - " /XObject <<"); - - for (i = 0; i < num_resources; i++) { - res = _cairo_array_index (&surface->xobjects, i); - _cairo_output_stream_printf (surface->output, - " /res%d %d 0 R", - res->id, res->id); - } - - _cairo_output_stream_printf (surface->output, - " >>\r\n"); - } - - _cairo_output_stream_printf (surface->output, - " >>\r\n" ">>\r\n" "endobj\r\n"); @@ -2131,6 +2322,14 @@ _cairo_pdf_surface_fill (void *abstract_surface, return status; } +static char +hex_digit (int i) +{ + i &= 0xf; + if (i < 10) return '0' + i; + return 'a' + (i - 10); +} + static cairo_int_status_t _cairo_pdf_surface_show_glyphs (void *abstract_surface, cairo_operator_t op, @@ -2140,8 +2339,10 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, cairo_scaled_font_t *scaled_font) { cairo_pdf_surface_t *surface = abstract_surface; - cairo_path_fixed_t path; + int current_subset_id = -1; + unsigned int font_id, subset_id, subset_glyph_index; cairo_status_t status; + int i; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _analyze_operation (surface, op, source); @@ -2152,14 +2353,27 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, if (status) return status; - _cairo_path_fixed_init (&path); - _cairo_scaled_font_glyph_path (scaled_font, glyphs, num_glyphs, &path); - status = _cairo_pdf_surface_fill (surface, op, source, - &path, CAIRO_FILL_RULE_WINDING, - 0.1, scaled_font->options.antialias); - _cairo_path_fixed_fini (&path); + for (i = 0; i < num_glyphs; i++) { + status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, + scaled_font, glyphs[i].index, + &font_id, &subset_id, &subset_glyph_index); + if (status) + return status; - return status; + if (subset_id != current_subset_id) { + _cairo_output_stream_printf (surface->output, + "/CairoFont-%d-%d 1 Tf\r\n", + font_id, subset_id); + current_subset_id = subset_id; + } + _cairo_output_stream_printf (surface->output, + "BT %f %f Td <%c%c> Tj ET\r\n", + glyphs[i].x, glyphs[i].y, + hex_digit (subset_glyph_index >> 4), + hex_digit (subset_glyph_index)); + } + + return _cairo_output_stream_get_status (surface->output); } static void diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 42196b0c3..fb8935b4e 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -211,7 +211,7 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface) } } -static cairo_status_t +static void _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, cairo_scaled_font_t *scaled_font, unsigned long scaled_font_glyph_index, @@ -220,9 +220,6 @@ _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, cairo_scaled_glyph_t *scaled_glyph; cairo_status_t status; - _cairo_output_stream_printf (surface->final_stream, - "\t\t{ %% %d\n", subset_glyph_index); - status = _cairo_scaled_glyph_lookup (scaled_font, scaled_font_glyph_index, CAIRO_SCALED_GLYPH_INFO_METRICS| @@ -238,15 +235,18 @@ _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); if (status) { - _cairo_output_stream_printf (surface->final_stream, "\t\t}\n"); - return status; + _cairo_surface_set_error (&surface->base, status); + return; } /* XXX: Need to actually use the image not the path if that's all * we could get... */ _cairo_output_stream_printf (surface->final_stream, - "%f %f %f %f 0 0 setcachedevice\n", + "\t\t{ %% %d\n", subset_glyph_index); + + _cairo_output_stream_printf (surface->final_stream, + "0 0 %f %f %f %f setcachedevice\n", _cairo_fixed_to_double (scaled_glyph->bbox.p1.x), -_cairo_fixed_to_double (scaled_glyph->bbox.p2.y), _cairo_fixed_to_double (scaled_glyph->bbox.p2.x), @@ -265,10 +265,9 @@ _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, _cairo_output_stream_printf (surface->final_stream, "\t\t}\n"); - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, void *closure) { @@ -303,22 +302,23 @@ _cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, "\t\texch get exec\n" "\t}\n" ">> definefont pop\n"); - - return _cairo_output_stream_get_status (surface->final_stream); } - -static void +static cairo_status_t _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface) { + cairo_status_t status; + _cairo_output_stream_printf (surface->final_stream, "%% _cairo_ps_surface_emit_font_subsets\n"); - _cairo_scaled_font_subsets_foreach (surface->font_subsets, - _cairo_ps_surface_emit_font_subset, - surface); + status = _cairo_scaled_font_subsets_foreach (surface->font_subsets, + _cairo_ps_surface_emit_font_subset, + surface); _cairo_scaled_font_subsets_destroy (surface->font_subsets); surface->font_subsets = NULL; + + return status; } static void @@ -1732,11 +1732,10 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, { cairo_ps_surface_t *surface = abstract_surface; cairo_output_stream_t *stream = surface->stream; - cairo_int_status_t status; - cairo_path_fixed_t *path; - int i; int current_subset_id = -1; unsigned int font_id, subset_id, subset_glyph_index; + cairo_status_t status; + int i; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _analyze_operation (surface, op, source); @@ -1753,11 +1752,9 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, scaled_font, glyphs[i].index, &font_id, &subset_id, &subset_glyph_index); - if (status) { - glyphs += i; - num_glyphs -= i; - goto fallback; - } + if (status) + return status; + if (subset_id != current_subset_id) { _cairo_output_stream_printf (surface->stream, "/CairoFont-%d-%d 1 selectfont\n", @@ -1770,19 +1767,8 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, hex_digit (subset_glyph_index >> 4), hex_digit (subset_glyph_index)); } - - return CAIRO_STATUS_SUCCESS; -fallback: - - path = _cairo_path_fixed_create (); - _cairo_scaled_font_glyph_path (scaled_font, glyphs, num_glyphs, path); - status = _cairo_ps_surface_fill (abstract_surface, op, source, - path, CAIRO_FILL_RULE_WINDING, - 0.1, scaled_font->options.antialias); - _cairo_path_fixed_destroy (path); - - return CAIRO_STATUS_SUCCESS; + return _cairo_output_stream_get_status (surface->stream); } static void diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h index d4137d436..aed01a306 100644 --- a/src/cairo-scaled-font-subsets-private.h +++ b/src/cairo-scaled-font-subsets-private.h @@ -140,7 +140,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets, unsigned int *subset_id_ret, unsigned int *subset_glyph_index_ret); -typedef cairo_status_t +typedef void (*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset, void *closure); diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index 3bd51218f..8a0fd97f0 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -545,7 +545,7 @@ _cairo_svg_path_close_path (void *closure) return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_svg_document_emit_glyph (cairo_svg_document_t *document, cairo_scaled_font_t *scaled_font, unsigned long scaled_font_glyph_index, @@ -572,8 +572,10 @@ _cairo_svg_document_emit_glyph (cairo_svg_document_t *document, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) - return status; + if (status) { + _cairo_surface_set_error (document->owner, status); + return; + } info.document = document; info.path = xmlBufferCreate (); @@ -597,28 +599,21 @@ _cairo_svg_document_emit_glyph (cairo_svg_document_t *document, xmlSetProp (child, CC2XML ("style"), CC2XML ("stroke: none;")); xmlBufferFree (info.path); - - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset, void *closure) { cairo_svg_document_t *document = closure; - cairo_status_t status; int i; for (i = 0; i < font_subset->num_glyphs; i++) { - status = _cairo_svg_document_emit_glyph (document, - font_subset->scaled_font, - font_subset->glyphs[i], - font_subset->font_id, i); - if (status) - return status; + _cairo_svg_document_emit_glyph (document, + font_subset->scaled_font, + font_subset->glyphs[i], + font_subset->font_id, i); } - - return CAIRO_STATUS_SUCCESS; } static void diff --git a/test/select-font-face-pdf-argb32-ref.png b/test/select-font-face-pdf-argb32-ref.png index b2de41827..9b8c07a46 100644 Binary files a/test/select-font-face-pdf-argb32-ref.png and b/test/select-font-face-pdf-argb32-ref.png differ