From b8059bf18609fe674048ac9e2ca25790a1714390 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 11 Oct 2017 18:51:13 +0200 Subject: [PATCH] svg: add a new function to specify the SVG document units X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE Add a cairo_svg_surface_set_document_unit() function to allow users to set a unit for the width and height values of the root element. In particular this allows to draw in pixels and still have the expected result when generating SVG output. https://bugs.freedesktop.org/show_bug.cgi?id=90166 --- src/cairo-svg-surface.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-- src/cairo-svg.h | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index a9b32e6d8..aa103a949 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -121,6 +121,20 @@ static const char * _cairo_svg_internal_version_strings[CAIRO_SVG_VERSION_LAST] "1.2" }; +static const char * _cairo_svg_unit_strings[] = +{ + [CAIRO_SVG_UNIT_EM] = "em", + [CAIRO_SVG_UNIT_EX] = "ex", + [CAIRO_SVG_UNIT_PX] = "px", + [CAIRO_SVG_UNIT_IN] = "in", + [CAIRO_SVG_UNIT_CM] = "cm", + [CAIRO_SVG_UNIT_MM] = "mm", + [CAIRO_SVG_UNIT_PT] = "pt", + [CAIRO_SVG_UNIT_PC] = "pc", + [CAIRO_SVG_UNIT_PERCENT] = "%", + [CAIRO_SVG_UNIT_USER] = "" +}; + struct cairo_svg_page { unsigned int surface_id; unsigned int clip_level; @@ -135,6 +149,7 @@ struct cairo_svg_document { double width; double height; + cairo_svg_unit_t unit; cairo_output_stream_t *xml_node_defs; cairo_output_stream_t *xml_node_glyphs; @@ -401,6 +416,37 @@ cairo_svg_version_to_string (cairo_svg_version_t version) return _cairo_svg_version_strings[version]; } +/** + * cairo_svg_surface_set_document_unit: + * @surface: a SVG #cairo_surface_t + * @unit: SVG unit + * + * Use the specified units for the width and height of the generated SVG file. + * See #cairo_svg_unit_t for a list of available unit values that can be used + * here. + * + * This function may be called at any time before generating the SVG file. + * + * However to minimize the risk of ambiguities it's recommended to call it + * before any drawing operations have been performed on the given surface. The + * simplest way to do this is to call this function immediately after creating + * the SVG surface. + * + * Since: 1.16 + **/ +void +cairo_svg_surface_set_document_unit (cairo_surface_t *abstract_surface, + cairo_svg_unit_t unit) +{ + cairo_svg_surface_t *surface = NULL; /* hide compiler warning */ + + if (! _extract_svg_surface (abstract_surface, &surface)) + return; + + if (unit <= CAIRO_SVG_UNIT_USER) + surface->document->unit = unit; +} + static cairo_bool_t _cliprect_covers_surface (cairo_svg_surface_t *surface, cairo_path_fixed_t *path) @@ -2688,6 +2734,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, document->finished = FALSE; document->width = width; document->height = height; + document->unit = CAIRO_SVG_UNIT_PT; document->linear_pattern_id = 0; document->radial_pattern_id = 0; @@ -2790,9 +2837,10 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) "\n" "\n", - document->width, document->height, + document->width, _cairo_svg_unit_strings [document->unit], + document->height, _cairo_svg_unit_strings [document->unit], document->width, document->height, _cairo_svg_internal_version_strings [document->svg_version]); diff --git a/src/cairo-svg.h b/src/cairo-svg.h index 592c645f6..51fc8148e 100644 --- a/src/cairo-svg.h +++ b/src/cairo-svg.h @@ -53,6 +53,42 @@ typedef enum _cairo_svg_version { CAIRO_SVG_VERSION_1_2 } cairo_svg_version_t; +/** + * cairo_svg_version_t: + * @CAIRO_SVG_UNIT_EM: The size of the element's font. (Since 1.16) + * @CAIRO_SVG_UNIT_EX: The x-height of the element’s font. (Since 1.16) + * @CAIRO_SVG_UNIT_PX: Pixels (1px = 1/96th of 1in). (Since 1.16) + * @CAIRO_SVG_UNIT_IN: Inches (1in = 2.54cm = 96px). (Since 1.16) + * @CAIRO_SVG_UNIT_CM: Centimeters (1cm = 96px/2.54). (Since 1.16) + * @CAIRO_SVG_UNIT_MM: Millimeters (1mm = 1/10th of 1cm). (Since 1.16) + * @CAIRO_SVG_UNIT_PT: Points (1pt = 1/72th of 1in). (Since 1.16) + * @CAIRO_SVG_UNIT_PC: Picas (1pc = 1/6th of 1in). (Since 1.16) + * @CAIRO_SVG_UNIT_PERCENT: Percent, a value that is some fraction of another reference value. (Since 1.16) + * @CAIRO_SVG_UNIT_USER: User units, corresponds to pixels in the initial coordinate system. (Since 1.16) + * + * #cairo_svg_unit_t is used to describe the unit identifiers for coordinates + * and lengths in SVG. + * + * See also: + * https://www.w3.org/TR/SVG/coords.html#Units + * https://www.w3.org/TR/SVG/types.html#DataTypeLength + * https://www.w3.org/TR/css-values-3/#lengths + * + * Since: 1.16 + **/ +typedef enum _cairo_svg_unit { + CAIRO_SVG_UNIT_EM, + CAIRO_SVG_UNIT_EX, + CAIRO_SVG_UNIT_PX, + CAIRO_SVG_UNIT_IN, + CAIRO_SVG_UNIT_CM, + CAIRO_SVG_UNIT_MM, + CAIRO_SVG_UNIT_PT, + CAIRO_SVG_UNIT_PC, + CAIRO_SVG_UNIT_PERCENT, + CAIRO_SVG_UNIT_USER +} cairo_svg_unit_t; + cairo_public cairo_surface_t * cairo_svg_surface_create (const char *filename, double width_in_points, @@ -75,6 +111,10 @@ cairo_svg_get_versions (cairo_svg_version_t const **versions, cairo_public const char * cairo_svg_version_to_string (cairo_svg_version_t version); +cairo_public void +cairo_svg_surface_set_document_unit (cairo_surface_t *surface, + cairo_svg_unit_t unit); + CAIRO_END_DECLS #else /* CAIRO_HAS_SVG_SURFACE */ -- 2.15.0.rc0