2005-01-05 14:29:31 +00:00
|
|
|
/* 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 University of Southern
|
|
|
|
|
* California.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
|
|
|
|
* Kristian Høgsberg <krh@redhat.com>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "cairoint.h"
|
2005-01-20 08:28:54 +00:00
|
|
|
#include "cairo-pdf.h"
|
2005-06-21 15:38:51 +00:00
|
|
|
#include "cairo-font-subset-private.h"
|
Change cairo_font_t to refer to a font scaled to a particular output device resolution.
src/cairoint.h src/cairo_font.c src/cairo_ft_font.c src/cairo_xlib_surface.c src/cairo_pdf_surface.c src/cairo_gstate.c src/cairo.c: Switch many internal methods from handling cairo_unscaled_font_t and cairo_font_scale_t pairs to handling cairo_font_t.
src/cairo-ft-private.h src/cairo_ft_fontc: Add some internal interfaces for use by the FreeType backend.
Clear the gstate's current font when the transform or target surface changes.
src/cairo.h src/cairo_ft_font.c: Rename cairo_ft_font_pattern to cairo_ft_font_get_pattern().
src/cairo.h src/cairo_ft_font.c: Make cairo_ft_font_create() and cairo_ft_font_create_for_ft_face() take a font scale; make the latter take load_flags for FT_Load_Glyph() as well. Change cairo_ft_font_face() to Xft-style cairo_ft_font_lock_face, cairo_ft_font_unlock_face.
Remove the name/slant/weight=>unscaled font cache, it didn't work with the new cairo_font_t setup. If it turns out to be needed, it can be added back in some other form.
src/cairoint.h src/cairo_font.c: Add a 'flags' field to cairo_glyph_cache_key_t, we use it for load flags with freetype backend.
Switch the caching to be from resolved fontconfig pattern => file; keep only a fixed number of FT_Face objects open at once, similar to FreeType.
src/cairo_gstate.c src/cairoint.h: Add public cairo_font_glyph_extents, use it to implement _cairo_gstate_glyph_extents().
Add refcounting for glyph cache elements; there was an bug where elements got ejected from the cache and freed before they could be used.
src/cairoint.h src/cairo_cache.c (_cairo_cache_random_entry()) New function to return a random entry in the cache matching a predicate; reuse the internals for the previous _random_live_entry().
src/cairoint.h src/cairo_cache.c (_cairo_cache_lookup()): Add an optional created_entry return value.
src/cairo_ft_font.c src/cairo_xlib_surface.c: Adapt to _cairo_cache_lookup() change.
Support max_memory == 0 to indicate an unbounded cache.
src/cairoint.h src/cairo_cache.c (_cairo_cache_remove()): Add a function to manually remove entries from the cache.
Update for changes, document cairo_matrix_t, cairo_glyph_t, etc.
src/cairo.h src/cairo-atsui.h src/cairo-ft.h src/cairo-glitz.h src/cairo-pdf.h src/cairo-png.h src/cairo-ps.h src/cairo-quartz.h src/cairo-xcb.h src/cairo-xlib.h: Add CAIRO_BEGIN/END_DECLS for extern "C", use it on all public headers. Move header guards outermost.
Fix encoding.
2005-01-21 14:33:47 +00:00
|
|
|
#include "cairo-ft-private.h"
|
2006-01-11 11:53:33 +00:00
|
|
|
#include "cairo-paginated-surface-private.h"
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
#include <time.h>
|
2005-01-05 17:46:31 +00:00
|
|
|
#include <zlib.h>
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
/* Issues:
|
|
|
|
|
*
|
|
|
|
|
* - Why doesn't pages inherit /alpha%d GS dictionaries from the Pages
|
|
|
|
|
* object?
|
|
|
|
|
*
|
|
|
|
|
* - We embed an image in the stream each time it's composited. We
|
|
|
|
|
* could add generation counters to surfaces and remember the stream
|
|
|
|
|
* ID for a particular generation for a particular surface.
|
|
|
|
|
*
|
|
|
|
|
* - Clipping: must be able to reset clipping
|
|
|
|
|
*
|
|
|
|
|
* - Images of other formats than 8 bit RGBA.
|
|
|
|
|
*
|
|
|
|
|
* - Backend specific meta data.
|
|
|
|
|
*
|
|
|
|
|
* - Surface patterns.
|
|
|
|
|
*
|
|
|
|
|
* - Alpha channels in gradients.
|
|
|
|
|
*
|
|
|
|
|
* - Should/does cairo support drawing into a scratch surface and then
|
|
|
|
|
* using that as a fill pattern? For this backend, that would involve
|
|
|
|
|
* using a tiling pattern (4.6.2). How do you create such a scratch
|
|
|
|
|
* surface? cairo_surface_create_similar() ?
|
|
|
|
|
*
|
|
|
|
|
* - What if you create a similiar surface and does show_page and then
|
|
|
|
|
* does show_surface on another surface?
|
|
|
|
|
*
|
|
|
|
|
* - Output TM so page scales to the right size - PDF default user
|
|
|
|
|
* space has 1 unit = 1 / 72 inch.
|
|
|
|
|
*
|
|
|
|
|
* - Add test case for RGBA images.
|
|
|
|
|
*
|
|
|
|
|
* - Add test case for RGBA gradients.
|
|
|
|
|
*
|
|
|
|
|
* - Coordinate space for create_similar() args?
|
|
|
|
|
*
|
|
|
|
|
* - Investigate /Matrix entry in content stream dicts for pages
|
|
|
|
|
* 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_stream cairo_pdf_stream_t;
|
|
|
|
|
typedef struct cairo_pdf_document cairo_pdf_document_t;
|
|
|
|
|
typedef struct cairo_pdf_surface cairo_pdf_surface_t;
|
|
|
|
|
|
|
|
|
|
struct cairo_pdf_object {
|
|
|
|
|
long offset;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct cairo_pdf_resource {
|
|
|
|
|
unsigned int id;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct cairo_pdf_stream {
|
|
|
|
|
unsigned int id;
|
|
|
|
|
unsigned int length_id;
|
|
|
|
|
long start_offset;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct cairo_pdf_document {
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output_stream;
|
2005-07-25 16:23:05 +00:00
|
|
|
unsigned long ref_count;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_surface_t *owner;
|
|
|
|
|
cairo_bool_t finished;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-05-13 09:26:20 +00:00
|
|
|
double width;
|
|
|
|
|
double height;
|
2005-05-16 11:41:42 +00:00
|
|
|
double x_dpi;
|
|
|
|
|
double y_dpi;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
unsigned int next_available_id;
|
|
|
|
|
unsigned int pages_id;
|
|
|
|
|
|
|
|
|
|
cairo_pdf_stream_t *current_stream;
|
|
|
|
|
|
|
|
|
|
cairo_array_t objects;
|
|
|
|
|
cairo_array_t pages;
|
2005-01-17 09:40:00 +00:00
|
|
|
|
|
|
|
|
cairo_array_t fonts;
|
2005-01-05 14:29:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct cairo_pdf_surface {
|
|
|
|
|
cairo_surface_t base;
|
|
|
|
|
|
2005-05-13 09:26:20 +00:00
|
|
|
double width;
|
|
|
|
|
double height;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
cairo_pdf_document_t *document;
|
|
|
|
|
cairo_pdf_stream_t *current_stream;
|
|
|
|
|
|
|
|
|
|
cairo_array_t patterns;
|
|
|
|
|
cairo_array_t xobjects;
|
|
|
|
|
cairo_array_t streams;
|
|
|
|
|
cairo_array_t alphas;
|
2005-01-17 09:40:00 +00:00
|
|
|
cairo_array_t fonts;
|
2005-06-14 19:45:22 +00:00
|
|
|
cairo_bool_t has_clip;
|
2005-01-05 14:29:31 +00:00
|
|
|
};
|
|
|
|
|
|
2005-05-16 11:41:42 +00:00
|
|
|
#define DEFAULT_DPI 300
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
static cairo_pdf_document_t *
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_pdf_document_create (cairo_output_stream_t *stream,
|
2005-05-13 09:26:20 +00:00
|
|
|
double width,
|
|
|
|
|
double height);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_document_destroy (cairo_pdf_document_t *document);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_document_finish (cairo_pdf_document_t *document);
|
|
|
|
|
|
2005-08-04 18:44:29 +00:00
|
|
|
static cairo_pdf_document_t *
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_reference (cairo_pdf_document_t *document);
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
static unsigned int
|
|
|
|
|
_cairo_pdf_document_new_object (cairo_pdf_document_t *document);
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_document_add_page (cairo_pdf_document_t *document,
|
|
|
|
|
cairo_pdf_surface_t *surface);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface);
|
|
|
|
|
|
|
|
|
|
static cairo_pdf_stream_t *
|
|
|
|
|
_cairo_pdf_document_open_stream (cairo_pdf_document_t *document,
|
2005-05-13 14:04:22 +00:00
|
|
|
const char *fmt,
|
|
|
|
|
...);
|
2005-06-21 15:38:51 +00:00
|
|
|
static void
|
|
|
|
|
_cairo_pdf_document_close_stream (cairo_pdf_document_t *document);
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static cairo_surface_t *
|
|
|
|
|
_cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document,
|
2005-05-13 09:26:20 +00:00
|
|
|
double width,
|
|
|
|
|
double height);
|
2005-01-05 14:29:31 +00:00
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface,
|
|
|
|
|
cairo_pdf_stream_t *stream);
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t *surface);
|
|
|
|
|
|
|
|
|
|
static const cairo_surface_backend_t cairo_pdf_surface_backend;
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
_cairo_pdf_document_new_object (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-11-04 16:13:30 +00:00
|
|
|
cairo_status_t status;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_object_t object;
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
object.offset = _cairo_output_stream_get_position (document->output_stream);
|
2005-11-04 16:13:30 +00:00
|
|
|
|
|
|
|
|
status = _cairo_array_append (&document->objects, &object);
|
|
|
|
|
if (status)
|
2005-01-17 09:40:00 +00:00
|
|
|
return 0;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return document->next_available_id++;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
static void
|
|
|
|
|
_cairo_pdf_document_update_object (cairo_pdf_document_t *document,
|
|
|
|
|
unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_object_t *object;
|
|
|
|
|
|
|
|
|
|
object = _cairo_array_index (&document->objects, id - 1);
|
2005-03-16 12:08:41 +00:00
|
|
|
object->offset = _cairo_output_stream_get_position (document->output_stream);
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface,
|
|
|
|
|
cairo_pdf_stream_t *stream)
|
|
|
|
|
{
|
2005-11-04 16:13:30 +00:00
|
|
|
/* XXX: Should be checking the return value here. */
|
|
|
|
|
_cairo_array_append (&surface->streams, &stream);
|
2005-01-05 14:29:31 +00:00
|
|
|
surface->current_stream = stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface, unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_resource_t resource;
|
|
|
|
|
|
|
|
|
|
resource.id = id;
|
2005-11-04 16:13:30 +00:00
|
|
|
/* XXX: Should be checking the return value here. */
|
|
|
|
|
_cairo_array_append (&surface->patterns, &resource);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface, unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_resource_t resource;
|
|
|
|
|
int i, num_resources;
|
|
|
|
|
|
|
|
|
|
num_resources = _cairo_array_num_elements (&surface->xobjects);
|
|
|
|
|
for (i = 0; i < num_resources; i++) {
|
|
|
|
|
_cairo_array_copy_element (&surface->xobjects, i, &resource);
|
|
|
|
|
if (resource.id == id)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource.id = id;
|
2005-11-04 16:13:30 +00:00
|
|
|
/* XXX: Should be checking the return value here. */
|
|
|
|
|
_cairo_array_append (&surface->xobjects, &resource);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha)
|
|
|
|
|
{
|
|
|
|
|
int num_alphas, i;
|
|
|
|
|
double other;
|
|
|
|
|
|
|
|
|
|
num_alphas = _cairo_array_num_elements (&surface->alphas);
|
|
|
|
|
for (i = 0; i < num_alphas; i++) {
|
|
|
|
|
_cairo_array_copy_element (&surface->alphas, i, &other);
|
|
|
|
|
if (alpha == other)
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-04 16:13:30 +00:00
|
|
|
/* XXX: Should be checking the return value here. */
|
|
|
|
|
_cairo_array_append (&surface->alphas, &alpha);
|
2005-01-05 14:29:31 +00:00
|
|
|
return _cairo_array_num_elements (&surface->alphas) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_add_font (cairo_pdf_surface_t *surface, unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_resource_t resource;
|
|
|
|
|
int i, num_fonts;
|
|
|
|
|
|
|
|
|
|
num_fonts = _cairo_array_num_elements (&surface->fonts);
|
|
|
|
|
for (i = 0; i < num_fonts; i++) {
|
|
|
|
|
_cairo_array_copy_element (&surface->fonts, i, &resource);
|
|
|
|
|
if (resource.id == id)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource.id = id;
|
2005-11-04 16:13:30 +00:00
|
|
|
/* XXX: Should be checking the return value here. */
|
|
|
|
|
_cairo_array_append (&surface->fonts, &resource);
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
static cairo_surface_t *
|
2005-05-17 05:58:01 +00:00
|
|
|
_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
cairo_content_t content,
|
|
|
|
|
double width,
|
|
|
|
|
double height)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document;
|
2006-01-11 11:53:33 +00:00
|
|
|
cairo_surface_t *target;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-05-13 09:26:20 +00:00
|
|
|
document = _cairo_pdf_document_create (stream, width, height);
|
2005-07-27 15:39:34 +00:00
|
|
|
if (document == NULL) {
|
|
|
|
|
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
|
|
|
return (cairo_surface_t*) &_cairo_surface_nil;
|
|
|
|
|
}
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2006-01-11 11:53:33 +00:00
|
|
|
target = _cairo_pdf_surface_create_for_document (document, width, height);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2006-01-11 11:53:33 +00:00
|
|
|
document->owner = target;
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_destroy (document);
|
|
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
return _cairo_paginated_surface_create (target, content, width, height);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-18 16:40:17 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_pdf_surface_create_for_stream:
|
|
|
|
|
* @write: a #cairo_write_func_t to accept the output data
|
|
|
|
|
* @closure: the closure argument for @write
|
|
|
|
|
* @content: CAIRO_CONTENT_COLOR_ALPHA or CAIRO_CONTENT_COLOR
|
|
|
|
|
* @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
|
|
|
|
|
* @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
|
|
|
|
|
*
|
|
|
|
|
* Creates a PDF surface of the specified size in points to be written
|
|
|
|
|
* incrementally to the stream represented by @write and @closure.
|
|
|
|
|
*
|
|
|
|
|
* The @content argument is used to specify whether the rendering
|
|
|
|
|
* semantics should behave as if destination alpha is available. The
|
|
|
|
|
* expectation is that the value for @content will be selected to
|
|
|
|
|
* achieve consistent results with a display surface that either has
|
|
|
|
|
* or does not have destination alpha (for example,
|
|
|
|
|
* CAIRO_FORMAT_ARGB32 vs. CAIRO_FORMAT_RGB24).
|
|
|
|
|
*
|
|
|
|
|
* Return value: a pointer to the newly created surface. The caller
|
|
|
|
|
* owns the surface and should call cairo_surface_destroy when done
|
|
|
|
|
* with it.
|
|
|
|
|
*
|
|
|
|
|
* This function always returns a valid pointer, but it will return a
|
|
|
|
|
* pointer to a "nil" surface if an error such as out of memory
|
|
|
|
|
* occurs. You can use cairo_surface_status() to check for this.
|
|
|
|
|
*/
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_surface_t *
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
cairo_pdf_surface_create_for_stream (cairo_write_func_t write,
|
2005-05-13 09:26:20 +00:00
|
|
|
void *closure,
|
2006-01-18 16:40:17 +00:00
|
|
|
cairo_content_t content,
|
|
|
|
|
double width_in_points,
|
|
|
|
|
double height_in_points)
|
2005-03-16 12:08:41 +00:00
|
|
|
{
|
|
|
|
|
cairo_output_stream_t *stream;
|
|
|
|
|
|
2005-05-17 05:58:01 +00:00
|
|
|
stream = _cairo_output_stream_create (write, closure);
|
2005-07-27 15:39:34 +00:00
|
|
|
if (stream == NULL) {
|
|
|
|
|
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
|
|
|
return (cairo_surface_t*) &_cairo_surface_nil;
|
|
|
|
|
}
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2006-01-18 16:40:17 +00:00
|
|
|
return _cairo_pdf_surface_create_for_stream_internal (stream, content,
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
width, height);
|
2005-03-16 12:08:41 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-18 16:40:17 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_pdf_surface_create:
|
|
|
|
|
* @filename: a filename for the PDF output (must be writable)
|
|
|
|
|
* @content: CAIRO_CONTENT_COLOR_ALPHA or CAIRO_CONTENT_COLOR
|
|
|
|
|
* @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
|
|
|
|
|
* @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
|
|
|
|
|
*
|
|
|
|
|
* Creates a PDF surface of the specified size in points to be written
|
|
|
|
|
* to @filename.
|
|
|
|
|
*
|
|
|
|
|
* The @content argument is used to specify whether the rendering
|
|
|
|
|
* semantics should behave as if destination alpha is available. The
|
|
|
|
|
* expectation is that the value for @content will be selected to
|
|
|
|
|
* achieve consistent results with a display surface that either has
|
|
|
|
|
* or does not have destination alpha (for example,
|
|
|
|
|
* CAIRO_FORMAT_ARGB32 vs. CAIRO_FORMAT_RGB24).
|
|
|
|
|
*
|
|
|
|
|
* Return value: a pointer to the newly created surface. The caller
|
|
|
|
|
* owns the surface and should call cairo_surface_destroy when done
|
|
|
|
|
* with it.
|
|
|
|
|
*
|
|
|
|
|
* This function always returns a valid pointer, but it will return a
|
|
|
|
|
* pointer to a "nil" surface if an error such as out of memory
|
|
|
|
|
* occurs. You can use cairo_surface_status() to check for this.
|
|
|
|
|
**/
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_surface_t *
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
cairo_pdf_surface_create (const char *filename,
|
2006-01-18 16:40:17 +00:00
|
|
|
cairo_content_t content,
|
|
|
|
|
double width_in_points,
|
|
|
|
|
double height_in_points)
|
2005-03-16 12:08:41 +00:00
|
|
|
{
|
|
|
|
|
cairo_output_stream_t *stream;
|
|
|
|
|
|
2005-05-16 11:41:42 +00:00
|
|
|
stream = _cairo_output_stream_create_for_file (filename);
|
2005-07-27 15:39:34 +00:00
|
|
|
if (stream == NULL) {
|
|
|
|
|
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
|
|
|
return (cairo_surface_t*) &_cairo_surface_nil;
|
|
|
|
|
}
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2006-01-18 16:40:17 +00:00
|
|
|
return _cairo_pdf_surface_create_for_stream_internal (stream, content,
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
width, height);
|
2005-05-13 09:26:20 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-11 11:53:33 +00:00
|
|
|
static cairo_bool_t
|
|
|
|
|
_cairo_surface_is_pdf (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
return surface->backend == &cairo_pdf_surface_backend;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-19 10:36:43 +00:00
|
|
|
/**
|
|
|
|
|
* cairo__surface_set_dpi:
|
|
|
|
|
* @surface: a postscript cairo_surface_t
|
|
|
|
|
* @x_dpi: horizontal dpi
|
|
|
|
|
* @y_dpi: vertical dpi
|
|
|
|
|
*
|
2006-01-18 16:40:17 +00:00
|
|
|
* Set the horizontal and vertical resolution for image fallbacks.
|
|
|
|
|
* When the pdf backend needs to fall back to image overlays, it will
|
|
|
|
|
* use this resolution. These DPI values are not used for any other
|
|
|
|
|
* purpose, (in particular, they do not have any bearing on the size
|
|
|
|
|
* passed to cairo_pdf_surface_create() nor on the CTM).
|
2005-08-19 10:36:43 +00:00
|
|
|
**/
|
2005-05-13 09:26:20 +00:00
|
|
|
void
|
2005-05-16 11:41:42 +00:00
|
|
|
cairo_pdf_surface_set_dpi (cairo_surface_t *surface,
|
|
|
|
|
double x_dpi,
|
|
|
|
|
double y_dpi)
|
2005-05-13 09:26:20 +00:00
|
|
|
{
|
2006-01-11 11:53:33 +00:00
|
|
|
cairo_surface_t *target;
|
|
|
|
|
cairo_pdf_surface_t *pdf_surface;
|
|
|
|
|
|
|
|
|
|
if (! _cairo_surface_is_paginated (surface)) {
|
|
|
|
|
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
target = _cairo_paginated_surface_get_target (surface);
|
|
|
|
|
|
|
|
|
|
if (! _cairo_surface_is_pdf (surface)) {
|
|
|
|
|
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdf_surface = (cairo_pdf_surface_t *) target;
|
2005-05-13 09:26:20 +00:00
|
|
|
|
2005-05-16 11:41:42 +00:00
|
|
|
pdf_surface->document->x_dpi = x_dpi;
|
|
|
|
|
pdf_surface->document->y_dpi = y_dpi;
|
2005-03-16 12:08:41 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static cairo_surface_t *
|
|
|
|
|
_cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document,
|
2005-05-13 09:26:20 +00:00
|
|
|
double width,
|
|
|
|
|
double height)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface;
|
|
|
|
|
|
|
|
|
|
surface = malloc (sizeof (cairo_pdf_surface_t));
|
2005-07-27 15:39:34 +00:00
|
|
|
if (surface == NULL) {
|
|
|
|
|
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
|
|
|
return (cairo_surface_t*) &_cairo_surface_nil;
|
|
|
|
|
}
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_surface_init (&surface->base, &cairo_pdf_surface_backend);
|
|
|
|
|
|
2005-05-13 09:26:20 +00:00
|
|
|
surface->width = width;
|
|
|
|
|
surface->height = height;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-08-04 18:44:29 +00:00
|
|
|
surface->document = _cairo_pdf_document_reference (document);
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_array_init (&surface->streams, sizeof (cairo_pdf_stream_t *));
|
|
|
|
|
_cairo_array_init (&surface->patterns, sizeof (cairo_pdf_resource_t));
|
|
|
|
|
_cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t));
|
|
|
|
|
_cairo_array_init (&surface->alphas, sizeof (double));
|
2005-02-13 20:36:28 +00:00
|
|
|
_cairo_array_init (&surface->fonts, sizeof (cairo_pdf_resource_t));
|
2005-06-14 19:45:22 +00:00
|
|
|
surface->has_clip = FALSE;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return &surface->base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
int num_streams, i;
|
|
|
|
|
cairo_pdf_stream_t *stream;
|
|
|
|
|
|
|
|
|
|
num_streams = _cairo_array_num_elements (&surface->streams);
|
|
|
|
|
for (i = 0; i < num_streams; i++) {
|
|
|
|
|
_cairo_array_copy_element (&surface->streams, i, &stream);
|
|
|
|
|
free (stream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_cairo_array_truncate (&surface->streams, 0);
|
|
|
|
|
_cairo_array_truncate (&surface->patterns, 0);
|
|
|
|
|
_cairo_array_truncate (&surface->xobjects, 0);
|
|
|
|
|
_cairo_array_truncate (&surface->alphas, 0);
|
2005-01-17 09:40:00 +00:00
|
|
|
_cairo_array_truncate (&surface->fonts, 0);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_surface_t *
|
2005-07-08 10:12:28 +00:00
|
|
|
_cairo_pdf_surface_create_similar (void *abstract_src,
|
|
|
|
|
cairo_content_t content,
|
2005-01-05 14:29:31 +00:00
|
|
|
int width,
|
|
|
|
|
int height)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *template = abstract_src;
|
|
|
|
|
|
|
|
|
|
return _cairo_pdf_surface_create_for_document (template->document,
|
|
|
|
|
width, height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_pdf_stream_t *
|
|
|
|
|
_cairo_pdf_document_open_stream (cairo_pdf_document_t *document,
|
2005-05-13 14:04:22 +00:00
|
|
|
const char *fmt,
|
|
|
|
|
...)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output_stream = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_stream_t *stream;
|
2005-05-13 14:04:22 +00:00
|
|
|
va_list ap;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
stream = malloc (sizeof (cairo_pdf_stream_t));
|
|
|
|
|
if (stream == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stream->id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
stream->length_id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output_stream,
|
|
|
|
|
"%d 0 obj\r\n"
|
2005-05-13 14:04:22 +00:00
|
|
|
"<< /Length %d 0 R\r\n",
|
2005-03-16 12:08:41 +00:00
|
|
|
stream->id,
|
2005-05-13 14:04:22 +00:00
|
|
|
stream->length_id);
|
|
|
|
|
|
|
|
|
|
if (fmt != NULL) {
|
|
|
|
|
va_start (ap, fmt);
|
|
|
|
|
_cairo_output_stream_vprintf (output_stream, fmt, ap);
|
|
|
|
|
va_end (ap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (output_stream,
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"stream\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
stream->start_offset = _cairo_output_stream_get_position (output_stream);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
document->current_stream = stream;
|
|
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_document_close_stream (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output_stream = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
long length;
|
|
|
|
|
cairo_pdf_stream_t *stream;
|
|
|
|
|
|
|
|
|
|
stream = document->current_stream;
|
|
|
|
|
if (stream == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
length = _cairo_output_stream_get_position (output_stream) -
|
|
|
|
|
stream->start_offset;
|
|
|
|
|
_cairo_output_stream_printf (output_stream,
|
|
|
|
|
"endstream\r\n"
|
|
|
|
|
"endobj\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
_cairo_pdf_document_update_object (document, stream->length_id);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output_stream,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
" %ld\r\n"
|
|
|
|
|
"endobj\r\n",
|
|
|
|
|
stream->length_id,
|
|
|
|
|
length);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
document->current_stream = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_surface_finish (void *abstract_surface)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_status_t status;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
|
|
|
|
|
|
|
|
|
if (surface->current_stream == document->current_stream)
|
|
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
if (document->owner == &surface->base)
|
|
|
|
|
status = _cairo_pdf_document_finish (document);
|
|
|
|
|
else
|
|
|
|
|
status = CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_destroy (document);
|
|
|
|
|
|
2005-07-14 17:52:17 +00:00
|
|
|
_cairo_array_fini (&surface->streams);
|
|
|
|
|
_cairo_array_fini (&surface->patterns);
|
|
|
|
|
_cairo_array_fini (&surface->xobjects);
|
|
|
|
|
_cairo_array_fini (&surface->alphas);
|
|
|
|
|
_cairo_array_fini (&surface->fonts);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
|
|
|
|
cairo_pdf_stream_t *stream;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
if (document->current_stream == NULL ||
|
|
|
|
|
document->current_stream != surface->current_stream) {
|
|
|
|
|
_cairo_pdf_document_close_stream (document);
|
2005-05-13 14:04:22 +00:00
|
|
|
stream = _cairo_pdf_document_open_stream (document,
|
|
|
|
|
" /Type /XObject\r\n"
|
|
|
|
|
" /Subtype /Form\r\n"
|
|
|
|
|
" /BBox [ 0 0 %f %f ]\r\n",
|
|
|
|
|
surface->width,
|
|
|
|
|
surface->height);
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_surface_add_stream (surface, stream);
|
|
|
|
|
|
|
|
|
|
/* If this is the first stream we open for this surface,
|
|
|
|
|
* output the cairo to PDF transformation matrix. */
|
|
|
|
|
if (_cairo_array_num_elements (&surface->streams) == 1)
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"1 0 0 -1 0 %f cm\r\n",
|
2005-05-13 09:26:20 +00:00
|
|
|
document->height);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
static void *
|
|
|
|
|
compress_dup (const void *data, unsigned long data_size,
|
|
|
|
|
unsigned long *compressed_size)
|
2005-01-06 23:20:07 +00:00
|
|
|
{
|
2005-01-17 09:40:00 +00:00
|
|
|
void *compressed;
|
|
|
|
|
|
|
|
|
|
/* Bound calculation taken from zlib. */
|
|
|
|
|
*compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
|
|
|
|
|
compressed = malloc (*compressed_size);
|
|
|
|
|
if (compressed == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
compress (compressed, compressed_size, data, data_size);
|
|
|
|
|
|
|
|
|
|
return compressed;
|
2005-01-06 23:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
/* XXX: This should be rewritten to use the standard cairo_status_t
|
|
|
|
|
* return and the error paths here need to be checked for memory
|
|
|
|
|
* leaks. */
|
2005-01-05 14:29:31 +00:00
|
|
|
static unsigned int
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
emit_image_rgb_data (cairo_pdf_document_t *document,
|
|
|
|
|
cairo_image_surface_t *image)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_stream_t *stream;
|
2005-01-05 17:46:31 +00:00
|
|
|
char *rgb, *compressed;
|
|
|
|
|
int i, x, y;
|
|
|
|
|
unsigned long rgb_size, compressed_size;
|
|
|
|
|
pixman_bits_t *pixel;
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
cairo_surface_t *opaque;
|
|
|
|
|
cairo_image_surface_t *opaque_image;
|
|
|
|
|
cairo_pattern_union_t pattern;
|
2005-01-05 17:46:31 +00:00
|
|
|
|
|
|
|
|
rgb_size = image->height * image->width * 3;
|
|
|
|
|
rgb = malloc (rgb_size);
|
|
|
|
|
if (rgb == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
/* XXX: We could actually output the alpha channels through PDF
|
|
|
|
|
* 1.4's SMask. But for now, all we support is opaque image data,
|
|
|
|
|
* so we must flatten any ARGB image by blending over white
|
|
|
|
|
* first. */
|
|
|
|
|
if (image->format != CAIRO_FORMAT_RGB24) {
|
|
|
|
|
opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
|
|
|
|
|
image->width,
|
|
|
|
|
image->height);
|
|
|
|
|
if (opaque->status)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
|
|
|
|
|
|
|
|
|
|
_cairo_surface_fill_rectangle (opaque,
|
|
|
|
|
CAIRO_OPERATOR_SOURCE,
|
|
|
|
|
CAIRO_COLOR_WHITE,
|
|
|
|
|
0, 0, image->width, image->height);
|
|
|
|
|
|
|
|
|
|
_cairo_surface_composite (CAIRO_OPERATOR_OVER,
|
|
|
|
|
&pattern.base,
|
|
|
|
|
NULL,
|
|
|
|
|
opaque,
|
|
|
|
|
0, 0,
|
|
|
|
|
0, 0,
|
|
|
|
|
0, 0,
|
|
|
|
|
image->width,
|
|
|
|
|
image->height);
|
|
|
|
|
|
|
|
|
|
_cairo_pattern_fini (&pattern.base);
|
|
|
|
|
opaque_image = (cairo_image_surface_t *) opaque;
|
|
|
|
|
} else {
|
|
|
|
|
opaque = &image->base;
|
|
|
|
|
opaque_image = image;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-05 17:46:31 +00:00
|
|
|
i = 0;
|
|
|
|
|
for (y = 0; y < image->height; y++) {
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
pixel = (pixman_bits_t *) (opaque_image->data + y * opaque_image->stride);
|
2005-01-05 17:46:31 +00:00
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
for (x = 0; x < opaque_image->width; x++, pixel++) {
|
2005-01-05 17:46:31 +00:00
|
|
|
rgb[i++] = (*pixel & 0x00ff0000) >> 16;
|
|
|
|
|
rgb[i++] = (*pixel & 0x0000ff00) >> 8;
|
|
|
|
|
rgb[i++] = (*pixel & 0x000000ff) >> 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
compressed = compress_dup (rgb, rgb_size, &compressed_size);
|
|
|
|
|
if (compressed == NULL) {
|
|
|
|
|
free (rgb);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
2005-05-13 14:04:22 +00:00
|
|
|
stream = _cairo_pdf_document_open_stream (document,
|
|
|
|
|
" /Type /XObject\r\n"
|
|
|
|
|
" /Subtype /Image\r\n"
|
|
|
|
|
" /Width %d\r\n"
|
|
|
|
|
" /Height %d\r\n"
|
|
|
|
|
" /ColorSpace /DeviceRGB\r\n"
|
|
|
|
|
" /BitsPerComponent 8\r\n"
|
|
|
|
|
" /Filter /FlateDecode\r\n",
|
|
|
|
|
image->width, image->height);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_write (output, compressed, compressed_size);
|
2005-05-03 14:28:50 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
2005-01-05 17:46:31 +00:00
|
|
|
free (rgb);
|
|
|
|
|
free (compressed);
|
|
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
if (opaque_image != image)
|
|
|
|
|
cairo_surface_destroy (opaque);
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
return stream->id;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-05 17:46:31 +00:00
|
|
|
static cairo_int_status_t
|
2005-02-01 20:47:43 +00:00
|
|
|
_cairo_pdf_surface_composite_image (cairo_pdf_surface_t *dst,
|
2005-03-03 17:40:04 +00:00
|
|
|
cairo_surface_pattern_t *pattern)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = dst->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned id;
|
|
|
|
|
cairo_matrix_t i2u;
|
2005-02-01 20:47:43 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
cairo_image_surface_t *image;
|
|
|
|
|
cairo_surface_t *src;
|
|
|
|
|
void *image_extra;
|
|
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
src = pattern->surface;
|
2005-02-01 20:47:43 +00:00
|
|
|
status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
|
2005-06-10 12:18:20 +00:00
|
|
|
if (status)
|
2005-02-01 20:47:43 +00:00
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
id = emit_image_rgb_data (dst->document, image);
|
2005-02-01 20:47:43 +00:00
|
|
|
if (id == 0) {
|
|
|
|
|
status = CAIRO_STATUS_NO_MEMORY;
|
|
|
|
|
goto bail;
|
|
|
|
|
}
|
2005-01-05 17:46:31 +00:00
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_surface_add_xobject (dst, id);
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (dst);
|
|
|
|
|
|
2005-05-06 13:32:53 +00:00
|
|
|
i2u = pattern->base.matrix;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_invert (&i2u);
|
|
|
|
|
cairo_matrix_translate (&i2u, 0, image->height);
|
|
|
|
|
cairo_matrix_scale (&i2u, image->width, -image->height);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"q %f %f %f %f %f %f cm /res%d Do Q\r\n",
|
2005-04-07 10:01:49 +00:00
|
|
|
i2u.xx, i2u.yx,
|
|
|
|
|
i2u.xy, i2u.yy,
|
|
|
|
|
i2u.x0, i2u.y0,
|
2005-03-16 12:08:41 +00:00
|
|
|
id);
|
2005-01-05 17:46:31 +00:00
|
|
|
|
2005-02-01 20:47:43 +00:00
|
|
|
bail:
|
|
|
|
|
_cairo_surface_release_source_image (src, image, image_extra);
|
|
|
|
|
|
|
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The contents of the surface is already transformed into PDF units,
|
|
|
|
|
* but when we composite the surface we may want to use a different
|
|
|
|
|
* space. The problem I see now is that the show_surface snippet
|
|
|
|
|
* creates a surface 1x1, which in the snippet environment is the
|
|
|
|
|
* entire surface. When compositing the surface, cairo gives us the
|
|
|
|
|
* 1x1 to 256x256 matrix. This would be fine if cairo didn't actually
|
|
|
|
|
* also transform the drawing to the surface. Should the CTM be part
|
|
|
|
|
* of the current target surface?
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static cairo_int_status_t
|
|
|
|
|
_cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
|
2005-03-03 17:40:04 +00:00
|
|
|
cairo_surface_pattern_t *pattern)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = dst->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_t i2u;
|
|
|
|
|
cairo_pdf_stream_t *stream;
|
|
|
|
|
int num_streams, i;
|
2005-02-01 20:47:43 +00:00
|
|
|
cairo_pdf_surface_t *src;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (dst);
|
|
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
src = (cairo_pdf_surface_t *) pattern->surface;
|
2005-02-01 20:47:43 +00:00
|
|
|
|
2005-06-17 13:25:19 +00:00
|
|
|
i2u = pattern->base.matrix;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_invert (&i2u);
|
2005-05-13 09:26:20 +00:00
|
|
|
cairo_matrix_scale (&i2u, 1.0 / src->width, 1.0 / src->height);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"q %f %f %f %f %f %f cm",
|
2005-04-07 10:01:49 +00:00
|
|
|
i2u.xx, i2u.yx,
|
|
|
|
|
i2u.xy, i2u.yy,
|
|
|
|
|
i2u.x0, i2u.y0);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
num_streams = _cairo_array_num_elements (&src->streams);
|
|
|
|
|
for (i = 0; i < num_streams; i++) {
|
|
|
|
|
_cairo_array_copy_element (&src->streams, i, &stream);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /res%d Do",
|
|
|
|
|
stream->id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_surface_add_xobject (dst, stream->id);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output, " Q\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_int_status_t
|
2005-12-16 03:02:35 +00:00
|
|
|
_cairo_pdf_surface_composite (cairo_operator_t op,
|
2005-03-03 18:39:06 +00:00
|
|
|
cairo_pattern_t *src_pattern,
|
|
|
|
|
cairo_pattern_t *mask_pattern,
|
2005-01-05 14:29:31 +00:00
|
|
|
void *abstract_dst,
|
|
|
|
|
int src_x,
|
|
|
|
|
int src_y,
|
|
|
|
|
int mask_x,
|
|
|
|
|
int mask_y,
|
|
|
|
|
int dst_x,
|
|
|
|
|
int dst_y,
|
|
|
|
|
unsigned int width,
|
|
|
|
|
unsigned int height)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *dst = abstract_dst;
|
2005-03-03 18:39:06 +00:00
|
|
|
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-03-03 18:39:06 +00:00
|
|
|
if (mask_pattern)
|
2005-03-07 21:22:42 +00:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-03-03 18:39:06 +00:00
|
|
|
|
|
|
|
|
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
|
2005-02-01 20:47:43 +00:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-27 10:46:20 +00:00
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
if (src->surface->backend == &cairo_pdf_surface_backend)
|
|
|
|
|
return _cairo_pdf_surface_composite_pdf (dst, src);
|
2005-02-01 20:47:43 +00:00
|
|
|
else
|
2005-03-03 17:40:04 +00:00
|
|
|
return _cairo_pdf_surface_composite_image (dst, src);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_int_status_t
|
|
|
|
|
_cairo_pdf_surface_fill_rectangles (void *abstract_surface,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2005-01-05 14:29:31 +00:00
|
|
|
const cairo_color_t *color,
|
|
|
|
|
cairo_rectangle_t *rects,
|
|
|
|
|
int num_rects)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (surface);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%f %f %f rg\r\n",
|
|
|
|
|
color->red, color->green, color->blue);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
for (i = 0; i < num_rects; i++) {
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d %d %d %d re f\r\n",
|
|
|
|
|
rects[i].x, rects[i].y,
|
|
|
|
|
rects[i].width, rects[i].height);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
static cairo_status_t
|
2005-03-03 17:40:04 +00:00
|
|
|
emit_solid_pattern (cairo_pdf_surface_t *surface,
|
|
|
|
|
cairo_solid_pattern_t *pattern)
|
2005-02-01 20:47:43 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-02-01 20:47:43 +00:00
|
|
|
unsigned int alpha;
|
|
|
|
|
|
2005-04-14 14:42:26 +00:00
|
|
|
alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
|
2005-02-01 20:47:43 +00:00
|
|
|
_cairo_pdf_surface_ensure_stream (surface);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%f %f %f rg /a%d gs\r\n",
|
2005-04-14 14:42:26 +00:00
|
|
|
pattern->color.red,
|
|
|
|
|
pattern->color.green,
|
|
|
|
|
pattern->color.blue,
|
2005-03-16 12:08:41 +00:00
|
|
|
alpha);
|
2005-10-07 13:21:01 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-02-01 20:47:43 +00:00
|
|
|
}
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
static cairo_status_t
|
2005-02-01 20:47:43 +00:00
|
|
|
emit_surface_pattern (cairo_pdf_surface_t *dst,
|
2005-10-11 13:20:44 +00:00
|
|
|
cairo_surface_pattern_t *pattern)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = dst->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_stream_t *stream;
|
|
|
|
|
cairo_image_surface_t *image;
|
2005-01-31 08:50:22 +00:00
|
|
|
void *image_extra;
|
|
|
|
|
cairo_status_t status;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int id, alpha;
|
|
|
|
|
cairo_matrix_t pm;
|
|
|
|
|
|
2005-10-13 20:15:29 +00:00
|
|
|
/* XXX: This is broken. We need new code here to actually emit the
|
|
|
|
|
* PDF surface. */
|
2005-10-10 09:36:39 +00:00
|
|
|
if (pattern->surface->backend == &cairo_pdf_surface_backend)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-31 08:50:22 +00:00
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
|
2005-06-10 12:18:20 +00:00
|
|
|
if (status)
|
2005-10-10 09:36:39 +00:00
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
Big change to the test infrastructure and supporting internals. The goal now is to test both a COLOR_ALPHA and a COLOR content for each surface backend, (since the semantics are different and we probably need to support both in each backend.
The PS/PDF backends don't allow a content to be passed in right now, so they fail against the rgb24 tests, but the trivial addition to the constructors will allow them to pass all tests with both content values.
And new constructors (currently internal only) to create an image surface with a cairo_content_t rather than a cairo_format_t.
Add a cairo_content_t argument to the constructor.
Add a cairo_content_t to the constructor and use this content value when constructing intermediate image surfaces in acquire_source, show_page, copy_page, and snapshot.
Add image flattening by compositing over white, as is done in cairo-ps-surface.c.
Track changes to cairo-paginates-surface which now requires a cairo_content_t value (no change to public PS/PDF constructors yet).
Track change in meta-surface and paginated-surface interfaces by now accepting a cairo_content_t rather than a cairo_format_t.
Ignore new output files (argb32 from pdf and ps as well as rgb24 from test-fallback, test-meta, and test-paginated).
Add new utility for flattening PNG images in order to generate the -argbf-ref.png images.
Add image_diff_flattened for comparing flattened output from PS and PDF backend with ARGB reference images by first blending the reference images over white.
Get rid of conditional, format-specific background-color initialization before running tests. Now uses ARGB(0,0,0,0) in all cases. Switch from specifying tests with a format value to specifying tests with a content value. Add support for a 'fake' COLOR_ALPHA_FLATTENED content for testing the PS and PDF output against a flattened version of the argb32 reference images (first blended over white).
Track change in cairo_ps_surface_create (now requires cairo_content_t value).
Adjust tests that draw in default (black) to first paint white so that the results are visible.
Adjust ARGB32 reference images for new white background for changed tests.
Adjust RGB24 reference images for new black background due to changed initialization (and the tests themselves being unchanged).
2006-01-17 16:59:08 +00:00
|
|
|
id = emit_image_rgb_data (dst->document, image);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
/* BBox must be smaller than XStep by YStep or acroread wont
|
|
|
|
|
* display the pattern. */
|
|
|
|
|
|
2005-04-07 10:01:49 +00:00
|
|
|
cairo_matrix_init_identity (&pm);
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_scale (&pm, image->width, image->height);
|
2005-05-06 13:32:53 +00:00
|
|
|
pm = pattern->base.matrix;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_invert (&pm);
|
|
|
|
|
|
2005-05-13 14:04:22 +00:00
|
|
|
stream = _cairo_pdf_document_open_stream (document,
|
|
|
|
|
" /BBox [ 0 0 256 256 ]\r\n"
|
|
|
|
|
" /XStep 256\r\n"
|
|
|
|
|
" /YStep 256\r\n"
|
|
|
|
|
" /PatternType 1\r\n"
|
|
|
|
|
" /TilingType 1\r\n"
|
|
|
|
|
" /PaintType 1\r\n"
|
|
|
|
|
" /Resources << /XObject << /res%d %d 0 R >> >>\r\n",
|
|
|
|
|
id, id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
|
2005-05-03 14:28:50 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /res%d Do\r\n",
|
|
|
|
|
id);
|
2005-02-01 20:47:43 +00:00
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_surface_add_pattern (dst, stream->id);
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (dst);
|
|
|
|
|
alpha = _cairo_pdf_surface_add_alpha (dst, 1.0);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"/Pattern cs /res%d scn /a%d gs\r\n",
|
|
|
|
|
stream->id, alpha);
|
2005-01-31 08:50:22 +00:00
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
2005-10-07 13:21:01 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-10-11 13:20:44 +00:00
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
typedef struct _cairo_pdf_color_stop {
|
2005-10-11 13:20:44 +00:00
|
|
|
double offset;
|
|
|
|
|
unsigned int gradient_id;
|
|
|
|
|
unsigned char color_char[4];
|
2005-10-07 13:21:01 +00:00
|
|
|
} cairo_pdf_color_stop_t;
|
|
|
|
|
|
2005-10-11 13:20:44 +00:00
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
emit_linear_colorgradient (cairo_pdf_document_t *document,
|
|
|
|
|
cairo_pdf_color_stop_t *stop1,
|
|
|
|
|
cairo_pdf_color_stop_t *stop2)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-10-11 13:20:44 +00:00
|
|
|
unsigned int function_id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /FunctionType 0\r\n"
|
2005-10-11 13:20:44 +00:00
|
|
|
" /Domain [ 0 1 ]\r\n"
|
|
|
|
|
" /Size [ 2 ]\r\n"
|
2005-03-16 12:08:41 +00:00
|
|
|
" /BitsPerSample 8\r\n"
|
2005-10-11 13:20:44 +00:00
|
|
|
" /Range [ 0 1 0 1 0 1 ]\r\n"
|
|
|
|
|
" /Length 6\r\n"
|
2005-03-16 12:08:41 +00:00
|
|
|
">>\r\n"
|
|
|
|
|
"stream\r\n",
|
2005-10-11 13:20:44 +00:00
|
|
|
function_id);
|
2005-10-07 13:21:01 +00:00
|
|
|
|
2005-10-11 13:20:44 +00:00
|
|
|
_cairo_output_stream_write (output, stop1->color_char, 3);
|
|
|
|
|
_cairo_output_stream_write (output, stop2->color_char, 3);
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"\r\n"
|
|
|
|
|
"endstream\r\n"
|
|
|
|
|
"endobj\r\n");
|
|
|
|
|
|
|
|
|
|
return function_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
emit_stiched_colorgradient (cairo_pdf_document_t *document,
|
|
|
|
|
unsigned int n_stops,
|
|
|
|
|
cairo_pdf_color_stop_t stops[])
|
|
|
|
|
{
|
|
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
|
|
|
|
unsigned int function_id;
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
/* emit linear gradients between pairs of subsequent stops... */
|
|
|
|
|
for (i = 0; i < n_stops-1; i++) {
|
|
|
|
|
stops[i].gradient_id = emit_linear_colorgradient (document,
|
|
|
|
|
&stops[i],
|
|
|
|
|
&stops[i+1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ... and stich them together */
|
|
|
|
|
function_id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /FunctionType 3\r\n"
|
|
|
|
|
" /Domain [ 0 1 ]\r\n"
|
|
|
|
|
" /Functions [ ",
|
|
|
|
|
function_id);
|
|
|
|
|
for (i = 0; i < n_stops-1; i++)
|
|
|
|
|
_cairo_output_stream_printf (output, "%d 0 R ", stops[i].gradient_id);
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"]\r\n"
|
|
|
|
|
" /Bounds [ ");
|
|
|
|
|
for (i = 1; i < n_stops-1; i++)
|
|
|
|
|
_cairo_output_stream_printf (output, "%f ", stops[i].offset);
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"]\r\n"
|
|
|
|
|
" /Encode [ ");
|
|
|
|
|
for (i = 1; i < n_stops; i++)
|
|
|
|
|
_cairo_output_stream_printf (output, "0 1 ");
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"]\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n");
|
|
|
|
|
|
|
|
|
|
return function_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define COLOR_STOP_EPSILLON 1e-6
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
|
|
|
|
unsigned int function_id;
|
|
|
|
|
cairo_pdf_color_stop_t *allstops, *stops;
|
|
|
|
|
unsigned int n_stops;
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
function_id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
|
|
|
|
|
allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t));
|
|
|
|
|
if (allstops == NULL) {
|
2005-10-07 13:21:01 +00:00
|
|
|
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-10-11 13:20:44 +00:00
|
|
|
stops = &allstops[1];
|
|
|
|
|
n_stops = pattern->n_stops;
|
2005-10-07 13:21:01 +00:00
|
|
|
|
|
|
|
|
for (i = 0; i < pattern->n_stops; i++) {
|
2006-01-05 05:06:50 +00:00
|
|
|
stops[i].color_char[0] = pattern->stops[i].color.red >> 8;
|
|
|
|
|
stops[i].color_char[1] = pattern->stops[i].color.green >> 8;
|
|
|
|
|
stops[i].color_char[2] = pattern->stops[i].color.blue >> 8;
|
|
|
|
|
stops[i].color_char[3] = pattern->stops[i].color.alpha >> 8;
|
|
|
|
|
stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
|
2005-10-07 13:21:01 +00:00
|
|
|
}
|
2005-10-11 13:20:44 +00:00
|
|
|
|
|
|
|
|
/* make sure first offset is 0.0 and last offset is 1.0. (Otherwise Acrobat
|
|
|
|
|
* Reader chokes.) */
|
|
|
|
|
if (stops[0].offset > COLOR_STOP_EPSILLON) {
|
|
|
|
|
memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t));
|
|
|
|
|
stops = allstops;
|
|
|
|
|
stops[0].offset = 0.0;
|
|
|
|
|
n_stops++;
|
|
|
|
|
}
|
|
|
|
|
if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILLON) {
|
|
|
|
|
memcpy (&stops[n_stops],
|
|
|
|
|
&stops[n_stops - 1],
|
|
|
|
|
sizeof (cairo_pdf_color_stop_t));
|
|
|
|
|
stops[n_stops].offset = 1.0;
|
|
|
|
|
n_stops++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n_stops == 2) {
|
|
|
|
|
/* no need for stiched function */
|
|
|
|
|
function_id = emit_linear_colorgradient (document, &stops[0], &stops[1]);
|
|
|
|
|
} else {
|
|
|
|
|
/* multiple stops: stich. XXX possible optimization: regulary spaced
|
|
|
|
|
* stops do not require stiching. XXX */
|
|
|
|
|
function_id = emit_stiched_colorgradient (document,
|
|
|
|
|
n_stops,
|
|
|
|
|
stops);
|
2005-10-07 13:21:01 +00:00
|
|
|
}
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2005-10-11 13:20:44 +00:00
|
|
|
free (allstops);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return function_id;
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
static cairo_status_t
|
2005-03-03 17:40:04 +00:00
|
|
|
emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *pattern)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int function_id, pattern_id, alpha;
|
|
|
|
|
double x0, y0, x1, y1;
|
|
|
|
|
cairo_matrix_t p2u;
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
function_id = emit_pattern_stops (surface, &pattern->base);
|
2005-10-07 13:21:01 +00:00
|
|
|
if (function_id == 0)
|
|
|
|
|
return CAIRO_STATUS_NO_MEMORY;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-05-06 13:32:53 +00:00
|
|
|
p2u = pattern->base.base.matrix;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_invert (&p2u);
|
|
|
|
|
|
2006-01-05 05:06:50 +00:00
|
|
|
x0 = _cairo_fixed_to_double (pattern->gradient.p1.x);
|
|
|
|
|
y0 = _cairo_fixed_to_double (pattern->gradient.p1.y);
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_transform_point (&p2u, &x0, &y0);
|
2006-01-05 05:06:50 +00:00
|
|
|
x1 = _cairo_fixed_to_double (pattern->gradient.p2.x);
|
|
|
|
|
y1 = _cairo_fixed_to_double (pattern->gradient.p2.y);
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_transform_point (&p2u, &x1, &y1);
|
|
|
|
|
|
|
|
|
|
pattern_id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /Pattern\r\n"
|
|
|
|
|
" /PatternType 2\r\n"
|
|
|
|
|
" /Matrix [ 1 0 0 -1 0 %f ]\r\n"
|
|
|
|
|
" /Shading\r\n"
|
|
|
|
|
" << /ShadingType 2\r\n"
|
|
|
|
|
" /ColorSpace /DeviceRGB\r\n"
|
|
|
|
|
" /Coords [ %f %f %f %f ]\r\n"
|
|
|
|
|
" /Function %d 0 R\r\n"
|
|
|
|
|
" /Extend [ true true ]\r\n"
|
|
|
|
|
" >>\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n",
|
|
|
|
|
pattern_id,
|
2005-05-13 09:26:20 +00:00
|
|
|
document->height,
|
2005-03-16 12:08:41 +00:00
|
|
|
x0, y0, x1, y1,
|
|
|
|
|
function_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_surface_add_pattern (surface, pattern_id);
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (surface);
|
|
|
|
|
alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
|
|
|
|
|
|
|
|
|
|
/* Use pattern */
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"/Pattern cs /res%d scn /a%d gs\r\n",
|
|
|
|
|
pattern_id, alpha);
|
2005-10-07 13:21:01 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
static cairo_status_t
|
2005-03-03 17:40:04 +00:00
|
|
|
emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *pattern)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int function_id, pattern_id, alpha;
|
|
|
|
|
double x0, y0, x1, y1, r0, r1;
|
|
|
|
|
cairo_matrix_t p2u;
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
2005-03-03 17:40:04 +00:00
|
|
|
function_id = emit_pattern_stops (surface, &pattern->base);
|
2005-10-07 13:21:01 +00:00
|
|
|
if (function_id == 0)
|
|
|
|
|
return CAIRO_STATUS_NO_MEMORY;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-05-06 13:32:53 +00:00
|
|
|
p2u = pattern->base.base.matrix;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_invert (&p2u);
|
|
|
|
|
|
2006-01-05 05:06:50 +00:00
|
|
|
x0 = _cairo_fixed_to_double (pattern->gradient.inner.x);
|
|
|
|
|
y0 = _cairo_fixed_to_double (pattern->gradient.inner.y);
|
|
|
|
|
r0 = _cairo_fixed_to_double (pattern->gradient.inner.radius);
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_transform_point (&p2u, &x0, &y0);
|
2006-01-05 05:06:50 +00:00
|
|
|
x1 = _cairo_fixed_to_double (pattern->gradient.outer.x);
|
|
|
|
|
y1 = _cairo_fixed_to_double (pattern->gradient.outer.y);
|
|
|
|
|
r1 = _cairo_fixed_to_double (pattern->gradient.outer.radius);
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_matrix_transform_point (&p2u, &x1, &y1);
|
|
|
|
|
|
|
|
|
|
/* FIXME: This is surely crack, but how should you scale a radius
|
|
|
|
|
* in a non-orthogonal coordinate system? */
|
|
|
|
|
cairo_matrix_transform_distance (&p2u, &r0, &r1);
|
|
|
|
|
|
2005-02-01 20:47:43 +00:00
|
|
|
/* FIXME: There is a difference between the cairo gradient extend
|
|
|
|
|
* semantics and PDF extend semantics. PDFs extend=false means
|
|
|
|
|
* that nothing is painted outside the gradient boundaries,
|
|
|
|
|
* whereas cairo takes this to mean that the end color is padded
|
|
|
|
|
* to infinity. Setting extend=true in PDF gives the cairo default
|
|
|
|
|
* behavoir, not yet sure how to implement the cairo mirror and
|
|
|
|
|
* repeat behaviour. */
|
2005-01-05 14:29:31 +00:00
|
|
|
pattern_id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /Pattern\r\n"
|
|
|
|
|
" /PatternType 2\r\n"
|
|
|
|
|
" /Matrix [ 1 0 0 -1 0 %f ]\r\n"
|
|
|
|
|
" /Shading\r\n"
|
|
|
|
|
" << /ShadingType 3\r\n"
|
|
|
|
|
" /ColorSpace /DeviceRGB\r\n"
|
|
|
|
|
" /Coords [ %f %f %f %f %f %f ]\r\n"
|
|
|
|
|
" /Function %d 0 R\r\n"
|
|
|
|
|
" /Extend [ true true ]\r\n"
|
|
|
|
|
" >>\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n",
|
|
|
|
|
pattern_id,
|
2005-05-13 09:26:20 +00:00
|
|
|
document->height,
|
2005-03-16 12:08:41 +00:00
|
|
|
x0, y0, r0, x1, y1, r1,
|
|
|
|
|
function_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_surface_add_pattern (surface, pattern_id);
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (surface);
|
|
|
|
|
alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
|
|
|
|
|
|
|
|
|
|
/* Use pattern */
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"/Pattern cs /res%d scn /a%d gs\r\n",
|
|
|
|
|
pattern_id, alpha);
|
2005-10-07 13:21:01 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
static cairo_status_t
|
2005-02-01 20:47:43 +00:00
|
|
|
emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
|
|
|
|
|
{
|
|
|
|
|
switch (pattern->type) {
|
|
|
|
|
case CAIRO_PATTERN_SOLID:
|
2005-10-07 13:21:01 +00:00
|
|
|
return emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
|
2005-02-01 20:47:43 +00:00
|
|
|
|
|
|
|
|
case CAIRO_PATTERN_SURFACE:
|
2005-10-07 13:21:01 +00:00
|
|
|
return emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
|
2005-02-01 20:47:43 +00:00
|
|
|
|
|
|
|
|
case CAIRO_PATTERN_LINEAR:
|
2005-10-07 13:21:01 +00:00
|
|
|
return emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
|
2005-02-01 20:47:43 +00:00
|
|
|
|
|
|
|
|
case CAIRO_PATTERN_RADIAL:
|
2005-10-07 13:21:01 +00:00
|
|
|
return emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
|
2005-02-01 20:47:43 +00:00
|
|
|
}
|
2005-10-07 13:21:01 +00:00
|
|
|
|
|
|
|
|
ASSERT_NOT_REACHED;
|
2005-10-12 13:33:38 +00:00
|
|
|
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
2005-02-01 20:47:43 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static double
|
|
|
|
|
intersect (cairo_line_t *line, cairo_fixed_t y)
|
|
|
|
|
{
|
|
|
|
|
return _cairo_fixed_to_double (line->p1.x) +
|
|
|
|
|
_cairo_fixed_to_double (line->p2.x - line->p1.x) *
|
|
|
|
|
_cairo_fixed_to_double (y - line->p1.y) /
|
|
|
|
|
_cairo_fixed_to_double (line->p2.y - line->p1.y);
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-03 14:28:50 +00:00
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
cairo_output_stream_t *output_stream;
|
2005-06-14 19:45:22 +00:00
|
|
|
cairo_bool_t has_current_point;
|
2005-05-03 14:28:50 +00:00
|
|
|
} pdf_path_info_t;
|
|
|
|
|
|
|
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
|
|
|
|
|
{
|
|
|
|
|
pdf_path_info_t *info = closure;
|
|
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (info->output_stream,
|
|
|
|
|
"%f %f m ",
|
|
|
|
|
_cairo_fixed_to_double (point->x),
|
|
|
|
|
_cairo_fixed_to_double (point->y));
|
2005-06-14 19:45:22 +00:00
|
|
|
info->has_current_point = TRUE;
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_path_line_to (void *closure, cairo_point_t *point)
|
|
|
|
|
{
|
|
|
|
|
pdf_path_info_t *info = closure;
|
2005-06-14 19:45:22 +00:00
|
|
|
const char *pdf_operator;
|
|
|
|
|
|
|
|
|
|
if (info->has_current_point)
|
|
|
|
|
pdf_operator = "l";
|
|
|
|
|
else
|
|
|
|
|
pdf_operator = "m";
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (info->output_stream,
|
2005-06-14 19:45:22 +00:00
|
|
|
"%f %f %s ",
|
2005-05-03 14:28:50 +00:00
|
|
|
_cairo_fixed_to_double (point->x),
|
2005-06-14 19:45:22 +00:00
|
|
|
_cairo_fixed_to_double (point->y),
|
|
|
|
|
pdf_operator);
|
|
|
|
|
info->has_current_point = TRUE;
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_path_curve_to (void *closure,
|
|
|
|
|
cairo_point_t *b,
|
|
|
|
|
cairo_point_t *c,
|
|
|
|
|
cairo_point_t *d)
|
|
|
|
|
{
|
|
|
|
|
pdf_path_info_t *info = closure;
|
|
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (info->output_stream,
|
|
|
|
|
"%f %f %f %f %f %f c ",
|
|
|
|
|
_cairo_fixed_to_double (b->x),
|
|
|
|
|
_cairo_fixed_to_double (b->y),
|
|
|
|
|
_cairo_fixed_to_double (c->x),
|
|
|
|
|
_cairo_fixed_to_double (c->y),
|
|
|
|
|
_cairo_fixed_to_double (d->x),
|
|
|
|
|
_cairo_fixed_to_double (d->y));
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_path_close_path (void *closure)
|
|
|
|
|
{
|
|
|
|
|
pdf_path_info_t *info = closure;
|
|
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (info->output_stream,
|
|
|
|
|
"h\r\n");
|
2005-06-14 19:45:22 +00:00
|
|
|
info->has_current_point = FALSE;
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_int_status_t
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
_cairo_pdf_surface_fill (void *abstract_surface,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_pattern_t *pattern,
|
|
|
|
|
cairo_path_fixed_t *path,
|
|
|
|
|
cairo_fill_rule_t fill_rule,
|
|
|
|
|
double tolerance,
|
|
|
|
|
cairo_antialias_t antialias)
|
2005-05-03 14:28:50 +00:00
|
|
|
{
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
2005-05-03 14:28:50 +00:00
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-06-14 19:45:22 +00:00
|
|
|
const char *pdf_operator;
|
2005-05-03 14:28:50 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
pdf_path_info_t info;
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
status = emit_pattern (surface, pattern);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
/* After the above switch the current stream should belong to this
|
|
|
|
|
* surface, so no need to _cairo_pdf_surface_ensure_stream() */
|
|
|
|
|
assert (document->current_stream != NULL &&
|
|
|
|
|
document->current_stream == surface->current_stream);
|
|
|
|
|
|
|
|
|
|
info.output_stream = document->output_stream;
|
2005-06-14 19:45:22 +00:00
|
|
|
info.has_current_point = FALSE;
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
status = _cairo_path_fixed_interpret (path,
|
|
|
|
|
CAIRO_DIRECTION_FORWARD,
|
|
|
|
|
_cairo_pdf_path_move_to,
|
|
|
|
|
_cairo_pdf_path_line_to,
|
|
|
|
|
_cairo_pdf_path_curve_to,
|
|
|
|
|
_cairo_pdf_path_close_path,
|
|
|
|
|
&info);
|
|
|
|
|
|
2005-06-14 19:45:22 +00:00
|
|
|
switch (fill_rule) {
|
|
|
|
|
case CAIRO_FILL_RULE_WINDING:
|
|
|
|
|
pdf_operator = "f";
|
|
|
|
|
break;
|
|
|
|
|
case CAIRO_FILL_RULE_EVEN_ODD:
|
|
|
|
|
pdf_operator = "f*";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ASSERT_NOT_REACHED;
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-03 14:28:50 +00:00
|
|
|
_cairo_output_stream_printf (document->output_stream,
|
2005-06-14 19:45:22 +00:00
|
|
|
"%s\r\n",
|
|
|
|
|
pdf_operator);
|
2005-05-03 14:28:50 +00:00
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static cairo_int_status_t
|
2005-12-16 03:02:35 +00:00
|
|
|
_cairo_pdf_surface_composite_trapezoids (cairo_operator_t op,
|
2005-01-27 10:46:20 +00:00
|
|
|
cairo_pattern_t *pattern,
|
2005-01-05 14:29:31 +00:00
|
|
|
void *abstract_dst,
|
2005-08-08 18:35:22 +00:00
|
|
|
cairo_antialias_t antialias,
|
2005-01-05 14:29:31 +00:00
|
|
|
int x_src,
|
|
|
|
|
int y_src,
|
2005-01-27 10:46:20 +00:00
|
|
|
int x_dst,
|
|
|
|
|
int y_dst,
|
|
|
|
|
unsigned int width,
|
|
|
|
|
unsigned int height,
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_trapezoid_t *traps,
|
|
|
|
|
int num_traps)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = abstract_dst;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-10-07 13:21:01 +00:00
|
|
|
cairo_int_status_t status;
|
2005-01-05 14:29:31 +00:00
|
|
|
int i;
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
status = emit_pattern (surface, pattern);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
/* After the above switch the current stream should belong to this
|
|
|
|
|
* surface, so no need to _cairo_pdf_surface_ensure_stream() */
|
|
|
|
|
assert (document->current_stream != NULL &&
|
|
|
|
|
document->current_stream == surface->current_stream);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < num_traps; i++) {
|
|
|
|
|
double left_x1, left_x2, right_x1, right_x2;
|
|
|
|
|
|
|
|
|
|
left_x1 = intersect (&traps[i].left, traps[i].top);
|
|
|
|
|
left_x2 = intersect (&traps[i].left, traps[i].bottom);
|
|
|
|
|
right_x1 = intersect (&traps[i].right, traps[i].top);
|
|
|
|
|
right_x2 = intersect (&traps[i].right, traps[i].bottom);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%f %f m %f %f l %f %f l %f %f l h\r\n",
|
|
|
|
|
left_x1, _cairo_fixed_to_double (traps[i].top),
|
|
|
|
|
left_x2, _cairo_fixed_to_double (traps[i].bottom),
|
|
|
|
|
right_x2, _cairo_fixed_to_double (traps[i].bottom),
|
|
|
|
|
right_x1, _cairo_fixed_to_double (traps[i].top));
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"f\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_int_status_t
|
|
|
|
|
_cairo_pdf_surface_copy_page (void *abstract_surface)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
|
|
|
|
|
|
|
|
|
return _cairo_pdf_document_add_page (document, surface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_int_status_t
|
|
|
|
|
_cairo_pdf_surface_show_page (void *abstract_surface)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
|
|
|
|
cairo_int_status_t status;
|
|
|
|
|
|
|
|
|
|
status = _cairo_pdf_document_add_page (document, surface);
|
2005-06-10 12:46:49 +00:00
|
|
|
if (status)
|
|
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-06-10 12:46:49 +00:00
|
|
|
_cairo_pdf_surface_clear (surface);
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-04-19 16:29:04 +00:00
|
|
|
static cairo_int_status_t
|
|
|
|
|
_cairo_pdf_surface_get_extents (void *abstract_surface,
|
|
|
|
|
cairo_rectangle_t *rectangle)
|
|
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
|
|
|
|
|
|
|
|
|
rectangle->x = 0;
|
|
|
|
|
rectangle->y = 0;
|
|
|
|
|
|
|
|
|
|
/* XXX: The conversion to integers here is pretty bogus, (not to
|
|
|
|
|
* mention the aribitray limitation of width to a short(!). We
|
|
|
|
|
* may need to come up with a better interface for get_size.
|
|
|
|
|
*/
|
2005-05-13 09:26:20 +00:00
|
|
|
rectangle->width = (int) ceil (surface->width);
|
|
|
|
|
rectangle->height = (int) ceil (surface->height);
|
2005-04-19 16:29:04 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-21 15:38:51 +00:00
|
|
|
static cairo_font_subset_t *
|
2005-01-17 09:40:00 +00:00
|
|
|
_cairo_pdf_document_get_font (cairo_pdf_document_t *document,
|
2005-04-07 11:03:59 +00:00
|
|
|
cairo_scaled_font_t *scaled_font)
|
2005-01-17 09:40:00 +00:00
|
|
|
{
|
2005-11-04 16:13:30 +00:00
|
|
|
cairo_status_t status;
|
Change cairo_font_t to refer to a font scaled to a particular output device resolution.
src/cairoint.h src/cairo_font.c src/cairo_ft_font.c src/cairo_xlib_surface.c src/cairo_pdf_surface.c src/cairo_gstate.c src/cairo.c: Switch many internal methods from handling cairo_unscaled_font_t and cairo_font_scale_t pairs to handling cairo_font_t.
src/cairo-ft-private.h src/cairo_ft_fontc: Add some internal interfaces for use by the FreeType backend.
Clear the gstate's current font when the transform or target surface changes.
src/cairo.h src/cairo_ft_font.c: Rename cairo_ft_font_pattern to cairo_ft_font_get_pattern().
src/cairo.h src/cairo_ft_font.c: Make cairo_ft_font_create() and cairo_ft_font_create_for_ft_face() take a font scale; make the latter take load_flags for FT_Load_Glyph() as well. Change cairo_ft_font_face() to Xft-style cairo_ft_font_lock_face, cairo_ft_font_unlock_face.
Remove the name/slant/weight=>unscaled font cache, it didn't work with the new cairo_font_t setup. If it turns out to be needed, it can be added back in some other form.
src/cairoint.h src/cairo_font.c: Add a 'flags' field to cairo_glyph_cache_key_t, we use it for load flags with freetype backend.
Switch the caching to be from resolved fontconfig pattern => file; keep only a fixed number of FT_Face objects open at once, similar to FreeType.
src/cairo_gstate.c src/cairoint.h: Add public cairo_font_glyph_extents, use it to implement _cairo_gstate_glyph_extents().
Add refcounting for glyph cache elements; there was an bug where elements got ejected from the cache and freed before they could be used.
src/cairoint.h src/cairo_cache.c (_cairo_cache_random_entry()) New function to return a random entry in the cache matching a predicate; reuse the internals for the previous _random_live_entry().
src/cairoint.h src/cairo_cache.c (_cairo_cache_lookup()): Add an optional created_entry return value.
src/cairo_ft_font.c src/cairo_xlib_surface.c: Adapt to _cairo_cache_lookup() change.
Support max_memory == 0 to indicate an unbounded cache.
src/cairoint.h src/cairo_cache.c (_cairo_cache_remove()): Add a function to manually remove entries from the cache.
Update for changes, document cairo_matrix_t, cairo_glyph_t, etc.
src/cairo.h src/cairo-atsui.h src/cairo-ft.h src/cairo-glitz.h src/cairo-pdf.h src/cairo-png.h src/cairo-ps.h src/cairo-quartz.h src/cairo-xcb.h src/cairo-xlib.h: Add CAIRO_BEGIN/END_DECLS for extern "C", use it on all public headers. Move header guards outermost.
Fix encoding.
2005-01-21 14:33:47 +00:00
|
|
|
cairo_unscaled_font_t *unscaled_font;
|
2005-06-21 15:38:51 +00:00
|
|
|
cairo_font_subset_t *pdf_font;
|
2005-01-17 09:40:00 +00:00
|
|
|
unsigned int num_fonts, i;
|
|
|
|
|
|
2005-07-13 11:01:25 +00:00
|
|
|
/* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
|
|
|
|
|
if (! _cairo_scaled_font_is_ft (scaled_font))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2005-06-21 15:38:51 +00:00
|
|
|
/* XXX Why is this an ft specific function? */
|
2005-04-07 11:03:59 +00:00
|
|
|
unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font);
|
Change cairo_font_t to refer to a font scaled to a particular output device resolution.
src/cairoint.h src/cairo_font.c src/cairo_ft_font.c src/cairo_xlib_surface.c src/cairo_pdf_surface.c src/cairo_gstate.c src/cairo.c: Switch many internal methods from handling cairo_unscaled_font_t and cairo_font_scale_t pairs to handling cairo_font_t.
src/cairo-ft-private.h src/cairo_ft_fontc: Add some internal interfaces for use by the FreeType backend.
Clear the gstate's current font when the transform or target surface changes.
src/cairo.h src/cairo_ft_font.c: Rename cairo_ft_font_pattern to cairo_ft_font_get_pattern().
src/cairo.h src/cairo_ft_font.c: Make cairo_ft_font_create() and cairo_ft_font_create_for_ft_face() take a font scale; make the latter take load_flags for FT_Load_Glyph() as well. Change cairo_ft_font_face() to Xft-style cairo_ft_font_lock_face, cairo_ft_font_unlock_face.
Remove the name/slant/weight=>unscaled font cache, it didn't work with the new cairo_font_t setup. If it turns out to be needed, it can be added back in some other form.
src/cairoint.h src/cairo_font.c: Add a 'flags' field to cairo_glyph_cache_key_t, we use it for load flags with freetype backend.
Switch the caching to be from resolved fontconfig pattern => file; keep only a fixed number of FT_Face objects open at once, similar to FreeType.
src/cairo_gstate.c src/cairoint.h: Add public cairo_font_glyph_extents, use it to implement _cairo_gstate_glyph_extents().
Add refcounting for glyph cache elements; there was an bug where elements got ejected from the cache and freed before they could be used.
src/cairoint.h src/cairo_cache.c (_cairo_cache_random_entry()) New function to return a random entry in the cache matching a predicate; reuse the internals for the previous _random_live_entry().
src/cairoint.h src/cairo_cache.c (_cairo_cache_lookup()): Add an optional created_entry return value.
src/cairo_ft_font.c src/cairo_xlib_surface.c: Adapt to _cairo_cache_lookup() change.
Support max_memory == 0 to indicate an unbounded cache.
src/cairoint.h src/cairo_cache.c (_cairo_cache_remove()): Add a function to manually remove entries from the cache.
Update for changes, document cairo_matrix_t, cairo_glyph_t, etc.
src/cairo.h src/cairo-atsui.h src/cairo-ft.h src/cairo-glitz.h src/cairo-pdf.h src/cairo-png.h src/cairo-ps.h src/cairo-quartz.h src/cairo-xcb.h src/cairo-xlib.h: Add CAIRO_BEGIN/END_DECLS for extern "C", use it on all public headers. Move header guards outermost.
Fix encoding.
2005-01-21 14:33:47 +00:00
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
num_fonts = _cairo_array_num_elements (&document->fonts);
|
|
|
|
|
for (i = 0; i < num_fonts; i++) {
|
Change cairo_font_t to refer to a font scaled to a particular output device resolution.
src/cairoint.h src/cairo_font.c src/cairo_ft_font.c src/cairo_xlib_surface.c src/cairo_pdf_surface.c src/cairo_gstate.c src/cairo.c: Switch many internal methods from handling cairo_unscaled_font_t and cairo_font_scale_t pairs to handling cairo_font_t.
src/cairo-ft-private.h src/cairo_ft_fontc: Add some internal interfaces for use by the FreeType backend.
Clear the gstate's current font when the transform or target surface changes.
src/cairo.h src/cairo_ft_font.c: Rename cairo_ft_font_pattern to cairo_ft_font_get_pattern().
src/cairo.h src/cairo_ft_font.c: Make cairo_ft_font_create() and cairo_ft_font_create_for_ft_face() take a font scale; make the latter take load_flags for FT_Load_Glyph() as well. Change cairo_ft_font_face() to Xft-style cairo_ft_font_lock_face, cairo_ft_font_unlock_face.
Remove the name/slant/weight=>unscaled font cache, it didn't work with the new cairo_font_t setup. If it turns out to be needed, it can be added back in some other form.
src/cairoint.h src/cairo_font.c: Add a 'flags' field to cairo_glyph_cache_key_t, we use it for load flags with freetype backend.
Switch the caching to be from resolved fontconfig pattern => file; keep only a fixed number of FT_Face objects open at once, similar to FreeType.
src/cairo_gstate.c src/cairoint.h: Add public cairo_font_glyph_extents, use it to implement _cairo_gstate_glyph_extents().
Add refcounting for glyph cache elements; there was an bug where elements got ejected from the cache and freed before they could be used.
src/cairoint.h src/cairo_cache.c (_cairo_cache_random_entry()) New function to return a random entry in the cache matching a predicate; reuse the internals for the previous _random_live_entry().
src/cairoint.h src/cairo_cache.c (_cairo_cache_lookup()): Add an optional created_entry return value.
src/cairo_ft_font.c src/cairo_xlib_surface.c: Adapt to _cairo_cache_lookup() change.
Support max_memory == 0 to indicate an unbounded cache.
src/cairoint.h src/cairo_cache.c (_cairo_cache_remove()): Add a function to manually remove entries from the cache.
Update for changes, document cairo_matrix_t, cairo_glyph_t, etc.
src/cairo.h src/cairo-atsui.h src/cairo-ft.h src/cairo-glitz.h src/cairo-pdf.h src/cairo-png.h src/cairo-ps.h src/cairo-quartz.h src/cairo-xcb.h src/cairo-xlib.h: Add CAIRO_BEGIN/END_DECLS for extern "C", use it on all public headers. Move header guards outermost.
Fix encoding.
2005-01-21 14:33:47 +00:00
|
|
|
_cairo_array_copy_element (&document->fonts, i, &pdf_font);
|
|
|
|
|
if (pdf_font->unscaled_font == unscaled_font)
|
|
|
|
|
return pdf_font;
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME: Figure out here which font backend is in use and call
|
|
|
|
|
* the appropriate constructor. */
|
2005-06-21 15:38:51 +00:00
|
|
|
pdf_font = _cairo_font_subset_create (unscaled_font);
|
2005-01-25 10:56:50 +00:00
|
|
|
if (pdf_font == NULL)
|
2005-01-17 09:40:00 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
2005-06-21 15:38:51 +00:00
|
|
|
pdf_font->font_id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
|
2005-11-04 16:13:30 +00:00
|
|
|
status = _cairo_array_append (&document->fonts, &pdf_font);
|
|
|
|
|
if (status) {
|
2005-06-21 15:38:51 +00:00
|
|
|
_cairo_font_subset_destroy (pdf_font);
|
2005-01-17 09:40:00 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
Change cairo_font_t to refer to a font scaled to a particular output device resolution.
src/cairoint.h src/cairo_font.c src/cairo_ft_font.c src/cairo_xlib_surface.c src/cairo_pdf_surface.c src/cairo_gstate.c src/cairo.c: Switch many internal methods from handling cairo_unscaled_font_t and cairo_font_scale_t pairs to handling cairo_font_t.
src/cairo-ft-private.h src/cairo_ft_fontc: Add some internal interfaces for use by the FreeType backend.
Clear the gstate's current font when the transform or target surface changes.
src/cairo.h src/cairo_ft_font.c: Rename cairo_ft_font_pattern to cairo_ft_font_get_pattern().
src/cairo.h src/cairo_ft_font.c: Make cairo_ft_font_create() and cairo_ft_font_create_for_ft_face() take a font scale; make the latter take load_flags for FT_Load_Glyph() as well. Change cairo_ft_font_face() to Xft-style cairo_ft_font_lock_face, cairo_ft_font_unlock_face.
Remove the name/slant/weight=>unscaled font cache, it didn't work with the new cairo_font_t setup. If it turns out to be needed, it can be added back in some other form.
src/cairoint.h src/cairo_font.c: Add a 'flags' field to cairo_glyph_cache_key_t, we use it for load flags with freetype backend.
Switch the caching to be from resolved fontconfig pattern => file; keep only a fixed number of FT_Face objects open at once, similar to FreeType.
src/cairo_gstate.c src/cairoint.h: Add public cairo_font_glyph_extents, use it to implement _cairo_gstate_glyph_extents().
Add refcounting for glyph cache elements; there was an bug where elements got ejected from the cache and freed before they could be used.
src/cairoint.h src/cairo_cache.c (_cairo_cache_random_entry()) New function to return a random entry in the cache matching a predicate; reuse the internals for the previous _random_live_entry().
src/cairoint.h src/cairo_cache.c (_cairo_cache_lookup()): Add an optional created_entry return value.
src/cairo_ft_font.c src/cairo_xlib_surface.c: Adapt to _cairo_cache_lookup() change.
Support max_memory == 0 to indicate an unbounded cache.
src/cairoint.h src/cairo_cache.c (_cairo_cache_remove()): Add a function to manually remove entries from the cache.
Update for changes, document cairo_matrix_t, cairo_glyph_t, etc.
src/cairo.h src/cairo-atsui.h src/cairo-ft.h src/cairo-glitz.h src/cairo-pdf.h src/cairo-png.h src/cairo-ps.h src/cairo-quartz.h src/cairo-xcb.h src/cairo-xlib.h: Add CAIRO_BEGIN/END_DECLS for extern "C", use it on all public headers. Move header guards outermost.
Fix encoding.
2005-01-21 14:33:47 +00:00
|
|
|
return pdf_font;
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
2005-04-19 16:29:04 +00:00
|
|
|
static cairo_int_status_t
|
2005-11-01 16:40:37 +00:00
|
|
|
_cairo_pdf_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2005-11-01 16:40:37 +00:00
|
|
|
cairo_pattern_t *pattern,
|
|
|
|
|
void *abstract_surface,
|
|
|
|
|
int source_x,
|
|
|
|
|
int source_y,
|
|
|
|
|
int dest_x,
|
|
|
|
|
int dest_y,
|
|
|
|
|
unsigned int width,
|
|
|
|
|
unsigned int height,
|
|
|
|
|
const cairo_glyph_t *glyphs,
|
|
|
|
|
int num_glyphs)
|
2005-01-17 09:40:00 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = abstract_surface;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-06-21 15:38:51 +00:00
|
|
|
cairo_font_subset_t *pdf_font;
|
2005-10-07 13:21:01 +00:00
|
|
|
cairo_int_status_t status;
|
2005-01-17 09:40:00 +00:00
|
|
|
int i, index;
|
2005-08-19 14:05:14 +00:00
|
|
|
double det;
|
2005-01-17 09:40:00 +00:00
|
|
|
|
2005-07-13 11:01:25 +00:00
|
|
|
/* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
|
|
|
|
|
if (! _cairo_scaled_font_is_ft (scaled_font))
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
|
2005-04-07 11:03:59 +00:00
|
|
|
pdf_font = _cairo_pdf_document_get_font (document, scaled_font);
|
2005-01-17 09:40:00 +00:00
|
|
|
if (pdf_font == NULL)
|
|
|
|
|
return CAIRO_STATUS_NO_MEMORY;
|
|
|
|
|
|
2005-08-19 14:05:14 +00:00
|
|
|
/* Some PDF viewers (at least older versions of xpdf) have trouble with
|
|
|
|
|
* size 0 fonts. If the font size is less than 1/1000pt, ignore the
|
|
|
|
|
* font */
|
|
|
|
|
_cairo_matrix_compute_determinant (&scaled_font->scale, &det);
|
|
|
|
|
if (fabs (det) < 0.000001)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2005-10-07 13:21:01 +00:00
|
|
|
status = emit_pattern (surface, pattern);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
2005-01-17 09:40:00 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"BT /res%u 1 Tf", pdf_font->font_id);
|
2005-01-17 09:40:00 +00:00
|
|
|
for (i = 0; i < num_glyphs; i++) {
|
|
|
|
|
|
2005-06-21 15:38:51 +00:00
|
|
|
index = _cairo_font_subset_use_glyph (pdf_font, glyphs[i].index);
|
2005-01-17 09:40:00 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" %f %f %f %f %f %f Tm (\\%o) Tj",
|
2005-04-07 11:03:59 +00:00
|
|
|
scaled_font->scale.xx,
|
|
|
|
|
scaled_font->scale.yx,
|
2005-06-07 23:28:12 +00:00
|
|
|
-scaled_font->scale.xy,
|
2005-04-07 11:03:59 +00:00
|
|
|
-scaled_font->scale.yy,
|
2005-03-16 12:08:41 +00:00
|
|
|
glyphs[i].x,
|
|
|
|
|
glyphs[i].y,
|
|
|
|
|
index);
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" ET\r\n");
|
2005-01-17 09:40:00 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_surface_add_font (surface, pdf_font->font_id);
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-14 19:45:22 +00:00
|
|
|
static cairo_int_status_t
|
|
|
|
|
_cairo_pdf_surface_intersect_clip_path (void *dst,
|
|
|
|
|
cairo_path_fixed_t *path,
|
|
|
|
|
cairo_fill_rule_t fill_rule,
|
2005-08-08 18:35:22 +00:00
|
|
|
double tolerance,
|
|
|
|
|
cairo_antialias_t antialias)
|
2005-06-14 19:45:22 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_surface_t *surface = dst;
|
|
|
|
|
cairo_pdf_document_t *document = surface->document;
|
|
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
|
|
|
|
cairo_status_t status;
|
|
|
|
|
pdf_path_info_t info;
|
|
|
|
|
const char *pdf_operator;
|
|
|
|
|
|
|
|
|
|
_cairo_pdf_surface_ensure_stream (surface);
|
|
|
|
|
|
|
|
|
|
if (path == NULL) {
|
|
|
|
|
if (surface->has_clip)
|
|
|
|
|
_cairo_output_stream_printf (output, "Q\r\n");
|
|
|
|
|
surface->has_clip = FALSE;
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!surface->has_clip) {
|
|
|
|
|
_cairo_output_stream_printf (output, "q ");
|
|
|
|
|
surface->has_clip = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info.output_stream = document->output_stream;
|
|
|
|
|
info.has_current_point = FALSE;
|
|
|
|
|
|
|
|
|
|
status = _cairo_path_fixed_interpret (path,
|
|
|
|
|
CAIRO_DIRECTION_FORWARD,
|
|
|
|
|
_cairo_pdf_path_move_to,
|
|
|
|
|
_cairo_pdf_path_line_to,
|
|
|
|
|
_cairo_pdf_path_curve_to,
|
|
|
|
|
_cairo_pdf_path_close_path,
|
|
|
|
|
&info);
|
|
|
|
|
|
|
|
|
|
switch (fill_rule) {
|
|
|
|
|
case CAIRO_FILL_RULE_WINDING:
|
|
|
|
|
pdf_operator = "W";
|
|
|
|
|
break;
|
|
|
|
|
case CAIRO_FILL_RULE_EVEN_ODD:
|
|
|
|
|
pdf_operator = "W*";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ASSERT_NOT_REACHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (document->output_stream,
|
|
|
|
|
"%s n\r\n",
|
|
|
|
|
pdf_operator);
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-21 06:52:13 +00:00
|
|
|
static void
|
|
|
|
|
_cairo_pdf_surface_get_font_options (void *abstract_surface,
|
|
|
|
|
cairo_font_options_t *options)
|
|
|
|
|
{
|
|
|
|
|
_cairo_font_options_init_default (options);
|
|
|
|
|
|
|
|
|
|
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
|
|
|
|
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
|
|
|
|
_cairo_pdf_surface_create_similar,
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_pdf_surface_finish,
|
2005-04-07 14:25:00 +00:00
|
|
|
NULL, /* acquire_source_image */
|
|
|
|
|
NULL, /* release_source_image */
|
|
|
|
|
NULL, /* acquire_dest_image */
|
|
|
|
|
NULL, /* release_dest_image */
|
|
|
|
|
NULL, /* clone_similar */
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_surface_composite,
|
|
|
|
|
_cairo_pdf_surface_fill_rectangles,
|
|
|
|
|
_cairo_pdf_surface_composite_trapezoids,
|
|
|
|
|
_cairo_pdf_surface_copy_page,
|
|
|
|
|
_cairo_pdf_surface_show_page,
|
2005-04-07 14:25:00 +00:00
|
|
|
NULL, /* set_clip_region */
|
2005-06-14 19:45:22 +00:00
|
|
|
_cairo_pdf_surface_intersect_clip_path,
|
2005-04-19 16:29:04 +00:00
|
|
|
_cairo_pdf_surface_get_extents,
|
2005-11-01 16:40:37 +00:00
|
|
|
_cairo_pdf_surface_old_show_glyphs,
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
_cairo_pdf_surface_get_font_options,
|
|
|
|
|
NULL, /* flush */
|
|
|
|
|
NULL, /* mark_dirty_rectangle */
|
|
|
|
|
NULL, /* scaled_font_fini */
|
|
|
|
|
NULL, /* scaled_glyph_fini */
|
|
|
|
|
|
|
|
|
|
/* Here are the drawing functions */
|
|
|
|
|
|
|
|
|
|
NULL, /* paint */
|
|
|
|
|
NULL, /* mask */
|
|
|
|
|
NULL, /* stroke */
|
|
|
|
|
_cairo_pdf_surface_fill,
|
|
|
|
|
NULL /* show_glyphs */
|
2005-01-05 14:29:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static cairo_pdf_document_t *
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_pdf_document_create (cairo_output_stream_t *output_stream,
|
2005-05-13 09:26:20 +00:00
|
|
|
double width,
|
|
|
|
|
double height)
|
2005-01-05 14:29:31 +00:00
|
|
|
{
|
|
|
|
|
cairo_pdf_document_t *document;
|
|
|
|
|
|
|
|
|
|
document = malloc (sizeof (cairo_pdf_document_t));
|
|
|
|
|
if (document == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
document->output_stream = output_stream;
|
2005-07-25 16:23:05 +00:00
|
|
|
document->ref_count = 1;
|
2005-03-16 12:08:41 +00:00
|
|
|
document->owner = NULL;
|
|
|
|
|
document->finished = FALSE;
|
2005-05-13 09:26:20 +00:00
|
|
|
document->width = width;
|
|
|
|
|
document->height = height;
|
2005-05-16 11:41:42 +00:00
|
|
|
document->x_dpi = DEFAULT_DPI;
|
|
|
|
|
document->y_dpi = DEFAULT_DPI;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
_cairo_array_init (&document->objects, sizeof (cairo_pdf_object_t));
|
|
|
|
|
_cairo_array_init (&document->pages, sizeof (unsigned int));
|
|
|
|
|
document->next_available_id = 1;
|
|
|
|
|
|
|
|
|
|
document->current_stream = NULL;
|
|
|
|
|
|
|
|
|
|
document->pages_id = _cairo_pdf_document_new_object (document);
|
|
|
|
|
|
2005-06-21 15:38:51 +00:00
|
|
|
_cairo_array_init (&document->fonts, sizeof (cairo_font_subset_t *));
|
2005-01-17 09:40:00 +00:00
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
/* Document header */
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output_stream,
|
|
|
|
|
"%%PDF-1.4\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return document;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
_cairo_pdf_document_write_info (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int id;
|
|
|
|
|
|
|
|
|
|
id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Creator (cairographics.org)\r\n"
|
|
|
|
|
" /Producer (cairographics.org)\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n",
|
|
|
|
|
id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_document_write_pages (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *stream = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int page_id;
|
|
|
|
|
int num_pages, i;
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
_cairo_pdf_document_update_object (document, document->pages_id);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (stream,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /Pages\r\n"
|
|
|
|
|
" /Kids [ ",
|
|
|
|
|
document->pages_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
num_pages = _cairo_array_num_elements (&document->pages);
|
|
|
|
|
for (i = 0; i < num_pages; i++) {
|
|
|
|
|
_cairo_array_copy_element (&document->pages, i, &page_id);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (stream, "%d 0 R ", page_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (stream, "]\r\n");
|
|
|
|
|
_cairo_output_stream_printf (stream, " /Count %d\r\n", num_pages);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
/* TODO: Figure out wich other defaults to be inherited by /Page
|
|
|
|
|
* objects. */
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (stream,
|
|
|
|
|
" /MediaBox [ 0 0 %f %f ]\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n",
|
2005-05-13 09:26:20 +00:00
|
|
|
document->width,
|
|
|
|
|
document->height);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_document_write_fonts (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-06-21 15:38:51 +00:00
|
|
|
cairo_font_subset_t *font;
|
2005-01-17 09:40:00 +00:00
|
|
|
int num_fonts, i, j;
|
|
|
|
|
const char *data;
|
|
|
|
|
char *compressed;
|
|
|
|
|
unsigned long data_size, compressed_size;
|
|
|
|
|
unsigned int stream_id, descriptor_id;
|
|
|
|
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
|
|
num_fonts = _cairo_array_num_elements (&document->fonts);
|
|
|
|
|
for (i = 0; i < num_fonts; i++) {
|
|
|
|
|
_cairo_array_copy_element (&document->fonts, i, &font);
|
|
|
|
|
|
2005-06-21 15:38:51 +00:00
|
|
|
status = _cairo_font_subset_generate (font, &data, &data_size);
|
2005-01-17 09:40:00 +00:00
|
|
|
if (status)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
compressed = compress_dup (data, data_size, &compressed_size);
|
|
|
|
|
if (compressed == NULL) {
|
|
|
|
|
status = CAIRO_STATUS_NO_MEMORY;
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stream_id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Filter /FlateDecode\r\n"
|
|
|
|
|
" /Length %lu\r\n"
|
|
|
|
|
" /Length1 %lu\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"stream\r\n",
|
|
|
|
|
stream_id,
|
|
|
|
|
compressed_size,
|
|
|
|
|
data_size);
|
|
|
|
|
_cairo_output_stream_write (output, compressed, compressed_size);
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"\r\n"
|
|
|
|
|
"endstream\r\n"
|
|
|
|
|
"endobj\r\n");
|
2005-01-17 09:40:00 +00:00
|
|
|
free (compressed);
|
|
|
|
|
|
|
|
|
|
descriptor_id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /FontDescriptor\r\n"
|
|
|
|
|
" /FontName /7%s\r\n"
|
|
|
|
|
" /Flags 4\r\n"
|
|
|
|
|
" /FontBBox [ %ld %ld %ld %ld ]\r\n"
|
|
|
|
|
" /ItalicAngle 0\r\n"
|
|
|
|
|
" /Ascent %ld\r\n"
|
|
|
|
|
" /Descent %ld\r\n"
|
|
|
|
|
" /CapHeight 500\r\n"
|
|
|
|
|
" /StemV 80\r\n"
|
|
|
|
|
" /StemH 80\r\n"
|
|
|
|
|
" /FontFile2 %u 0 R\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n",
|
|
|
|
|
descriptor_id,
|
|
|
|
|
font->base_font,
|
|
|
|
|
font->x_min,
|
|
|
|
|
font->y_min,
|
|
|
|
|
font->x_max,
|
|
|
|
|
font->y_max,
|
|
|
|
|
font->ascent,
|
|
|
|
|
font->descent,
|
|
|
|
|
stream_id);
|
2005-01-17 09:40:00 +00:00
|
|
|
|
|
|
|
|
_cairo_pdf_document_update_object (document, font->font_id);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /Font\r\n"
|
|
|
|
|
" /Subtype /TrueType\r\n"
|
|
|
|
|
" /BaseFont /%s\r\n"
|
|
|
|
|
" /FirstChar 0\r\n"
|
|
|
|
|
" /LastChar %d\r\n"
|
|
|
|
|
" /FontDescriptor %d 0 R\r\n"
|
|
|
|
|
" /Widths ",
|
|
|
|
|
font->font_id,
|
|
|
|
|
font->base_font,
|
|
|
|
|
font->num_glyphs,
|
|
|
|
|
descriptor_id);
|
|
|
|
|
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"[");
|
2005-01-17 09:40:00 +00:00
|
|
|
|
|
|
|
|
for (j = 0; j < font->num_glyphs; j++)
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" %d",
|
|
|
|
|
font->widths[j]);
|
2005-01-17 09:40:00 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" ]\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n");
|
2005-01-17 09:40:00 +00:00
|
|
|
|
|
|
|
|
fail:
|
2005-06-21 15:38:51 +00:00
|
|
|
_cairo_font_subset_destroy (font);
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
static unsigned int
|
|
|
|
|
_cairo_pdf_document_write_catalog (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int id;
|
|
|
|
|
|
|
|
|
|
id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /Catalog\r\n"
|
|
|
|
|
" /Pages %d 0 R\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n",
|
|
|
|
|
id, document->pages_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static long
|
|
|
|
|
_cairo_pdf_document_write_xref (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_object_t *object;
|
|
|
|
|
int num_objects, i;
|
|
|
|
|
long offset;
|
2005-05-13 14:04:22 +00:00
|
|
|
char buffer[11];
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
num_objects = _cairo_array_num_elements (&document->objects);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
offset = _cairo_output_stream_get_position (output);
|
|
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"xref\r\n"
|
|
|
|
|
"%d %d\r\n",
|
|
|
|
|
0, num_objects + 1);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"0000000000 65535 f\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
for (i = 0; i < num_objects; i++) {
|
|
|
|
|
object = _cairo_array_index (&document->objects, i);
|
2005-05-13 14:04:22 +00:00
|
|
|
snprintf (buffer, sizeof buffer, "%010ld", object->offset);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
2005-05-13 14:04:22 +00:00
|
|
|
"%s 00000 n\r\n", buffer);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-04 18:44:29 +00:00
|
|
|
static cairo_pdf_document_t *
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_reference (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-07-25 16:23:05 +00:00
|
|
|
document->ref_count++;
|
2005-08-04 18:44:29 +00:00
|
|
|
|
|
|
|
|
return document;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_pdf_document_destroy (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-07-25 16:23:05 +00:00
|
|
|
document->ref_count--;
|
|
|
|
|
if (document->ref_count > 0)
|
2005-01-05 14:29:31 +00:00
|
|
|
return;
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_pdf_document_finish (document);
|
|
|
|
|
|
|
|
|
|
free (document);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_document_finish (cairo_pdf_document_t *document)
|
|
|
|
|
{
|
2005-05-17 12:40:55 +00:00
|
|
|
cairo_status_t status;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
|
|
|
|
long offset;
|
|
|
|
|
unsigned int info_id, catalog_id;
|
|
|
|
|
|
|
|
|
|
if (document->finished)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
_cairo_pdf_document_write_pages (document);
|
2005-01-17 09:40:00 +00:00
|
|
|
_cairo_pdf_document_write_fonts (document);
|
2005-01-05 14:29:31 +00:00
|
|
|
info_id = _cairo_pdf_document_write_info (document);
|
|
|
|
|
catalog_id = _cairo_pdf_document_write_catalog (document);
|
|
|
|
|
offset = _cairo_pdf_document_write_xref (document);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"trailer\r\n"
|
|
|
|
|
"<< /Size %d\r\n"
|
|
|
|
|
" /Root %d 0 R\r\n"
|
|
|
|
|
" /Info %d 0 R\r\n"
|
|
|
|
|
">>\r\n",
|
|
|
|
|
document->next_available_id,
|
|
|
|
|
catalog_id,
|
|
|
|
|
info_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"startxref\r\n"
|
|
|
|
|
"%ld\r\n"
|
|
|
|
|
"%%%%EOF\r\n",
|
|
|
|
|
offset);
|
|
|
|
|
|
2005-05-17 12:40:55 +00:00
|
|
|
status = _cairo_output_stream_get_status (output);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_destroy (output);
|
2005-05-17 12:40:55 +00:00
|
|
|
|
2005-07-14 17:52:17 +00:00
|
|
|
_cairo_array_fini (&document->objects);
|
|
|
|
|
_cairo_array_fini (&document->pages);
|
|
|
|
|
_cairo_array_fini (&document->fonts);
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
document->finished = TRUE;
|
|
|
|
|
|
2005-05-17 12:40:55 +00:00
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_status_t
|
|
|
|
|
_cairo_pdf_document_add_page (cairo_pdf_document_t *document,
|
|
|
|
|
cairo_pdf_surface_t *surface)
|
|
|
|
|
{
|
2005-11-04 16:13:30 +00:00
|
|
|
cairo_status_t status;
|
2005-01-05 14:29:31 +00:00
|
|
|
cairo_pdf_stream_t *stream;
|
|
|
|
|
cairo_pdf_resource_t *res;
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_output_stream_t *output = document->output_stream;
|
2005-01-05 14:29:31 +00:00
|
|
|
unsigned int page_id;
|
|
|
|
|
double alpha;
|
|
|
|
|
int num_streams, num_alphas, num_resources, i;
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
assert (!document->finished);
|
|
|
|
|
|
2005-06-14 19:45:22 +00:00
|
|
|
_cairo_pdf_surface_ensure_stream (surface);
|
|
|
|
|
|
|
|
|
|
if (surface->has_clip)
|
|
|
|
|
_cairo_output_stream_printf (output, "Q\r\n");
|
|
|
|
|
|
2005-01-05 14:29:31 +00:00
|
|
|
_cairo_pdf_document_close_stream (document);
|
|
|
|
|
|
|
|
|
|
page_id = _cairo_pdf_document_new_object (document);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
"%d 0 obj\r\n"
|
|
|
|
|
"<< /Type /Page\r\n"
|
|
|
|
|
" /Parent %d 0 R\r\n"
|
|
|
|
|
" /Contents [",
|
|
|
|
|
page_id,
|
|
|
|
|
document->pages_id);
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
num_streams = _cairo_array_num_elements (&surface->streams);
|
|
|
|
|
for (i = 0; i < num_streams; i++) {
|
|
|
|
|
_cairo_array_copy_element (&surface->streams, i, &stream);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" %d 0 R",
|
|
|
|
|
stream->id);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" ]\r\n"
|
|
|
|
|
" /Resources <<\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-01-17 09:40:00 +00:00
|
|
|
num_resources = _cairo_array_num_elements (&surface->fonts);
|
|
|
|
|
if (num_resources > 0) {
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /Font <<");
|
2005-01-17 09:40:00 +00:00
|
|
|
|
|
|
|
|
for (i = 0; i < num_resources; i++) {
|
|
|
|
|
res = _cairo_array_index (&surface->fonts, i);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /res%d %d 0 R",
|
|
|
|
|
res->id, res->id);
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" >>\r\n");
|
2005-01-17 09:40:00 +00:00
|
|
|
}
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
num_alphas = _cairo_array_num_elements (&surface->alphas);
|
|
|
|
|
if (num_alphas > 0) {
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /ExtGState <<\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
for (i = 0; i < num_alphas; i++) {
|
|
|
|
|
_cairo_array_copy_element (&surface->alphas, i, &alpha);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /a%d << /ca %f >>\r\n",
|
|
|
|
|
i, alpha);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" >>\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
num_resources = _cairo_array_num_elements (&surface->patterns);
|
|
|
|
|
if (num_resources > 0) {
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /Pattern <<");
|
2005-01-05 14:29:31 +00:00
|
|
|
for (i = 0; i < num_resources; i++) {
|
|
|
|
|
res = _cairo_array_index (&surface->patterns, i);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /res%d %d 0 R",
|
|
|
|
|
res->id, res->id);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" >>\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
num_resources = _cairo_array_num_elements (&surface->xobjects);
|
|
|
|
|
if (num_resources > 0) {
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /XObject <<");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
for (i = 0; i < num_resources; i++) {
|
|
|
|
|
res = _cairo_array_index (&surface->xobjects, i);
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" /res%d %d 0 R",
|
|
|
|
|
res->id, res->id);
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" >>\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
_cairo_output_stream_printf (output,
|
|
|
|
|
" >>\r\n"
|
|
|
|
|
">>\r\n"
|
|
|
|
|
"endobj\r\n");
|
2005-01-05 14:29:31 +00:00
|
|
|
|
2005-11-04 16:13:30 +00:00
|
|
|
status = _cairo_array_append (&document->pages, &page_id);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
2005-01-05 14:29:31 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|