[librsvg/rustification] length.rs: New file with RsvgLength and a public rsvg_length_parse()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustification] length.rs: New file with RsvgLength and a public rsvg_length_parse()
- Date: Fri, 11 Nov 2016 01:15:00 +0000 (UTC)
commit 03d7716b4dd2e4e7cb04f58b14f00d2bff42c0d4
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Nov 10 19:12:21 2016 -0600
length.rs: New file with RsvgLength and a public rsvg_length_parse()
This is the parser for SVG length values, converted to Rust.
The new rsvg_length_parse() replaces the old _rsvg_css_parse_length()
throughout the code.
rsvg-css.c | 127 ----------------------
rsvg-filter.c | 44 ++++----
rsvg-image.c | 10 +-
rsvg-marker.c | 12 +-
rsvg-mask.c | 16 ++--
rsvg-paint-server.c | 38 ++++----
rsvg-private.h | 8 ++-
rsvg-shapes.c | 42 ++++----
rsvg-structure.c | 32 +++---
rsvg-styles.c | 16 ++--
rsvg-text.c | 12 +-
rust/src/length.rs | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++
rust/src/lib.rs | 10 ++
13 files changed, 428 insertions(+), 239 deletions(-)
---
diff --git a/rsvg-css.c b/rsvg-css.c
index 2280776..e132d7a 100644
--- a/rsvg-css.c
+++ b/rsvg-css.c
@@ -91,133 +91,6 @@ rsvg_css_parse_vbox (const char *vbox)
}
}
-typedef enum _RelativeSize {
- RELATIVE_SIZE_NORMAL,
- RELATIVE_SIZE_SMALLER,
- RELATIVE_SIZE_LARGER
-} RelativeSize;
-
-static double
-rsvg_css_parse_raw_length (const char *str, gboolean * in,
- gboolean * percent, gboolean * em, gboolean * ex, RelativeSize * relative_size)
-{
- double length = 0.0;
- char *p = NULL;
-
- /*
- * The supported CSS length unit specifiers are:
- * em, ex, px, pt, pc, cm, mm, in, and %
- */
- *percent = FALSE;
- *em = FALSE;
- *ex = FALSE;
- *relative_size = RELATIVE_SIZE_NORMAL;
-
- length = g_ascii_strtod (str, &p);
-
- if ((length == -HUGE_VAL || length == HUGE_VAL) && (ERANGE == errno)) {
- /* todo: error condition - figure out how to best represent it */
- return 0.0;
- }
-
- /* test for either pixels or no unit, which is assumed to be pixels */
- if (p && *p && (strcmp (p, "px") != 0)) {
- if (!strcmp (p, "pt")) {
- length /= POINTS_PER_INCH;
- *in = TRUE;
- } else if (!strcmp (p, "in"))
- *in = TRUE;
- else if (!strcmp (p, "cm")) {
- length /= CM_PER_INCH;
- *in = TRUE;
- } else if (!strcmp (p, "mm")) {
- length /= MM_PER_INCH;
- *in = TRUE;
- } else if (!strcmp (p, "pc")) {
- length /= PICA_PER_INCH;
- *in = TRUE;
- } else if (!strcmp (p, "em"))
- *em = TRUE;
- else if (!strcmp (p, "ex"))
- *ex = TRUE;
- else if (!strcmp (p, "%")) {
- *percent = TRUE;
- length *= 0.01;
- } else {
- double pow_factor = 0.0;
-
- if (!g_ascii_strcasecmp (p, "larger")) {
- *relative_size = RELATIVE_SIZE_LARGER;
- return 0.0;
- } else if (!g_ascii_strcasecmp (p, "smaller")) {
- *relative_size = RELATIVE_SIZE_SMALLER;
- return 0.0;
- } else if (!g_ascii_strcasecmp (p, "xx-small")) {
- pow_factor = -3.0;
- } else if (!g_ascii_strcasecmp (p, "x-small")) {
- pow_factor = -2.0;
- } else if (!g_ascii_strcasecmp (p, "small")) {
- pow_factor = -1.0;
- } else if (!g_ascii_strcasecmp (p, "medium")) {
- pow_factor = 0.0;
- } else if (!g_ascii_strcasecmp (p, "large")) {
- pow_factor = 1.0;
- } else if (!g_ascii_strcasecmp (p, "x-large")) {
- pow_factor = 2.0;
- } else if (!g_ascii_strcasecmp (p, "xx-large")) {
- pow_factor = 3.0;
- } else {
- return 0.0;
- }
-
- length = 12.0 * pow (1.2, pow_factor) / POINTS_PER_INCH;
- *in = TRUE;
- }
- }
-
- return length;
-}
-
-/* https://www.w3.org/TR/SVG/types.html#DataTypeLength
- * https://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#length-units
- *
- * Lengths have units. When they need to be need resolved to
- * units in the user's coordinate system, some unit types
- * need to know if they are horizontal/vertical/both. For example,
- * a some_object.width="50%" is 50% with respect to the current
- * viewport's width. In this case, the @dir argument is used
- * when _rsvg_css_normalize_length() needs to know to what the
- * length refers.
- */
-RsvgLength
-_rsvg_css_parse_length (const char *str, LengthDir dir)
-{
- RsvgLength out;
- gboolean percent, em, ex, in;
- RelativeSize relative_size = RELATIVE_SIZE_NORMAL;
- percent = em = ex = in = FALSE;
-
- out.length = rsvg_css_parse_raw_length (str, &in, &percent, &em, &ex, &relative_size);
- if (percent)
- out.unit = LENGTH_UNIT_PERCENT;
- else if (em)
- out.unit = LENGTH_UNIT_FONT_EM;
- else if (ex)
- out.unit = LENGTH_UNIT_FONT_EX;
- else if (in)
- out.unit = LENGTH_UNIT_INCH;
- else if (relative_size == RELATIVE_SIZE_LARGER)
- out.unit = LENGTH_UNIT_RELATIVE_LARGER;
- else if (relative_size == RELATIVE_SIZE_SMALLER)
- out.unit = LENGTH_UNIT_RELATIVE_SMALLER;
- else
- out.unit = LENGTH_UNIT_DEFAULT;
-
- out.dir = dir;
-
- return out;
-}
-
/* Recursive evaluation of all parent elements regarding absolute font size */
double
_rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx)
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 5fcc079..b099daf 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -126,19 +126,19 @@ filter_primitive_set_x_y_width_height_atts (RsvgFilterPrimitive *prim, RsvgPrope
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "x"))) {
- prim->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ prim->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
prim->x_specified = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y"))) {
- prim->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ prim->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
prim->y_specified = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "width"))) {
- prim->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ prim->width = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
prim->width_specified = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "height"))) {
- prim->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ prim->height = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
prim->height_specified = TRUE;
}
}
@@ -791,13 +791,13 @@ rsvg_filter_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
filter->primitiveunits = userSpaceOnUse;
}
if ((value = rsvg_property_bag_lookup (atts, "x")))
- filter->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ filter->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- filter->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ filter->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- filter->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ filter->width = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- filter->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ filter->height = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
}
}
@@ -815,10 +815,10 @@ rsvg_new_filter (void)
_rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER);
filter->filterunits = objectBoundingBox;
filter->primitiveunits = userSpaceOnUse;
- filter->x = _rsvg_css_parse_length ("-10%", LENGTH_DIR_HORIZONTAL);
- filter->y = _rsvg_css_parse_length ("-10%", LENGTH_DIR_VERTICAL);
- filter->width = _rsvg_css_parse_length ("120%", LENGTH_DIR_HORIZONTAL);
- filter->height = _rsvg_css_parse_length ("120%", LENGTH_DIR_VERTICAL);
+ filter->x = rsvg_length_parse ("-10%", LENGTH_DIR_HORIZONTAL);
+ filter->y = rsvg_length_parse ("-10%", LENGTH_DIR_VERTICAL);
+ filter->width = rsvg_length_parse ("120%", LENGTH_DIR_HORIZONTAL);
+ filter->height = rsvg_length_parse ("120%", LENGTH_DIR_VERTICAL);
filter->super.set_atts = rsvg_filter_set_atts;
return (RsvgNode *) filter;
}
@@ -2057,9 +2057,9 @@ rsvg_filter_primitive_offset_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPr
filter_primitive_set_x_y_width_height_atts ((RsvgFilterPrimitive *) filter, atts);
if ((value = rsvg_property_bag_lookup (atts, "dx")))
- filter->dx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ filter->dx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "dy")))
- filter->dy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ filter->dy = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
}
}
@@ -2071,8 +2071,8 @@ rsvg_new_filter_primitive_offset (void)
_rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET);
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
- filter->dx = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
- filter->dy = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
+ filter->dx = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
+ filter->dy = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
filter->super.render = rsvg_filter_primitive_offset_render;
filter->super.super.free = rsvg_filter_primitive_free;
filter->super.super.set_atts = rsvg_filter_primitive_offset_set_atts;
@@ -4334,17 +4334,17 @@ rsvg_node_light_source_set_atts (RsvgNode * self,
if ((value = rsvg_property_bag_lookup (atts, "limitingConeAngle")))
data->limitingconeAngle = rsvg_css_parse_angle (value) / 180.0 * M_PI;
if ((value = rsvg_property_bag_lookup (atts, "x")))
- data->x = data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ data->x = data->pointsAtX = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- data->y = data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ data->y = data->pointsAtX = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "z")))
- data->z = data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ data->z = data->pointsAtX = rsvg_length_parse (value, LENGTH_DIR_BOTH);
if ((value = rsvg_property_bag_lookup (atts, "pointsAtX")))
- data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ data->pointsAtX = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "pointsAtY")))
- data->pointsAtY = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ data->pointsAtY = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "pointsAtZ")))
- data->pointsAtZ = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ data->pointsAtZ = rsvg_length_parse (value, LENGTH_DIR_BOTH);
if ((value = rsvg_property_bag_lookup (atts, "specularExponent")))
data->specularExponent = g_ascii_strtod (value, NULL);
}
diff --git a/rsvg-image.c b/rsvg-image.c
index 69127e3..1c2b438 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -203,13 +203,13 @@ rsvg_node_image_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "x")))
- image->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ image->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- image->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ image->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- image->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ image->w = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- image->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ image->h = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
/* path is used by some older adobe illustrator versions */
if ((value = rsvg_property_bag_lookup (atts, "path"))
|| (value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
@@ -244,7 +244,7 @@ rsvg_new_image (void)
g_assert (image->super.state);
image->surface = NULL;
image->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
- image->x = image->y = image->w = image->h = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+ image->x = image->y = image->w = image->h = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
image->super.free = rsvg_node_image_free;
image->super.draw = rsvg_node_image_draw;
image->super.set_atts = rsvg_node_image_set_atts;
diff --git a/rsvg-marker.c b/rsvg-marker.c
index 8d333df..83c34bd 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -67,13 +67,13 @@ rsvg_node_marker_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
if ((value = rsvg_property_bag_lookup (atts, "viewBox")))
marker->vbox = rsvg_css_parse_vbox (value);
if ((value = rsvg_property_bag_lookup (atts, "refX")))
- marker->refX = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ marker->refX = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "refY")))
- marker->refY = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ marker->refY = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "markerWidth")))
- marker->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ marker->width = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "markerHeight")))
- marker->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ marker->height = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "orient"))) {
if (!strcmp (value, "auto"))
marker->orientAuto = TRUE;
@@ -101,8 +101,8 @@ rsvg_new_marker (void)
marker->orient = 0;
marker->orientAuto = FALSE;
marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
- marker->refX = marker->refY = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
- marker->width = marker->height = _rsvg_css_parse_length ("3", LENGTH_DIR_BOTH);
+ marker->refX = marker->refY = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
+ marker->width = marker->height = rsvg_length_parse ("3", LENGTH_DIR_BOTH);
marker->bbox = TRUE;
marker->vbox.active = FALSE;
marker->super.set_atts = rsvg_node_marker_set_atts;
diff --git a/rsvg-mask.c b/rsvg-mask.c
index 90ccd76..7976186 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -50,13 +50,13 @@ rsvg_mask_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
mask->contentunits = userSpaceOnUse;
}
if ((value = rsvg_property_bag_lookup (atts, "x")))
- mask->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ mask->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- mask->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ mask->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- mask->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ mask->width = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- mask->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ mask->height = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "id")))
id = value;
@@ -76,10 +76,10 @@ rsvg_new_mask (void)
_rsvg_node_init (&mask->super, RSVG_NODE_TYPE_MASK);
mask->maskunits = objectBoundingBox;
mask->contentunits = userSpaceOnUse;
- mask->x = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
- mask->y = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
- mask->width = _rsvg_css_parse_length ("1", LENGTH_DIR_HORIZONTAL);
- mask->height = _rsvg_css_parse_length ("1", LENGTH_DIR_VERTICAL);
+ mask->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
+ mask->y = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
+ mask->width = rsvg_length_parse ("1", LENGTH_DIR_HORIZONTAL);
+ mask->height = rsvg_length_parse ("1", LENGTH_DIR_VERTICAL);
mask->super.set_atts = rsvg_mask_set_atts;
return &mask->super;
}
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index ebf24bb..d86aff6 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -160,7 +160,7 @@ rsvg_stop_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "offset"))) {
/* either a number [0,1] or a percentage */
- RsvgLength length = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ RsvgLength length = rsvg_length_parse (value, LENGTH_DIR_BOTH);
offset = _rsvg_css_hand_normalize_length (&length, rsvg_dpi_percentage (ctx), 1., 0.);
if (offset < 0.)
@@ -209,19 +209,19 @@ rsvg_linear_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "x1"))) {
- grad->x1 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ grad->x1 = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
grad->hasx1 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y1"))) {
- grad->y1 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ grad->y1 = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
grad->hasy1 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "x2"))) {
- grad->x2 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ grad->x2 = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
grad->hasx2 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y2"))) {
- grad->y2 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ grad->y2 = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
grad->hasy2 = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "spreadMethod"))) {
@@ -269,9 +269,9 @@ rsvg_new_linear_gradient (void)
_rsvg_node_init (&grad->super, RSVG_NODE_TYPE_LINEAR_GRADIENT);
cairo_matrix_init_identity (&grad->affine);
grad->has_current_color = FALSE;
- grad->x1 = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
- grad->y1 = grad->y2 = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
- grad->x2 = _rsvg_css_parse_length ("1", LENGTH_DIR_HORIZONTAL);
+ grad->x1 = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
+ grad->y1 = grad->y2 = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
+ grad->x2 = rsvg_length_parse ("1", LENGTH_DIR_HORIZONTAL);
grad->fallback = NULL;
grad->obj_bbox = TRUE;
grad->spread = CAIRO_EXTEND_PAD;
@@ -290,27 +290,27 @@ rsvg_radial_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "cx"))) {
- grad->cx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ grad->cx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
grad->hascx = TRUE;
if (!grad->hasfx)
grad->fx = grad->cx;
}
if ((value = rsvg_property_bag_lookup (atts, "cy"))) {
- grad->cy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ grad->cy = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
grad->hascy = TRUE;
if (!grad->hasfy)
grad->fy = grad->cy;
}
if ((value = rsvg_property_bag_lookup (atts, "r"))) {
- grad->r = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ grad->r = rsvg_length_parse (value, LENGTH_DIR_BOTH);
grad->hasr = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "fx"))) {
- grad->fx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ grad->fx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
grad->hasfx = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "fy"))) {
- grad->fy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ grad->fy = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
grad->hasfy = TRUE;
}
g_free (grad->fallback);
@@ -361,7 +361,7 @@ rsvg_new_radial_gradient (void)
grad->obj_bbox = TRUE;
grad->spread = CAIRO_EXTEND_PAD;
grad->fallback = NULL;
- grad->cx = grad->cy = grad->r = grad->fx = grad->fy = _rsvg_css_parse_length ("0.5", LENGTH_DIR_BOTH);
+ grad->cx = grad->cy = grad->r = grad->fx = grad->fy = rsvg_length_parse ("0.5", LENGTH_DIR_BOTH);
grad->super.free = rsvg_radial_gradient_free;
grad->super.set_atts = rsvg_radial_gradient_set_atts;
grad->hascx = grad->hascy = grad->hasfx = grad->hasfy = grad->hasr = grad->hasbbox =
@@ -381,19 +381,19 @@ rsvg_pattern_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts
pattern->hasvbox = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "x"))) {
- pattern->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ pattern->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
pattern->hasx = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y"))) {
- pattern->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ pattern->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
pattern->hasy = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "width"))) {
- pattern->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ pattern->width = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
pattern->haswidth = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "height"))) {
- pattern->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ pattern->height = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
pattern->hasheight = TRUE;
}
g_free (pattern->fallback);
@@ -440,7 +440,7 @@ rsvg_new_pattern (void)
cairo_matrix_init_identity (&pattern->affine);
pattern->obj_bbox = TRUE;
pattern->obj_cbbox = FALSE;
- pattern->x = pattern->y = pattern->width = pattern->height = _rsvg_css_parse_length ("0",
LENGTH_DIR_BOTH);
+ pattern->x = pattern->y = pattern->width = pattern->height = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
pattern->fallback = NULL;
pattern->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
pattern->vbox.active = FALSE;
diff --git a/rsvg-private.h b/rsvg-private.h
index 1c9f2f5..e6062aa 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -242,6 +242,7 @@ _rsvg_render_check_type (RsvgRender *render,
#define _RSVG_RENDER_CIC(render, render_type, RenderCType) \
((RenderCType*) _rsvg_render_check_type ((render), (render_type)))
+/* Keep this in sync with rust/src/length.rs:LengthUnit */
typedef enum {
LENGTH_UNIT_DEFAULT,
LENGTH_UNIT_PERCENT,
@@ -252,12 +253,14 @@ typedef enum {
LENGTH_UNIT_RELATIVE_SMALLER
} LengthUnit;
+/* Keep this in sync with rust/src/length.rs:LengthDir */
typedef enum {
LENGTH_DIR_HORIZONTAL,
LENGTH_DIR_VERTICAL,
LENGTH_DIR_BOTH
} LengthDir;
+/* Keep this in sync with rust/src/length.rs:RsvgLength */
typedef struct {
double length;
LengthUnit unit;
@@ -425,8 +428,11 @@ double _rsvg_css_hand_normalize_length (const RsvgLength * in, gdouble pixels_p
double _rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx);
G_GNUC_INTERNAL
double _rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx);
+
+/* Implemented in rust/src/length.rs */
G_GNUC_INTERNAL
-RsvgLength _rsvg_css_parse_length (const char *str, LengthDir dir);
+RsvgLength rsvg_length_parse (const char *str, LengthDir dir);
+
G_GNUC_INTERNAL
void _rsvg_push_view_box (RsvgDrawingCtx * ctx, double w, double h);
G_GNUC_INTERNAL
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 6c46798..12ba717 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -253,13 +253,13 @@ _rsvg_node_line_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "x1")))
- line->x1 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ line->x1 = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y1")))
- line->y1 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ line->y1 = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "x2")))
- line->x2 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ line->x2 = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y2")))
- line->y2 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ line->y2 = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
if ((value = rsvg_property_bag_lookup (atts, "id")))
@@ -301,7 +301,7 @@ rsvg_new_line (void)
_rsvg_node_init (&line->super, RSVG_NODE_TYPE_LINE);
line->super.draw = _rsvg_node_line_draw;
line->super.set_atts = _rsvg_node_line_set_atts;
- line->x1 = line->x2 = line->y1 = line->y2 = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+ line->x1 = line->x2 = line->y1 = line->y2 = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &line->super;
}
@@ -322,19 +322,19 @@ _rsvg_node_rect_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
/* FIXME: negative w/h/rx/ry is an error, per http://www.w3.org/TR/SVG11/shapes.html#RectElement */
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "x")))
- rect->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ rect->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- rect->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ rect->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- rect->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ rect->w = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- rect->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ rect->h = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "rx"))) {
- rect->rx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ rect->rx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
rect->got_rx = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "ry"))) {
- rect->ry = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ rect->ry = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
rect->got_ry = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "class")))
@@ -493,7 +493,7 @@ rsvg_new_rect (void)
_rsvg_node_init (&rect->super, RSVG_NODE_TYPE_RECT);
rect->super.draw = _rsvg_node_rect_draw;
rect->super.set_atts = _rsvg_node_rect_set_atts;
- rect->x = rect->y = rect->w = rect->h = rect->rx = rect->ry = _rsvg_css_parse_length ("0",
LENGTH_DIR_BOTH);
+ rect->x = rect->y = rect->w = rect->h = rect->rx = rect->ry = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
rect->got_rx = rect->got_ry = FALSE;
return &rect->super;
}
@@ -513,11 +513,11 @@ _rsvg_node_circle_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "cx")))
- circle->cx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ circle->cx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "cy")))
- circle->cy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ circle->cy = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "r")))
- circle->r = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ circle->r = rsvg_length_parse (value, LENGTH_DIR_BOTH);
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
if ((value = rsvg_property_bag_lookup (atts, "id")))
@@ -584,7 +584,7 @@ rsvg_new_circle (void)
_rsvg_node_init (&circle->super, RSVG_NODE_TYPE_CIRCLE);
circle->super.draw = _rsvg_node_circle_draw;
circle->super.set_atts = _rsvg_node_circle_set_atts;
- circle->cx = circle->cy = circle->r = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+ circle->cx = circle->cy = circle->r = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &circle->super;
}
@@ -603,13 +603,13 @@ _rsvg_node_ellipse_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "cx")))
- ellipse->cx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ ellipse->cx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "cy")))
- ellipse->cy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ ellipse->cy = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "rx")))
- ellipse->rx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ ellipse->rx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "ry")))
- ellipse->ry = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ ellipse->ry = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
if ((value = rsvg_property_bag_lookup (atts, "id")))
@@ -677,6 +677,6 @@ rsvg_new_ellipse (void)
_rsvg_node_init (&ellipse->super, RSVG_NODE_TYPE_ELLIPSE);
ellipse->super.draw = _rsvg_node_ellipse_draw;
ellipse->super.set_atts = _rsvg_node_ellipse_set_atts;
- ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+ ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &ellipse->super;
}
diff --git a/rsvg-structure.c b/rsvg-structure.c
index cf9e9c5..a74d91a 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -319,17 +319,17 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
svg->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- svg->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ svg->w = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- svg->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ svg->h = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
/*
* x & y attributes have no effect on outermost svg
* http://www.w3.org/TR/SVG/struct.html#SVGElement
*/
if (self->parent && (value = rsvg_property_bag_lookup (atts, "x")))
- svg->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ svg->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if (self->parent && (value = rsvg_property_bag_lookup (atts, "y")))
- svg->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ svg->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
/*
* style element is not loaded yet here, so we need to store those attribues
@@ -373,10 +373,10 @@ rsvg_new_svg (void)
_rsvg_node_init (&svg->super, RSVG_NODE_TYPE_SVG);
svg->vbox.active = FALSE;
svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
- svg->x = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
- svg->y = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
- svg->w = _rsvg_css_parse_length ("100%", LENGTH_DIR_HORIZONTAL);
- svg->h = _rsvg_css_parse_length ("100%", LENGTH_DIR_VERTICAL);
+ svg->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
+ svg->y = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
+ svg->w = rsvg_length_parse ("100%", LENGTH_DIR_HORIZONTAL);
+ svg->h = rsvg_length_parse ("100%", LENGTH_DIR_VERTICAL);
svg->super.draw = rsvg_node_svg_draw;
svg->super.free = _rsvg_svg_free;
svg->super.set_atts = rsvg_node_svg_set_atts;
@@ -401,13 +401,13 @@ rsvg_node_use_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
use = (RsvgNodeUse *) self;
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "x")))
- use->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ use->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- use->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ use->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- use->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ use->w = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- use->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ use->h = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
if ((value = rsvg_property_bag_lookup (atts, "id")))
@@ -431,10 +431,10 @@ rsvg_new_use (void)
use->super.draw = rsvg_node_use_draw;
use->super.free = rsvg_node_use_free;
use->super.set_atts = rsvg_node_use_set_atts;
- use->x = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
- use->y = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
- use->w = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
- use->h = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
+ use->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
+ use->y = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
+ use->w = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
+ use->h = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
use->link = NULL;
return (RsvgNode *) use;
}
diff --git a/rsvg-styles.c b/rsvg-styles.c
index c5089e0..9ac401b 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -132,7 +132,7 @@ rsvg_state_init (RsvgState * state)
state->fill = rsvg_paint_server_parse (NULL, "#000");
state->fill_opacity = 0xff;
state->stroke_opacity = 0xff;
- state->stroke_width = _rsvg_css_parse_length ("1", LENGTH_DIR_BOTH);
+ state->stroke_width = rsvg_length_parse ("1", LENGTH_DIR_BOTH);
state->miter_limit = 4;
state->cap = CAIRO_LINE_CAP_BUTT;
state->join = CAIRO_LINE_JOIN_MITER;
@@ -146,7 +146,7 @@ rsvg_state_init (RsvgState * state)
state->flood_opacity = 255;
state->font_family = g_strdup (RSVG_DEFAULT_FONT);
- state->font_size = _rsvg_css_parse_length ("12.0", LENGTH_DIR_BOTH);
+ state->font_size = rsvg_length_parse ("12.0", LENGTH_DIR_BOTH);
state->font_style = PANGO_STYLE_NORMAL;
state->font_variant = PANGO_VARIANT_NORMAL;
state->font_weight = PANGO_WEIGHT_NORMAL;
@@ -155,7 +155,7 @@ rsvg_state_init (RsvgState * state)
state->text_gravity = PANGO_GRAVITY_SOUTH;
state->unicode_bidi = UNICODE_BIDI_NORMAL;
state->text_anchor = TEXT_ANCHOR_START;
- state->letter_spacing = _rsvg_css_parse_length ("0.0", LENGTH_DIR_HORIZONTAL);
+ state->letter_spacing = rsvg_length_parse ("0.0", LENGTH_DIR_HORIZONTAL);
state->visible = TRUE;
state->cond_true = TRUE;
state->filter = NULL;
@@ -704,7 +704,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
rsvg_paint_server_unref (stroke);
} else if (g_str_equal (name, "stroke-width")) {
- state->stroke_width = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ state->stroke_width = rsvg_length_parse (value, LENGTH_DIR_BOTH);
state->has_stroke_width = TRUE;
} else if (g_str_equal (name, "stroke-linecap")) {
state->has_cap = TRUE;
@@ -730,7 +730,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
else
g_warning (_("unknown line join style %s\n"), value);
} else if (g_str_equal (name, "font-size")) {
- state->font_size = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ state->font_size = rsvg_length_parse (value, LENGTH_DIR_BOTH);
state->has_font_size = TRUE;
} else if (g_str_equal (name, "font-family")) {
char *save = g_strdup (rsvg_css_parse_font_family (value, &state->has_font_family));
@@ -817,7 +817,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
}
} else if (g_str_equal (name, "letter-spacing")) {
state->has_letter_spacing = TRUE;
- state->letter_spacing = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ state->letter_spacing = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
} else if (g_str_equal (name, "stop-color")) {
if (!g_str_equal (value, "inherit")) {
state->stop_color = rsvg_css_parse_color (value, &state->has_stop_color);
@@ -844,7 +844,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
state->miter_limit = g_ascii_strtod (value, NULL);
} else if (g_str_equal (name, "stroke-dashoffset")) {
state->has_dashoffset = TRUE;
- state->dash.offset = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
+ state->dash.offset = rsvg_length_parse (value, LENGTH_DIR_BOTH);
if (state->dash.offset.length < 0.)
state->dash.offset.length = 0.;
} else if (g_str_equal (name, "shape-rendering")) {
@@ -1712,7 +1712,7 @@ rsvg_state_reinherit_top (RsvgDrawingCtx * ctx, RsvgState * state, int dominate)
RsvgState *current;
if (dominate == 3)
- return;
+ g_assert_not_reached ();
current = rsvg_current_state (ctx);
/*This is a special domination mode for patterns, the transform
diff --git a/rsvg-text.c b/rsvg-text.c
index 45ad3f3..a807d90 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -131,17 +131,17 @@ set_text_common_atts (RsvgNodeText *text, RsvgPropertyBag * atts)
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "x"))) {
- text->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ text->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
text->x_specified = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "y"))) {
- text->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ text->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
text->y_specified = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "dx")))
- text->dx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
+ text->dx = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "dy")))
- text->dy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
+ text->dy = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
}
@@ -320,7 +320,7 @@ rsvg_new_text (void)
_rsvg_node_init (&text->super, RSVG_NODE_TYPE_TEXT);
text->super.draw = _rsvg_node_text_draw;
text->super.set_atts = _rsvg_node_text_set_atts;
- text->x = text->y = text->dx = text->dy = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+ text->x = text->y = text->dx = text->dy = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &text->super;
}
@@ -412,7 +412,7 @@ rsvg_new_tspan (void)
text = g_new0 (RsvgNodeText, 1);
_rsvg_node_init (&text->super, RSVG_NODE_TYPE_TSPAN);
text->super.set_atts = _rsvg_node_tspan_set_atts;
- text->dx = text->dy = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+ text->dx = text->dy = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &text->super;
}
diff --git a/rust/src/length.rs b/rust/src/length.rs
new file mode 100644
index 0000000..9dd222b
--- /dev/null
+++ b/rust/src/length.rs
@@ -0,0 +1,300 @@
+extern crate libc;
+extern crate glib;
+
+use self::glib::translate::*;
+
+use strtod::*;
+
+/* Keep this in sync with ../../rsvg-private.h:LengthUnit */
+#[repr(C)]
+#[derive(Debug, PartialEq)]
+pub enum LengthUnit {
+ Default,
+ Percent,
+ FontEm,
+ FontEx,
+ Inch,
+ RelativeLarger,
+ RelativeSmaller
+}
+
+/* Keep this in sync with ../../rsvg-private.h:LengthDir */
+#[repr(C)]
+#[derive(Debug, PartialEq)]
+pub enum LengthDir {
+ Horizontal,
+ Vertical,
+ Both
+}
+
+/* This is *not* an opaque struct; it is actually visible to the C code. It is so
+ * that the remaining C code can create RsvgLength values as part of existing
+ * structures or objects, without allocations on the heap.
+ */
+/* Keep this in sync with ../../rsvg-private.h:RsvgLength */
+#[repr(C)]
+#[derive(Debug, PartialEq)]
+pub struct RsvgLength {
+ length: f64,
+ unit: LengthUnit,
+ dir: LengthDir
+}
+
+pub enum RsvgDrawingCtx {}
+
+const POINTS_PER_INCH: f64 = 72.0;
+const CM_PER_INCH: f64 = 2.54;
+const MM_PER_INCH: f64 = 25.4;
+const PICA_PER_INCH: f64 = 6.0;
+
+fn compute_named_size (name: &str) -> f64 {
+ let power: f64;
+
+ match name {
+ "xx-small" => { power = -3.0; },
+ "x-small" => { power = -2.0; },
+ "small" => { power = -1.0; },
+ "medium" => { power = 0.0; },
+ "large" => { power = 1.0; },
+ "x-large" => { power = 2.0; },
+ "xx-large" => { power = 3.0; },
+ _ => { return 0.0; }
+ }
+
+ 12.0 * 1.2f64.powf (power) / POINTS_PER_INCH
+}
+
+#[no_mangle]
+pub extern fn rsvg_length_parse (string: *const libc::c_char, dir: LengthDir) -> RsvgLength {
+ let my_string = unsafe { &String::from_glib_none (string) };
+
+ parse_length (my_string, dir)
+}
+
+/* https://www.w3.org/TR/SVG/types.html#DataTypeLength
+ * https://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#length-units
+ *
+ * Lengths have units. When they need to be need resolved to
+ * units in the user's coordinate system, some unit types
+ * need to know if they are horizontal/vertical/both. For example,
+ * a some_object.width="50%" is 50% with respect to the current
+ * viewport's width. In this case, the @dir argument is used
+ * when _rsvg_css_normalize_length() needs to know to what the
+ * length refers.
+ */
+pub fn parse_length (string: &str, dir: LengthDir) -> RsvgLength {
+ let unit: LengthUnit;
+
+ let (mut value, rest) = strtod (string);
+ println! ("strtod yielded {}, {}", value, rest);
+
+ match rest.as_ref () {
+ "%" => {
+ value *= 0.01; // normalize to [0, 1]
+ unit = LengthUnit::Percent;
+ },
+
+ "em" => {
+ unit = LengthUnit::FontEm;
+ },
+
+ "ex" => {
+ unit = LengthUnit::FontEx;
+ },
+
+ "pt" => {
+ value /= POINTS_PER_INCH;
+ unit = LengthUnit::Inch;
+ },
+
+ "in" => {
+ unit = LengthUnit::Inch;
+ },
+
+ "cm" => {
+ value /= CM_PER_INCH;
+ unit = LengthUnit::Inch;
+ },
+
+ "mm" => {
+ value /= MM_PER_INCH;
+ unit = LengthUnit::Inch;
+ },
+
+ "pc" => {
+ value /= PICA_PER_INCH;
+ unit = LengthUnit::Inch;
+ },
+
+ "larger" => {
+ unit = LengthUnit::RelativeLarger;
+ },
+
+ "smaller" => {
+ unit = LengthUnit::RelativeSmaller;
+ },
+
+ "xx-small" |
+ "x-small" |
+ "small" |
+ "medium" |
+ "large" |
+ "x-large" |
+ "xx-large" => {
+ value = compute_named_size (rest);
+ unit = LengthUnit::Inch;
+ },
+
+ _ => {
+ unit = LengthUnit::Default;
+ }
+ }
+
+ RsvgLength {
+ length: value,
+ unit: unit,
+ dir: dir
+ }
+}
+
+#[no_mangle]
+pub extern fn rsvg_length_normalize (length: *const RsvgLength, draw_ctx: *const RsvgDrawingCtx) -> f64 {
+ unimplemented! ();
+}
+
+#[no_mangle]
+pub extern fn rsvg_length_hand_normalize (length: *const RsvgLength,
+ pixels_per_inch: f64,
+ width_or_height: f64,
+ font_size: f64) -> f64 {
+ unimplemented! ();
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parses_default () {
+ assert_eq! (parse_length ("42", LengthDir::Horizontal),
+ RsvgLength {
+ length: 42.0,
+ unit: LengthUnit::Default,
+ dir: LengthDir::Horizontal});
+
+ assert_eq! (parse_length ("-42px", LengthDir::Horizontal),
+ RsvgLength {
+ length: -42.0,
+ unit: LengthUnit::Default,
+ dir: LengthDir::Horizontal});
+ }
+
+ #[test]
+ fn parses_percent () {
+ assert_eq! (parse_length ("50.0%", LengthDir::Horizontal),
+ RsvgLength {
+ length: 0.5,
+ unit: LengthUnit::Percent,
+ dir: LengthDir::Horizontal});
+ }
+
+ #[test]
+ fn parses_font_em () {
+ assert_eq! (parse_length ("22.5em", LengthDir::Vertical),
+ RsvgLength {
+ length: 22.5,
+ unit: LengthUnit::FontEm,
+ dir: LengthDir::Vertical });
+ }
+
+ #[test]
+ fn parses_font_ex () {
+ assert_eq! (parse_length ("22.5ex", LengthDir::Vertical),
+ RsvgLength {
+ length: 22.5,
+ unit: LengthUnit::FontEx,
+ dir: LengthDir::Vertical });
+ }
+
+ #[test]
+ fn parses_physical_units () {
+ assert_eq! (parse_length ("72pt", LengthDir::Both),
+ RsvgLength {
+ length: 1.0,
+ unit: LengthUnit::Inch,
+ dir: LengthDir::Both });
+
+ assert_eq! (parse_length ("-22.5in", LengthDir::Both),
+ RsvgLength {
+ length: -22.5,
+ unit: LengthUnit::Inch,
+ dir: LengthDir::Both });
+
+ assert_eq! (parse_length ("-25.4cm", LengthDir::Both),
+ RsvgLength {
+ length: -10.0,
+ unit: LengthUnit::Inch,
+ dir: LengthDir::Both });
+
+ assert_eq! (parse_length ("254mm", LengthDir::Both),
+ RsvgLength {
+ length: 10.0,
+ unit: LengthUnit::Inch,
+ dir: LengthDir::Both });
+
+ assert_eq! (parse_length ("60pc", LengthDir::Both),
+ RsvgLength {
+ length: 10.0,
+ unit: LengthUnit::Inch,
+ dir: LengthDir::Both });
+ }
+
+ #[test]
+ fn parses_relative_larger () {
+ assert_eq! (parse_length ("larger", LengthDir::Vertical),
+ RsvgLength {
+ length: 0.0,
+ unit: LengthUnit::RelativeLarger,
+ dir: LengthDir::Vertical });
+ }
+
+ #[test]
+ fn parses_relative_smaller () {
+ assert_eq! (parse_length ("smaller", LengthDir::Vertical),
+ RsvgLength {
+ length: 0.0,
+ unit: LengthUnit::RelativeSmaller,
+ dir: LengthDir::Vertical });
+ }
+
+ #[test]
+ fn parses_named_sizes () {
+ let names = vec![ "xx-small",
+ "x-small",
+ "small",
+ "medium",
+ "large",
+ "x-large",
+ "xx-large" ];
+
+ let mut previous_value: Option<f64> = None;
+
+ // Just ensure that the values are progressively larger; don't
+ // enforce a particular sequence.
+
+ for name in names {
+ let length = parse_length (name, LengthDir::Both);
+
+ assert_eq! (length.unit, LengthUnit::Inch);
+ assert_eq! (length.dir, LengthDir::Both);
+
+ if let Some (v) = previous_value {
+ assert! (length.length > v);
+ } else {
+ previous_value = Some (length.length);
+ }
+
+ }
+
+ }
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 76e2e77..200f5d6 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -17,7 +17,17 @@ pub use path_parser::{
rsvg_path_parser_from_str_into_builder
};
+pub use length::{
+ LengthUnit,
+ LengthDir,
+ RsvgLength,
+ rsvg_length_parse,
+ rsvg_length_normalize,
+ rsvg_length_hand_normalize,
+};
+
mod path_builder;
mod path_parser;
mod marker;
mod strtod;
+mod length;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]