[librsvg/rustification] Implement rsvg_length_normalize() fully in Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustification] Implement rsvg_length_normalize() fully in Rust
- Date: Thu, 17 Nov 2016 00:29:13 +0000 (UTC)
commit 4d19ded9d0e880e0bb0fd9cd9580c4175276dde8
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Nov 16 18:27:05 2016 -0600
Implement rsvg_length_normalize() fully in Rust
We add an RsvgLength::normalize() method, and the corresponding
rsvg_length_normalize() function to make this accessible to the C code.
This removes the old _rsvg_css_normalize_length() function.
rsvg-base.c | 2 +-
rsvg-cairo-draw.c | 36 +++++++++++++-------------
rsvg-css.c | 64 +----------------------------------------------
rsvg-filter.c | 38 ++++++++++++++--------------
rsvg-image.c | 8 +++---
rsvg-marker.c | 12 ++++----
rsvg-private.h | 4 ++-
rsvg-shapes.c | 34 ++++++++++++------------
rsvg-structure.c | 16 ++++++------
rsvg-text.c | 22 ++++++++--------
rust/src/drawing_ctx.rs | 20 ++++++++++++++
rust/src/length.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++---
12 files changed, 168 insertions(+), 152 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index eda5934..22b52f3 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -2195,7 +2195,7 @@ rsvg_get_normalized_stroke_width (RsvgDrawingCtx *ctx)
{
RsvgState *state = rsvg_current_state (ctx);
- return _rsvg_css_normalize_length (&state->stroke_width, ctx);
+ return rsvg_length_normalize (&state->stroke_width, ctx);
}
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 070b76a..e4995a1 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -101,10 +101,10 @@ _set_source_rsvg_linear_gradient (RsvgDrawingCtx * ctx,
if (linear->obj_bbox)
rsvg_drawing_ctx_push_view_box (ctx, 1., 1.);
- pattern = cairo_pattern_create_linear (_rsvg_css_normalize_length (&linear->x1, ctx),
- _rsvg_css_normalize_length (&linear->y1, ctx),
- _rsvg_css_normalize_length (&linear->x2, ctx),
- _rsvg_css_normalize_length (&linear->y2, ctx));
+ pattern = cairo_pattern_create_linear (rsvg_length_normalize (&linear->x1, ctx),
+ rsvg_length_normalize (&linear->y1, ctx),
+ rsvg_length_normalize (&linear->x2, ctx),
+ rsvg_length_normalize (&linear->y2, ctx));
if (linear->obj_bbox)
rsvg_drawing_ctx_pop_view_box (ctx);
@@ -210,12 +210,12 @@ _set_source_rsvg_radial_gradient (RsvgDrawingCtx * ctx,
if (radial->obj_bbox)
rsvg_drawing_ctx_push_view_box (ctx, 1., 1.);
- fx = _rsvg_css_normalize_length (&radial->fx, ctx);
- fy = _rsvg_css_normalize_length (&radial->fy, ctx);
+ fx = rsvg_length_normalize (&radial->fx, ctx);
+ fy = rsvg_length_normalize (&radial->fy, ctx);
- cx = _rsvg_css_normalize_length (&radial->cx, ctx);
- cy = _rsvg_css_normalize_length (&radial->cy, ctx);
- radius = _rsvg_css_normalize_length (&radial->r, ctx);
+ cx = rsvg_length_normalize (&radial->cx, ctx);
+ cy = rsvg_length_normalize (&radial->cy, ctx);
+ radius = rsvg_length_normalize (&radial->r, ctx);
fix_focus_point (fx, fy, cx, cy, radius, &new_fx, &new_fy);
@@ -289,10 +289,10 @@ _set_source_rsvg_pattern (RsvgDrawingCtx * ctx,
if (rsvg_pattern->obj_bbox)
rsvg_drawing_ctx_push_view_box (ctx, 1., 1.);
- patternx = _rsvg_css_normalize_length (&rsvg_pattern->x, ctx);
- patterny = _rsvg_css_normalize_length (&rsvg_pattern->y, ctx);
- patternw = _rsvg_css_normalize_length (&rsvg_pattern->width, ctx);
- patternh = _rsvg_css_normalize_length (&rsvg_pattern->height, ctx);
+ patternx = rsvg_length_normalize (&rsvg_pattern->x, ctx);
+ patterny = rsvg_length_normalize (&rsvg_pattern->y, ctx);
+ patternw = rsvg_length_normalize (&rsvg_pattern->width, ctx);
+ patternh = rsvg_length_normalize (&rsvg_pattern->height, ctx);
if (rsvg_pattern->obj_bbox)
rsvg_drawing_ctx_pop_view_box (ctx);
@@ -484,7 +484,7 @@ setup_cr_for_stroke (cairo_t *cr, RsvgDrawingCtx *ctx, RsvgState *state)
cairo_set_line_cap (cr, (cairo_line_cap_t) state->cap);
cairo_set_line_join (cr, (cairo_line_join_t) state->join);
cairo_set_dash (cr, state->dash.dash, state->dash.n_dash,
- _rsvg_css_normalize_length (&state->dash.offset, ctx));
+ rsvg_length_normalize (&state->dash.offset, ctx));
}
void
@@ -740,10 +740,10 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
if (self->maskunits == objectBoundingBox)
rsvg_drawing_ctx_push_view_box (ctx, 1, 1);
- sx = _rsvg_css_normalize_length (&self->x, ctx);
- sy = _rsvg_css_normalize_length (&self->y, ctx);
- sw = _rsvg_css_normalize_length (&self->width, ctx);
- sh = _rsvg_css_normalize_length (&self->height, ctx);
+ sx = rsvg_length_normalize (&self->x, ctx);
+ sy = rsvg_length_normalize (&self->y, ctx);
+ sw = rsvg_length_normalize (&self->width, ctx);
+ sh = rsvg_length_normalize (&self->height, ctx);
if (self->maskunits == objectBoundingBox)
rsvg_drawing_ctx_pop_view_box (ctx);
diff --git a/rsvg-css.c b/rsvg-css.c
index 21d5027..6df3bbf 100644
--- a/rsvg-css.c
+++ b/rsvg-css.c
@@ -109,7 +109,7 @@ normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx)
}
break;
default:
- return _rsvg_css_normalize_length (&state->font_size, ctx);
+ return rsvg_length_normalize (&state->font_size, ctx);
break;
}
@@ -122,68 +122,6 @@ rsvg_drawing_ctx_get_normalized_font_size (RsvgDrawingCtx *ctx)
return normalize_font_size (rsvg_current_state (ctx), ctx);
}
-static double
-viewport_percentage (double width, double height)
-{
- /* https://www.w3.org/TR/SVG/coords.html#Units
- *
- * "For any other length value expressed as a percentage of the viewport, the
- * percentage is calculated as the specified percentage of
- * sqrt((actual-width)**2 + (actual-height)**2))/sqrt(2)."
- */
- return sqrt (width * width + height * height) / M_SQRT2;
-}
-
-double
-_rsvg_css_normalize_length (const RsvgLength * in, RsvgDrawingCtx * ctx)
-{
- if (in->unit == LENGTH_UNIT_DEFAULT)
- return in->length;
- else if (in->unit == LENGTH_UNIT_PERCENT) {
- double w, h;
-
- rsvg_drawing_ctx_get_view_box_size (ctx, &w, &h);
-
- switch (in->dir) {
- case LENGTH_DIR_HORIZONTAL:
- return in->length * w;
-
- case LENGTH_DIR_VERTICAL:
- return in->length * h;
-
- case LENGTH_DIR_BOTH:
- return in->length * viewport_percentage (w, h);
- }
- } else if (in->unit == LENGTH_UNIT_FONT_EM || in->unit == LENGTH_UNIT_FONT_EX) {
- double font = rsvg_drawing_ctx_get_normalized_font_size (ctx);
- if (in->unit == LENGTH_UNIT_FONT_EM)
- return in->length * font;
- else
- return in->length * font / 2.;
- } else if (in->unit == LENGTH_UNIT_INCH) {
- double dpi_x, dpi_y;
-
- rsvg_drawing_ctx_get_dpi (ctx, &dpi_x, &dpi_y);
-
- switch (in->dir) {
- case LENGTH_DIR_HORIZONTAL:
- return in->length * dpi_x;
-
- case LENGTH_DIR_VERTICAL:
- return in->length * dpi_y;
-
- case LENGTH_DIR_BOTH:
- return in->length * viewport_percentage (dpi_x, dpi_y);
- }
- } else if (in->unit == LENGTH_UNIT_RELATIVE_LARGER) {
- /* todo: "larger" */
- } else if (in->unit == LENGTH_UNIT_RELATIVE_SMALLER) {
- /* todo: "smaller" */
- }
-
- return 0;
-}
-
/* Recursive evaluation of all parent elements regarding basline-shift */
double
_rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx)
diff --git a/rsvg-filter.c b/rsvg-filter.c
index ff588c0..1a6a806 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -161,10 +161,10 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext
otherbox.virgin = 0;
if (ctx->filter->filterunits == objectBoundingBox)
rsvg_drawing_ctx_push_view_box (ctx->ctx, 1., 1.);
- otherbox.rect.x = _rsvg_css_normalize_length (&ctx->filter->x, ctx->ctx);
- otherbox.rect.y = _rsvg_css_normalize_length (&ctx->filter->y, ctx->ctx);
- otherbox.rect.width = _rsvg_css_normalize_length (&ctx->filter->width, ctx->ctx);
- otherbox.rect.height = _rsvg_css_normalize_length (&ctx->filter->height, ctx->ctx);
+ otherbox.rect.x = rsvg_length_normalize (&ctx->filter->x, ctx->ctx);
+ otherbox.rect.y = rsvg_length_normalize (&ctx->filter->y, ctx->ctx);
+ otherbox.rect.width = rsvg_length_normalize (&ctx->filter->width, ctx->ctx);
+ otherbox.rect.height = rsvg_length_normalize (&ctx->filter->height, ctx->ctx);
if (ctx->filter->filterunits == objectBoundingBox)
rsvg_drawing_ctx_pop_view_box (ctx->ctx);
@@ -177,11 +177,11 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext
if (ctx->filter->primitiveunits == objectBoundingBox)
rsvg_drawing_ctx_push_view_box (ctx->ctx, 1., 1.);
if (self->x_specified)
- otherbox.rect.x = _rsvg_css_normalize_length (&self->x, ctx->ctx);
+ otherbox.rect.x = rsvg_length_normalize (&self->x, ctx->ctx);
else
otherbox.rect.x = 0;
if (self->y_specified)
- otherbox.rect.y = _rsvg_css_normalize_length (&self->y, ctx->ctx);
+ otherbox.rect.y = rsvg_length_normalize (&self->y, ctx->ctx);
else
otherbox.rect.y = 0;
@@ -191,12 +191,12 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext
rsvg_drawing_ctx_get_view_box_size (ctx->ctx, &curr_vbox_w, &curr_vbox_h);
if (self->width_specified)
- otherbox.rect.width = _rsvg_css_normalize_length (&self->width, ctx->ctx);
+ otherbox.rect.width = rsvg_length_normalize (&self->width, ctx->ctx);
else
otherbox.rect.width = curr_vbox_w;
if (self->height_specified)
- otherbox.rect.height = _rsvg_css_normalize_length (&self->height, ctx->ctx);
+ otherbox.rect.height = rsvg_length_normalize (&self->height, ctx->ctx);
else
otherbox.rect.height = curr_vbox_h;
}
@@ -2018,8 +2018,8 @@ rsvg_filter_primitive_offset_render (RsvgFilterPrimitive * self, RsvgFilterConte
output_pixels = cairo_image_surface_get_data (output);
- dx = _rsvg_css_normalize_length (&upself->dx, ctx->ctx);
- dy = _rsvg_css_normalize_length (&upself->dy, ctx->ctx);
+ dx = rsvg_length_normalize (&upself->dx, ctx->ctx);
+ dy = rsvg_length_normalize (&upself->dy, ctx->ctx);
ox = ctx->paffine.xx * dx + ctx->paffine.xy * dy;
oy = ctx->paffine.yx * dx + ctx->paffine.yy * dy;
@@ -4263,9 +4263,9 @@ get_light_direction (RsvgNodeLightSource * source, gdouble x1, gdouble y1, gdoub
double x, y;
x = affine->xx * x1 + affine->xy * y1 + affine->x0;
y = affine->yx * x1 + affine->yy * y1 + affine->y0;
- output.x = _rsvg_css_normalize_length (&source->x, ctx) - x;
- output.y = _rsvg_css_normalize_length (&source->y, ctx) - y;
- output.z = _rsvg_css_normalize_length (&source->z, ctx) - z;
+ output.x = rsvg_length_normalize (&source->x, ctx) - x;
+ output.y = rsvg_length_normalize (&source->y, ctx) - y;
+ output.z = rsvg_length_normalize (&source->z, ctx) - z;
output = normalise (output);
}
break;
@@ -4286,12 +4286,12 @@ get_light_color (RsvgNodeLightSource * source, vector3 color,
if (source->type != SPOTLIGHT)
return color;
- sx = _rsvg_css_normalize_length (&source->x, ctx);
- sy = _rsvg_css_normalize_length (&source->y, ctx);
- sz = _rsvg_css_normalize_length (&source->z, ctx);
- spx = _rsvg_css_normalize_length (&source->pointsAtX, ctx);
- spy = _rsvg_css_normalize_length (&source->pointsAtY, ctx);
- spz = _rsvg_css_normalize_length (&source->pointsAtZ, ctx);
+ sx = rsvg_length_normalize (&source->x, ctx);
+ sy = rsvg_length_normalize (&source->y, ctx);
+ sz = rsvg_length_normalize (&source->z, ctx);
+ spx = rsvg_length_normalize (&source->pointsAtX, ctx);
+ spy = rsvg_length_normalize (&source->pointsAtY, ctx);
+ spz = rsvg_length_normalize (&source->pointsAtZ, ctx);
x = affine->xx * x1 + affine->xy * y1 + affine->x0;
y = affine->yx * x1 + affine->yy * y1 + affine->y0;
diff --git a/rsvg-image.c b/rsvg-image.c
index 1c2b438..92fc004 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -172,10 +172,10 @@ rsvg_node_image_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
if (surface == NULL)
return;
- x = _rsvg_css_normalize_length (&z->x, ctx);
- y = _rsvg_css_normalize_length (&z->y, ctx);
- w = _rsvg_css_normalize_length (&z->w, ctx);
- h = _rsvg_css_normalize_length (&z->h, ctx);
+ x = rsvg_length_normalize (&z->x, ctx);
+ y = rsvg_length_normalize (&z->y, ctx);
+ w = rsvg_length_normalize (&z->w, ctx);
+ h = rsvg_length_normalize (&z->h, ctx);
rsvg_state_reinherit_top (ctx, z->super.state, dominate);
diff --git a/rsvg-marker.c b/rsvg-marker.c
index cb9916a..2ae5532 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -141,8 +141,8 @@ rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdoubl
if (self->vbox.active) {
double w, h, x, y;
- w = _rsvg_css_normalize_length (&self->width, ctx);
- h = _rsvg_css_normalize_length (&self->height, ctx);
+ w = rsvg_length_normalize (&self->width, ctx);
+ h = rsvg_length_normalize (&self->height, ctx);
x = 0;
y = 0;
@@ -158,8 +158,8 @@ rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdoubl
}
cairo_matrix_init_translate (&taffine,
- -_rsvg_css_normalize_length (&self->refX, ctx),
- -_rsvg_css_normalize_length (&self->refY, ctx));
+ -rsvg_length_normalize (&self->refX, ctx),
+ -rsvg_length_normalize (&self->refY, ctx));
cairo_matrix_multiply (&affine, &taffine, &affine);
rsvg_state_push (ctx);
@@ -181,8 +181,8 @@ rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdoubl
self->vbox.rect.width, self->vbox.rect.height);
else
rsvg_add_clipping_rect (ctx, 0, 0,
- _rsvg_css_normalize_length (&self->width, ctx),
- _rsvg_css_normalize_length (&self->height, ctx));
+ rsvg_length_normalize (&self->width, ctx),
+ rsvg_length_normalize (&self->height, ctx));
}
for (i = 0; i < self->super.children->len; i++) {
diff --git a/rsvg-private.h b/rsvg-private.h
index bc58bb2..c7dc94f 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -420,8 +420,10 @@ G_GNUC_INTERNAL
void rsvg_bbox_insert (RsvgBbox * dst, RsvgBbox * src);
G_GNUC_INTERNAL
void rsvg_bbox_clip (RsvgBbox * dst, RsvgBbox * src);
+
+/* This is implemented in rust/src/length.rs */
G_GNUC_INTERNAL
-double _rsvg_css_normalize_length (const RsvgLength * in, RsvgDrawingCtx * ctx);
+double rsvg_length_normalize (const RsvgLength *length, RsvgDrawingCtx * ctx);
/* This is implemented in rust/src/length.rs */
G_GNUC_INTERNAL
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 134d0fb..484a9f6 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -278,10 +278,10 @@ _rsvg_node_line_draw (RsvgNode * overself, RsvgDrawingCtx * ctx, int dominate)
builder = rsvg_path_builder_new ();
- x1 = _rsvg_css_normalize_length (&self->x1, ctx);
- y1 = _rsvg_css_normalize_length (&self->y1, ctx);
- x2 = _rsvg_css_normalize_length (&self->x2, ctx);
- y2 = _rsvg_css_normalize_length (&self->y2, ctx);
+ x1 = rsvg_length_normalize (&self->x1, ctx);
+ y1 = rsvg_length_normalize (&self->y1, ctx);
+ x2 = rsvg_length_normalize (&self->x2, ctx);
+ y2 = rsvg_length_normalize (&self->y2, ctx);
rsvg_path_builder_move_to (builder, x1, y1);
rsvg_path_builder_line_to (builder, x2, y2);
@@ -354,16 +354,16 @@ _rsvg_node_rect_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
RsvgPathBuilder *builder;
RsvgNodeRect *rect = (RsvgNodeRect *) self;
- x = _rsvg_css_normalize_length (&rect->x, ctx);
- y = _rsvg_css_normalize_length (&rect->y, ctx);
+ x = rsvg_length_normalize (&rect->x, ctx);
+ y = rsvg_length_normalize (&rect->y, ctx);
/* FIXME: negative w/h/rx/ry is an error, per http://www.w3.org/TR/SVG11/shapes.html#RectElement
* For now we'll just take the absolute value.
*/
- w = fabs (_rsvg_css_normalize_length (&rect->w, ctx));
- h = fabs (_rsvg_css_normalize_length (&rect->h, ctx));
- rx = fabs (_rsvg_css_normalize_length (&rect->rx, ctx));
- ry = fabs (_rsvg_css_normalize_length (&rect->ry, ctx));
+ w = fabs (rsvg_length_normalize (&rect->w, ctx));
+ h = fabs (rsvg_length_normalize (&rect->h, ctx));
+ rx = fabs (rsvg_length_normalize (&rect->rx, ctx));
+ ry = fabs (rsvg_length_normalize (&rect->ry, ctx));
if (w == 0. || h == 0.)
return;
@@ -534,9 +534,9 @@ _rsvg_node_circle_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
double cx, cy, r;
RsvgPathBuilder *builder;
- cx = _rsvg_css_normalize_length (&circle->cx, ctx);
- cy = _rsvg_css_normalize_length (&circle->cy, ctx);
- r = _rsvg_css_normalize_length (&circle->r, ctx);
+ cx = rsvg_length_normalize (&circle->cx, ctx);
+ cy = rsvg_length_normalize (&circle->cy, ctx);
+ r = rsvg_length_normalize (&circle->r, ctx);
if (r <= 0)
return;
@@ -626,10 +626,10 @@ _rsvg_node_ellipse_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
double cx, cy, rx, ry;
RsvgPathBuilder *builder;
- cx = _rsvg_css_normalize_length (&ellipse->cx, ctx);
- cy = _rsvg_css_normalize_length (&ellipse->cy, ctx);
- rx = _rsvg_css_normalize_length (&ellipse->rx, ctx);
- ry = _rsvg_css_normalize_length (&ellipse->ry, ctx);
+ cx = rsvg_length_normalize (&ellipse->cx, ctx);
+ cy = rsvg_length_normalize (&ellipse->cy, ctx);
+ rx = rsvg_length_normalize (&ellipse->rx, ctx);
+ ry = rsvg_length_normalize (&ellipse->ry, ctx);
if (rx <= 0 || ry <= 0)
return;
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 666f475..54dfd0a 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -176,10 +176,10 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
RsvgState *state;
cairo_matrix_t affine;
double x, y, w, h;
- x = _rsvg_css_normalize_length (&use->x, ctx);
- y = _rsvg_css_normalize_length (&use->y, ctx);
- w = _rsvg_css_normalize_length (&use->w, ctx);
- h = _rsvg_css_normalize_length (&use->h, ctx);
+ x = rsvg_length_normalize (&use->x, ctx);
+ y = rsvg_length_normalize (&use->y, ctx);
+ w = rsvg_length_normalize (&use->w, ctx);
+ h = rsvg_length_normalize (&use->h, ctx);
rsvg_state_reinherit_top (ctx, self->state, dominate);
@@ -253,10 +253,10 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
double nx, ny, nw, nh;
sself = (RsvgNodeSvg *) self;
- nx = _rsvg_css_normalize_length (&sself->x, ctx);
- ny = _rsvg_css_normalize_length (&sself->y, ctx);
- nw = _rsvg_css_normalize_length (&sself->w, ctx);
- nh = _rsvg_css_normalize_length (&sself->h, ctx);
+ nx = rsvg_length_normalize (&sself->x, ctx);
+ ny = rsvg_length_normalize (&sself->y, ctx);
+ nw = rsvg_length_normalize (&sself->w, ctx);
+ nh = rsvg_length_normalize (&sself->h, ctx);
rsvg_state_reinherit_top (ctx, self->state, dominate);
diff --git a/rsvg-text.c b/rsvg-text.c
index 1bb7eed..ad0c31a 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -282,10 +282,10 @@ _rsvg_node_text_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
RsvgNodeText *text = (RsvgNodeText *) self;
rsvg_state_reinherit_top (ctx, self->state, dominate);
- x = _rsvg_css_normalize_length (&text->x, ctx);
- y = _rsvg_css_normalize_length (&text->y, ctx);
- dx = _rsvg_css_normalize_length (&text->dx, ctx);
- dy = _rsvg_css_normalize_length (&text->dy, ctx);
+ x = rsvg_length_normalize (&text->x, ctx);
+ y = rsvg_length_normalize (&text->y, ctx);
+ dx = rsvg_length_normalize (&text->dx, ctx);
+ dy = rsvg_length_normalize (&text->dy, ctx);
if (rsvg_current_state (ctx)->text_anchor != TEXT_ANCHOR_START) {
_rsvg_node_text_length_children (self, ctx, &length, &lastwasspace, FALSE);
@@ -332,8 +332,8 @@ _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
double dx, dy, length = 0;
rsvg_state_reinherit_top (ctx, self->super.state, 0);
- dx = _rsvg_css_normalize_length (&self->dx, ctx);
- dy = _rsvg_css_normalize_length (&self->dy, ctx);
+ dx = rsvg_length_normalize (&self->dx, ctx);
+ dy = rsvg_length_normalize (&self->dy, ctx);
if (rsvg_current_state (ctx)->text_anchor != TEXT_ANCHOR_START) {
gboolean lws = *lastwasspace;
@@ -344,7 +344,7 @@ _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
}
if (self->x_specified) {
- *x = _rsvg_css_normalize_length (&self->x, ctx);
+ *x = rsvg_length_normalize (&self->x, ctx);
if (!PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state (ctx)->text_gravity)) {
*x -= length;
if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_MIDDLE)
@@ -356,7 +356,7 @@ _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
*x += dx;
if (self->y_specified) {
- *y = _rsvg_css_normalize_length (&self->y, ctx);
+ *y = rsvg_length_normalize (&self->y, ctx);
if (PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state (ctx)->text_gravity)) {
*y -= length;
if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_MIDDLE)
@@ -379,9 +379,9 @@ _rsvg_node_text_length_tspan (RsvgNodeText * self,
return TRUE;
if (PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state (ctx)->text_gravity))
- *length += _rsvg_css_normalize_length (&self->dy, ctx);
+ *length += rsvg_length_normalize (&self->dy, ctx);
else
- *length += _rsvg_css_normalize_length (&self->dx, ctx);
+ *length += rsvg_length_normalize (&self->dx, ctx);
return _rsvg_node_text_length_children (&self->super, ctx, length,
lastwasspace, usetextonly);
@@ -545,7 +545,7 @@ rsvg_text_create_layout (RsvgDrawingCtx * ctx, const char *text, PangoContext *
pango_font_description_free (font_desc);
attr_list = pango_attr_list_new ();
- attribute = pango_attr_letter_spacing_new (_rsvg_css_normalize_length (&state->letter_spacing, ctx) *
PANGO_SCALE);
+ attribute = pango_attr_letter_spacing_new (rsvg_length_normalize (&state->letter_spacing, ctx) *
PANGO_SCALE);
attribute->start_index = 0;
attribute->end_index = G_MAXINT;
pango_attr_list_insert (attr_list, attribute);
diff --git a/rust/src/drawing_ctx.rs b/rust/src/drawing_ctx.rs
index 2a16d82..915e717 100644
--- a/rust/src/drawing_ctx.rs
+++ b/rust/src/drawing_ctx.rs
@@ -1,11 +1,31 @@
pub enum RsvgDrawingCtx {}
extern "C" {
+ fn rsvg_drawing_ctx_get_dpi (draw_ctx: *const RsvgDrawingCtx,
+ out_dpi_x: *mut f64,
+ out_dpi_y: *mut f64);
+
+ fn rsvg_drawing_ctx_get_normalized_font_size (draw_ctx: *const RsvgDrawingCtx) -> f64;
+
fn rsvg_drawing_ctx_get_view_box_size (draw_ctx: *const RsvgDrawingCtx,
out_x: *mut f64,
out_y: *mut f64);
}
+pub fn get_dpi (draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
+ let mut dpi_x: f64 = 0.0;
+ let mut dpi_y: f64 = 0.0;
+
+ unsafe { rsvg_drawing_ctx_get_dpi (draw_ctx, &mut dpi_x, &mut dpi_y); }
+
+ (dpi_x, dpi_y)
+}
+
+
+pub fn get_normalized_font_size (draw_ctx: *const RsvgDrawingCtx) -> f64 {
+ unsafe { rsvg_drawing_ctx_get_normalized_font_size (draw_ctx) }
+}
+
pub fn get_view_box_size (draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
let mut w: f64 = 0.0;
let mut h: f64 = 0.0;
diff --git a/rust/src/length.rs b/rust/src/length.rs
index 6946b9a..16d0f05 100644
--- a/rust/src/length.rs
+++ b/rust/src/length.rs
@@ -1,9 +1,13 @@
extern crate libc;
extern crate glib;
+use std::f64;
+
use self::glib::translate::*;
use strtod::*;
+use drawing_ctx;
+use drawing_ctx::RsvgDrawingCtx;
/* Keep this in sync with ../../rsvg-private.h:LengthUnit */
#[repr(C)]
@@ -40,8 +44,6 @@ pub struct RsvgLength {
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;
@@ -79,7 +81,7 @@ pub extern fn rsvg_length_parse (string: *const libc::c_char, dir: LengthDir) ->
* 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
+ * inside RsvgLength::normalize(), when it needs to know to what the
* length refers.
*/
impl RsvgLength {
@@ -157,6 +159,46 @@ impl RsvgLength {
}
}
+ pub fn normalize (&self, draw_ctx: *const RsvgDrawingCtx) -> f64 {
+ match self.unit {
+ LengthUnit::Default => {
+ self.length
+ },
+
+ LengthUnit::Percent => {
+ let (width, height) = drawing_ctx::get_view_box_size (draw_ctx);
+
+ match self.dir {
+ LengthDir::Horizontal => { self.length * width },
+ LengthDir::Vertical => { self.length * height },
+ LengthDir::Both => { self.length * viewport_percentage (width, height) }
+ }
+ },
+
+ LengthUnit::FontEm => {
+ self.length * drawing_ctx::get_normalized_font_size (draw_ctx)
+ },
+
+ LengthUnit::FontEx => {
+ self.length * drawing_ctx::get_normalized_font_size (draw_ctx) / 2.0
+ },
+
+ LengthUnit::Inch => {
+ let (dpi_x, dpi_y) = drawing_ctx::get_dpi (draw_ctx);
+
+ match self.dir {
+ LengthDir::Horizontal => { self.length * dpi_x },
+ LengthDir::Vertical => { self.length * dpi_y },
+ LengthDir::Both => { self.length * viewport_percentage (dpi_x, dpi_y) }
+ }
+ },
+
+ // FIXME: these are pending:
https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-size
+ LengthUnit::RelativeLarger |
+ LengthUnit::RelativeSmaller => { 0.0 }
+ }
+ }
+
pub fn hand_normalize (&self,
pixels_per_inch: f64,
width_or_height: f64,
@@ -177,9 +219,23 @@ impl RsvgLength {
}
}
+fn viewport_percentage (x: f64, y: f64) -> f64 {
+ /* https://www.w3.org/TR/SVG/coords.html#Units
+ *
+ * "For any other length value expressed as a percentage of the viewport, the
+ * percentage is calculated as the specified percentage of
+ * sqrt((actual-width)**2 + (actual-height)**2))/sqrt(2)."
+ */
+ return (x * x + y * y).sqrt () / f64::consts::SQRT_2;
+}
+
#[no_mangle]
pub extern fn rsvg_length_normalize (raw_length: *const RsvgLength, draw_ctx: *const RsvgDrawingCtx) -> f64 {
- unimplemented! ();
+ assert! (!raw_length.is_null ());
+
+ let length: &RsvgLength = unsafe { &*raw_length };
+
+ length.normalize (draw_ctx)
}
#[no_mangle]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]