[cairo-commit] src/cairo-svg.h src/cairo-svg-surface.c
Bryce Harrington
bryce at kemper.freedesktop.org
Mon Dec 4 22:01:33 UTC 2017
src/cairo-svg-surface.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++--
src/cairo-svg.h | 47 ++++++++++++++++++++++++++
2 files changed, 129 insertions(+), 2 deletions(-)
New commits:
commit 15559b54af473d720da9e03b0e769c54a53505a9
Author: Antonio Ospite <ao2 at ao2.it>
Date: Wed Oct 11 18:51:13 2017 +0200
svg: add a new function to specify the SVG document unit
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 <svg> element.
In particular this allows to draw in pixels and still have the expected
result when generating SVG output.
Add also the correspondent getter function.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=90166
Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 29bdd8c0..0853360a 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -122,6 +122,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_USER] = "",
+ [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] = "%"
+};
+
struct cairo_svg_page {
unsigned int surface_id;
unsigned int clip_level;
@@ -136,6 +150,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;
@@ -405,6 +420,69 @@ 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 unit 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 can 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, to
+ * make it clearer what the unit used in the drawing operations is.
+ *
+ * The simplest way to do this is to call this function immediately after
+ * creating the SVG surface.
+ *
+ * NOTE: if this function is never called, the default unit for SVG documents
+ * generated by cairo will be "pt". This is for historical reasons.
+ *
+ * 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_PERCENT)
+ surface->document->unit = unit;
+}
+
+/**
+ * cairo_svg_surface_get_document_unit:
+ * @surface: a SVG #cairo_surface_t
+ *
+ * Get the unit of the SVG surface.
+ *
+ * If the surface passed as an argument is not a SVG surface, the function
+ * sets the error status to CAIRO_STATUS_SURFACE_TYPE_MISMATCH and returns
+ * CAIRO_SVG_UNIT_USER.
+ *
+ * Return value: the SVG unit of the SVG surface.
+ *
+ * Since: 1.16
+ **/
+cairo_svg_unit_t
+cairo_svg_surface_get_document_unit (cairo_surface_t *abstract_surface)
+{
+ cairo_svg_surface_t *surface = NULL; /* hide compiler warning */
+
+ if (! _extract_svg_surface (abstract_surface, &surface)) {
+ _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+ return CAIRO_SVG_UNIT_USER;
+ }
+
+ return surface->document->unit;
+}
+
static void
_cairo_svg_source_surface_init_key (cairo_svg_source_surface_t *key)
{
@@ -2801,6 +2879,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;
@@ -2903,9 +2982,10 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<svg xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
- "width=\"%fpt\" height=\"%fpt\" "
+ "width=\"%f%s\" height=\"%f%s\" "
"viewBox=\"0 0 %f %f\" version=\"%s\">\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 592c645f..95434dcf 100644
--- a/src/cairo-svg.h
+++ b/src/cairo-svg.h
@@ -53,6 +53,46 @@ typedef enum _cairo_svg_version {
CAIRO_SVG_VERSION_1_2
} cairo_svg_version_t;
+/**
+ * cairo_svg_version_t:
+ *
+ * @CAIRO_SVG_UNIT_USER: User unit, a value in the current coordinate system.
+ * If used in the root element for the initial coordinate systems it
+ * corresponds to pixels. (Since 1.16)
+ * @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_t is used to describe the units valid for coordinates and
+ * lengths in the SVG specification.
+ *
+ * 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_USER = 0,
+ 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_t;
+
cairo_public cairo_surface_t *
cairo_svg_surface_create (const char *filename,
double width_in_points,
@@ -75,6 +115,13 @@ 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_public cairo_svg_unit_t
+cairo_svg_surface_get_document_unit (cairo_surface_t *surface);
+
CAIRO_END_DECLS
#else /* CAIRO_HAS_SVG_SURFACE */
More information about the cairo-commit
mailing list