mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-18 05:20:28 +01:00
SVG: First pass for analyze-surface support
This commit is contained in:
parent
0625d4cd3f
commit
59dcb95ce5
1 changed files with 85 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
* Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
|
||||
* Copyright © 2005-2006 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
#include "cairo-svg.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-ft-private.h"
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
|
||||
#include <libxml/tree.h>
|
||||
|
||||
|
|
@ -98,6 +99,8 @@ struct cairo_svg_surface {
|
|||
|
||||
cairo_bool_t modified;
|
||||
unsigned int previous_id;
|
||||
|
||||
cairo_paginated_mode_t paginated_mode;
|
||||
};
|
||||
|
||||
static cairo_svg_document_t *
|
||||
|
|
@ -120,6 +123,10 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
|||
double width,
|
||||
double height);
|
||||
|
||||
static void
|
||||
_cairo_svg_set_paginated_mode (cairo_surface_t *target,
|
||||
cairo_paginated_mode_t mode);
|
||||
|
||||
static const cairo_surface_backend_t cairo_svg_surface_backend;
|
||||
|
||||
static cairo_surface_t *
|
||||
|
|
@ -131,8 +138,10 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
|||
cairo_surface_t *surface;
|
||||
|
||||
document = _cairo_svg_document_create (stream, width, height);
|
||||
if (document == NULL)
|
||||
return NULL;
|
||||
if (document == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
width, height);
|
||||
|
|
@ -140,7 +149,10 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
|||
document->owner = surface;
|
||||
_cairo_svg_document_destroy (document);
|
||||
|
||||
return surface;
|
||||
return _cairo_paginated_surface_create (surface,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
width, height,
|
||||
_cairo_svg_set_paginated_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -215,6 +227,12 @@ cairo_svg_surface_create (const char *filename,
|
|||
return _cairo_svg_surface_create_for_stream_internal (stream, width, height);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_surface_is_svg (cairo_surface_t *surface)
|
||||
{
|
||||
return surface->backend == &cairo_svg_surface_backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_svg_surface_set_dpi:
|
||||
* @surface: a svg cairo_surface_t
|
||||
|
|
@ -225,14 +243,30 @@ cairo_svg_surface_create (const char *filename,
|
|||
* When the svg 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_svg_surface_create() nor on the CTM).
|
||||
* passed to cairo_pdf_surface_create() nor on the CTM).
|
||||
**/
|
||||
|
||||
void
|
||||
cairo_svg_surface_set_dpi (cairo_surface_t *surface,
|
||||
double x_dpi,
|
||||
double y_dpi)
|
||||
{
|
||||
cairo_svg_surface_t *svg_surface = (cairo_svg_surface_t *) surface;
|
||||
cairo_surface_t *target;
|
||||
cairo_svg_surface_t *svg_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_svg (target)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
svg_surface = (cairo_svg_surface_t *) target;
|
||||
|
||||
svg_surface->document->x_dpi = x_dpi;
|
||||
svg_surface->document->y_dpi = y_dpi;
|
||||
|
|
@ -296,6 +330,8 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
|||
surface->previous_id = surface->id;
|
||||
surface->content = content;
|
||||
|
||||
surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
|
||||
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +369,21 @@ _cairo_svg_surface_finish (void *abstract_surface)
|
|||
return status;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
operator_supported (cairo_operator_t op)
|
||||
{
|
||||
return (op == CAIRO_OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
operator_analyze (cairo_operator_t op)
|
||||
{
|
||||
if (operator_supported (op))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
else
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_alpha_filter (cairo_svg_document_t *document)
|
||||
{
|
||||
|
|
@ -595,7 +646,7 @@ emit_composite_pattern (xmlNodePtr node,
|
|||
double *height,
|
||||
int is_pattern)
|
||||
{
|
||||
if (pattern->surface->backend == &cairo_svg_surface_backend)
|
||||
if (_cairo_surface_is_svg (pattern->surface))
|
||||
return emit_composite_svg_pattern (node, pattern, width, height, is_pattern);
|
||||
else
|
||||
return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
|
||||
|
|
@ -994,6 +1045,9 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
xmlNodePtr child;
|
||||
xmlBufferPtr style;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return operator_analyze (op);
|
||||
|
||||
info.document = document;
|
||||
info.path = xmlBufferCreate ();
|
||||
|
||||
|
|
@ -1115,6 +1169,9 @@ _cairo_svg_surface_paint (void *abstract_surface,
|
|||
}
|
||||
}
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return operator_analyze (op);
|
||||
|
||||
emit_paint (surface->xml_node, surface, op, source);
|
||||
|
||||
surface->modified = TRUE;
|
||||
|
|
@ -1134,6 +1191,9 @@ _cairo_svg_surface_mask (void *abstract_surface,
|
|||
|
||||
emit_alpha_filter (document);
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return operator_analyze (op);
|
||||
|
||||
mask_node = xmlNewNode (NULL, CC2XML ("mask"));
|
||||
snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
|
||||
xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
|
||||
|
|
@ -1177,6 +1237,9 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
|||
unsigned int i;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return operator_analyze (op);
|
||||
|
||||
info.document = document;
|
||||
info.path = xmlBufferCreate ();
|
||||
|
||||
|
|
@ -1272,6 +1335,9 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
|||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return operator_analyze (op);
|
||||
|
||||
/* FIXME: We don't really want to keep this as is. There's to possibilities:
|
||||
* - Use SVG fonts. But support for them seems very rare in SVG renderers.
|
||||
|
|
@ -1311,6 +1377,9 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
|
|||
svg_path_info_t info;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (path == NULL) {
|
||||
surface->xml_node = surface->xml_root_node;
|
||||
surface->clip_level = 0;
|
||||
|
|
@ -1505,3 +1574,12 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_svg_set_paginated_mode (cairo_surface_t *target,
|
||||
cairo_paginated_mode_t paginated_mode)
|
||||
{
|
||||
cairo_svg_surface_t *surface = (cairo_svg_surface_t *) target;
|
||||
|
||||
surface->paginated_mode = paginated_mode;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue