[librsvg: 1/2] state: port fill and stroke to rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/2] state: port fill and stroke to rust
- Date: Fri, 27 Apr 2018 14:09:28 +0000 (UTC)
commit 4ca9508399285a80277464423f22a3040a244bc3
Author: Paolo Borelli <pborelli gnome org>
Date: Wed Apr 25 15:09:41 2018 +0200
state: port fill and stroke to rust
librsvg/rsvg-styles.c | 56 --------------------
librsvg/rsvg-styles.h | 12 -----
rsvg_internals/src/draw.rs | 77 ++++++++++++++++-----------
rsvg_internals/src/lib.rs | 2 -
rsvg_internals/src/paint_server.rs | 103 +------------------------------------
rsvg_internals/src/state.rs | 56 ++++++++++----------
6 files changed, 78 insertions(+), 228 deletions(-)
---
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c
index 249f1670..6249e536 100644
--- a/librsvg/rsvg-styles.c
+++ b/librsvg/rsvg-styles.c
@@ -98,8 +98,6 @@ rsvg_state_init (RsvgState * state)
state->parent = NULL;
- state->fill = rsvg_paint_server_parse (NULL, "#000");
-
/* The following two start as INHERIT, even though has_stop_color and
* has_stop_opacity get initialized to FALSE below. This is so that the
* first pass of rsvg_state_inherit_run(), called from
@@ -110,8 +108,6 @@ rsvg_state_init (RsvgState * state)
state->stop_color.kind = RSVG_CSS_COLOR_SPEC_INHERIT;
state->stop_opacity.kind = RSVG_OPACITY_INHERIT;
- state->has_fill_server = FALSE;
- state->has_stroke_server = FALSE;
state->has_stop_color = FALSE;
state->has_stop_opacity = FALSE;
@@ -144,12 +140,6 @@ rsvg_state_new (void)
static void
rsvg_state_finalize (RsvgState * state)
{
- rsvg_paint_server_unref (state->fill);
- state->fill = NULL;
-
- rsvg_paint_server_unref (state->stroke);
- state->stroke = NULL;
-
if (state->state_rust) {
rsvg_state_rust_free (state->state_rust);
state->state_rust = NULL;
@@ -183,8 +173,6 @@ rsvg_state_clone (RsvgState * dst, const RsvgState * src)
*dst = *src;
dst->parent = parent;
- rsvg_paint_server_ref (dst->fill);
- rsvg_paint_server_ref (dst->stroke);
dst->state_rust = rsvg_state_rust_clone(src->state_rust);
}
@@ -201,18 +189,6 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
const InheritanceFunction function,
gboolean inherituninheritables)
{
- if (function (dst->has_fill_server, src->has_fill_server)) {
- rsvg_paint_server_ref (src->fill);
- if (dst->fill)
- rsvg_paint_server_unref (dst->fill);
- dst->fill = src->fill;
- }
- if (function (dst->has_stroke_server, src->has_stroke_server)) {
- rsvg_paint_server_ref (src->stroke);
- if (dst->stroke)
- rsvg_paint_server_unref (dst->stroke);
- dst->stroke = src->stroke;
- }
if (function (dst->has_stop_color, src->has_stop_color)) {
if (dst->stop_color.kind == RSVG_CSS_COLOR_SPEC_INHERIT) {
dst->has_stop_color = TRUE;
@@ -338,26 +314,6 @@ rsvg_parse_style_pair (RsvgState *state,
}
switch (attr) {
- case RSVG_ATTRIBUTE_FILL:
- {
- RsvgPaintServer *fill = state->fill;
- state->fill =
- rsvg_paint_server_parse (&state->has_fill_server, value);
- rsvg_paint_server_unref (fill);
- }
- break;
-
- case RSVG_ATTRIBUTE_STROKE:
- {
- RsvgPaintServer *stroke = state->stroke;
-
- state->stroke =
- rsvg_paint_server_parse (&state->has_stroke_server, value);
-
- rsvg_paint_server_unref (stroke);
- }
- break;
-
case RSVG_ATTRIBUTE_STOP_COLOR:
{
state->has_stop_color = TRUE;
@@ -950,12 +906,6 @@ rsvg_state_get_opacity (RsvgState *state)
return rsvg_state_rust_get_opacity (state->state_rust);
}
-RsvgPaintServer *
-rsvg_state_get_stroke (RsvgState *state)
-{
- return state->stroke;
-}
-
RsvgCssColorSpec *
rsvg_state_get_stop_color (RsvgState *state)
{
@@ -982,12 +932,6 @@ rsvg_state_get_current_color (RsvgState *state)
return rsvg_state_rust_get_color (state->state_rust);
}
-RsvgPaintServer *
-rsvg_state_get_fill (RsvgState *state)
-{
- return state->fill;
-}
-
guint32
rsvg_state_get_flood_color (RsvgState *state)
{
diff --git a/librsvg/rsvg-styles.h b/librsvg/rsvg-styles.h
index 5293051f..a418ecfb 100644
--- a/librsvg/rsvg-styles.h
+++ b/librsvg/rsvg-styles.h
@@ -48,12 +48,6 @@ typedef struct State State;
struct _RsvgState {
RsvgState *parent;
- RsvgPaintServer *fill;
- gboolean has_fill_server;
-
- RsvgPaintServer *stroke;
- gboolean has_stroke_server;
-
RsvgCssColorSpec stop_color;
gboolean has_stop_color;
@@ -124,9 +118,6 @@ char *rsvg_state_get_mask (RsvgState *state);
G_GNUC_INTERNAL
guint8 rsvg_state_get_opacity (RsvgState *state);
-G_GNUC_INTERNAL
-RsvgPaintServer *rsvg_state_get_stroke (RsvgState *state);
-
G_GNUC_INTERNAL
RsvgCssColorSpec *rsvg_state_get_stop_color (RsvgState *state);
@@ -136,9 +127,6 @@ RsvgOpacitySpec *rsvg_state_get_stop_opacity (RsvgState *state);
G_GNUC_INTERNAL
guint32 rsvg_state_get_current_color (RsvgState *state);
-G_GNUC_INTERNAL
-RsvgPaintServer *rsvg_state_get_fill (RsvgState *state);
-
G_GNUC_INTERNAL
guint32 rsvg_state_get_flood_color (RsvgState *state);
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index 77306351..cf29a450 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -17,9 +17,11 @@ use state::{
Color,
CompOp,
FillOpacity,
+ Fill,
FillRule,
RsvgState,
ShapeRendering,
+ Stroke,
StrokeDasharray,
StrokeDashoffset,
StrokeLinecap,
@@ -72,9 +74,6 @@ fn stroke_and_fill(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx) {
// coordinate system in patterns.
extents.to_drawing_ctx(draw_ctx);
- let fill = state::get_fill(state);
- let stroke = state::get_stroke(state);
-
let current_color = rstate
.color
.as_ref()
@@ -85,19 +84,29 @@ fn stroke_and_fill(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx) {
.as_ref()
.map_or_else(|| FillOpacity::default().0, |o| o.0);
- if let Some(fill) = fill {
- if paint_server::_set_source_rsvg_paint_server(
+ let success = match rstate.fill {
+ Some(Fill(ref fill)) => paint_server::_set_source_rsvg_paint_server(
draw_ctx,
fill,
u8::from(fill_opacity),
&extents.bbox,
¤t_color,
- ) {
- if stroke.is_some() {
- cr.fill_preserve();
- } else {
- cr.fill();
- }
+ ),
+
+ _ => paint_server::_set_source_rsvg_paint_server(
+ draw_ctx,
+ &Fill::default().0,
+ u8::from(fill_opacity),
+ &extents.bbox,
+ ¤t_color,
+ ),
+ };
+
+ if success {
+ if rstate.stroke.is_some() {
+ cr.fill_preserve();
+ } else {
+ cr.fill();
}
}
@@ -106,7 +115,7 @@ fn stroke_and_fill(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx) {
.as_ref()
.map_or_else(|| StrokeOpacity::default().0, |o| o.0);
- if let Some(stroke) = stroke {
+ if let Some(Stroke(ref stroke)) = rstate.stroke {
if paint_server::_set_source_rsvg_paint_server(
draw_ctx,
stroke,
@@ -326,7 +335,7 @@ fn compute_stroke_and_fill_extents(cr: &cairo::Context, state: *mut RsvgState) -
// Bounding box for stroke
- if state::get_stroke(state).is_some() {
+ if rstate.stroke.is_some() {
let mut sb = RsvgBbox::new(&rstate.affine);
let (x, y, w, h) = cr.stroke_extents();
@@ -384,9 +393,6 @@ pub fn draw_pango_layout(
let bbox = compute_text_bbox(&ink, x, y, &rstate.affine, gravity);
- let fill = state::get_fill(state);
- let stroke = state::get_stroke(state);
-
if !clipping {
drawing_ctx::insert_bbox(draw_ctx, &bbox);
}
@@ -418,17 +424,27 @@ pub fn draw_pango_layout(
.map_or_else(|| FillOpacity::default().0, |o| o.0);
if !clipping {
- if let Some(fill) = fill {
- if paint_server::_set_source_rsvg_paint_server(
+ let success = match rstate.fill {
+ Some(Fill(ref fill)) => paint_server::_set_source_rsvg_paint_server(
draw_ctx,
fill,
u8::from(fill_opacity),
&bbox,
¤t_color,
- ) {
- pangocairo::functions::update_layout(&cr, layout);
- pangocairo::functions::show_layout(&cr, layout);
- }
+ ),
+
+ _ => paint_server::_set_source_rsvg_paint_server(
+ draw_ctx,
+ &Fill::default().0,
+ u8::from(fill_opacity),
+ &bbox,
+ ¤t_color,
+ ),
+ };
+
+ if success {
+ pangocairo::functions::update_layout(&cr, layout);
+ pangocairo::functions::show_layout(&cr, layout);
}
}
@@ -437,19 +453,20 @@ pub fn draw_pango_layout(
.as_ref()
.map_or_else(|| StrokeOpacity::default().0, |o| o.0);
- let need_layout_path;
+ let mut need_layout_path = clipping;
- if clipping {
- need_layout_path = true;
- } else {
- need_layout_path = stroke.is_some()
- && paint_server::_set_source_rsvg_paint_server(
+ if !clipping {
+ if let Some(Stroke(ref stroke)) = rstate.stroke {
+ if paint_server::_set_source_rsvg_paint_server(
draw_ctx,
- stroke.unwrap(),
+ stroke,
u8::from(stroke_opacity),
&bbox,
¤t_color,
- );
+ ) {
+ need_layout_path = true;
+ }
+ }
}
if need_layout_path {
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 075487ab..e437d3c1 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -82,8 +82,6 @@ pub use node::{
pub use opacity::{rsvg_css_parse_opacity, OpacityKind, OpacitySpec};
-pub use paint_server::{rsvg_paint_server_parse, rsvg_paint_server_ref, rsvg_paint_server_unref};
-
pub use parsers::{rsvg_css_parse_number_list, rsvg_css_parse_number_optional_number};
pub use pattern::rsvg_node_pattern_new;
diff --git a/rsvg_internals/src/paint_server.rs b/rsvg_internals/src/paint_server.rs
index d4192e64..5617bff0 100644
--- a/rsvg_internals/src/paint_server.rs
+++ b/rsvg_internals/src/paint_server.rs
@@ -1,11 +1,5 @@
use cairo;
use cssparser;
-use glib::translate::*;
-use glib_sys;
-use libc;
-
-use std::ptr;
-use std::rc::Rc;
use bbox::RsvgBbox;
use drawing_ctx;
@@ -14,7 +8,6 @@ use gradient;
use node::NodeType;
use parsers::{Parse, ParseError};
use pattern;
-use util::utf8_cstr;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PaintServerSpread(pub cairo::enums::Extend);
@@ -43,7 +36,6 @@ impl Default for PaintServerSpread {
#[derive(Debug, Clone, PartialEq)]
pub enum PaintServer {
- Inherit,
None,
Iri {
iri: String,
@@ -60,9 +52,7 @@ impl Parse for PaintServer {
let mut input = cssparser::ParserInput::new(s);
let mut parser = cssparser::Parser::new(&mut input);
- if parser.try(|i| i.expect_ident_matching("inherit")).is_ok() {
- Ok(PaintServer::Inherit)
- } else if parser.try(|i| i.expect_ident_matching("none")).is_ok() {
+ if parser.try(|i| i.expect_ident_matching("none")).is_ok() {
Ok(PaintServer::None)
} else if let Ok(url) = parser.try(|i| i.expect_url()) {
let alternate = if !parser.is_exhausted() {
@@ -106,72 +96,6 @@ fn _set_source_rsvg_solid_color(
);
}
-/// Parses the paint specification, creating a new paint server object.
-/// Return value: (nullable): The newly created paint server, or NULL on error.
-///
-/// # Arguments
-///
-/// * `str` - The SVG paint specification string to parse.
-#[no_mangle]
-pub extern "C" fn rsvg_paint_server_parse(
- inherit: *mut glib_sys::gboolean,
- str: *const libc::c_char,
-) -> *const PaintServer {
- if !inherit.is_null() {
- unsafe {
- *inherit = true.to_glib();
- }
- }
-
- let paint_server = PaintServer::parse(unsafe { utf8_cstr(str) }, ());
-
- if let Ok(PaintServer::Inherit) = paint_server {
- if !inherit.is_null() {
- unsafe {
- *inherit = false.to_glib();
- }
- }
- }
-
- match paint_server {
- Ok(m) => Rc::into_raw(Rc::new(m)),
- Err(_) => ptr::null_mut(),
- }
-}
-
-/// Increase references counter of `PaintServer`.
-///
-/// # Arguments
-///
-/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
-#[no_mangle]
-pub extern "C" fn rsvg_paint_server_ref(paint_server: *const PaintServer) {
- if paint_server.is_null() {
- return;
- }
-
- let server: Rc<PaintServer> = unsafe { Rc::from_raw(paint_server) };
-
- // forget about references
- Rc::into_raw(server.clone());
- Rc::into_raw(server);
-}
-
-/// Decrease references counter of `PaintServer`.
-///
-/// # Arguments
-///
-/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
-#[no_mangle]
-pub extern "C" fn rsvg_paint_server_unref(paint_server: *const PaintServer) {
- if paint_server.is_null() {
- return;
- }
-
- // drop reference
- unsafe { Rc::from_raw(paint_server) };
-}
-
pub fn _set_source_rsvg_paint_server(
c_ctx: *mut drawing_ctx::RsvgDrawingCtx,
ps: &PaintServer,
@@ -222,10 +146,6 @@ pub fn _set_source_rsvg_paint_server(
PaintServer::None => {
had_paint_server = false;
}
-
- PaintServer::Inherit => {
- unreachable!();
- }
};
had_paint_server
@@ -262,11 +182,6 @@ mod tests {
assert!(PaintServer::parse("invalid", ()).is_err());
}
- #[test]
- fn parses_inherit() {
- assert_eq!(PaintServer::parse("inherit", ()), Ok(PaintServer::Inherit));
- }
-
#[test]
fn parses_none() {
assert_eq!(PaintServer::parse("none", ()), Ok(PaintServer::None));
@@ -335,20 +250,4 @@ mod tests {
assert!(PaintServer::parse("url(#link) invalid", ()).is_err());
}
-
- #[test]
- fn paint_server_refs_and_unrefs() {
- let rc = Rc::new(PaintServer::parse("#ffffff", ()).unwrap());
- let weak = Rc::downgrade(&rc);
- let ps = Rc::into_raw(rc);
-
- rsvg_paint_server_ref(ps);
- assert!(weak.upgrade().is_some());
-
- rsvg_paint_server_unref(ps);
- assert!(weak.upgrade().is_some());
-
- rsvg_paint_server_unref(ps);
- assert!(weak.upgrade().is_none());
- }
}
diff --git a/rsvg_internals/src/state.rs b/rsvg_internals/src/state.rs
index d28bd1ed..9a9ad955 100644
--- a/rsvg_internals/src/state.rs
+++ b/rsvg_internals/src/state.rs
@@ -50,6 +50,7 @@ pub struct State {
pub direction: Option<Direction>,
pub display: Option<Display>,
pub enable_background: Option<EnableBackground>,
+ pub fill: Option<Fill>,
pub fill_opacity: Option<FillOpacity>,
pub fill_rule: Option<FillRule>,
pub filter: Option<Filter>,
@@ -69,6 +70,7 @@ pub struct State {
pub opacity: Option<Opacity>,
pub overflow: Option<Overflow>,
pub shape_rendering: Option<ShapeRendering>,
+ pub stroke: Option<Stroke>,
pub stroke_dasharray: Option<StrokeDasharray>,
pub stroke_dashoffset: Option<StrokeDashoffset>,
pub stroke_line_cap: Option<StrokeLinecap>,
@@ -103,6 +105,7 @@ impl State {
direction: Default::default(),
display: Default::default(),
enable_background: Default::default(),
+ fill: Default::default(),
fill_opacity: Default::default(),
fill_rule: Default::default(),
filter: Default::default(),
@@ -122,6 +125,7 @@ impl State {
opacity: Default::default(),
overflow: Default::default(),
shape_rendering: Default::default(),
+ stroke: Default::default(),
stroke_dasharray: Default::default(),
stroke_dashoffset: Default::default(),
stroke_line_cap: Default::default(),
@@ -183,6 +187,10 @@ impl State {
self.enable_background = parse_property(value, ())?;
}
+ Attribute::Fill => {
+ self.fill = parse_property(value, ())?;
+ }
+
Attribute::FillOpacity => {
self.fill_opacity = parse_property(value, ())?;
}
@@ -273,6 +281,10 @@ impl State {
self.shape_rendering = parse_property(value, ())?;
}
+ Attribute::Stroke => {
+ self.stroke = parse_property(value, ())?;
+ }
+
Attribute::StrokeDasharray => {
self.stroke_dasharray = parse_property(value, ())?;
}
@@ -402,8 +414,6 @@ extern "C" {
fn rsvg_state_parent(state: *const RsvgState) -> *mut RsvgState;
fn rsvg_state_get_stop_color(state: *const RsvgState) -> *const color::ColorSpec;
fn rsvg_state_get_stop_opacity(state: *const RsvgState) -> *const opacity::OpacitySpec;
- fn rsvg_state_get_stroke(state: *const RsvgState) -> *const PaintServer;
- fn rsvg_state_get_fill(state: *const RsvgState) -> *const PaintServer;
fn rsvg_state_dominate(state: *mut RsvgState, src: *const RsvgState);
fn rsvg_state_force(state: *mut RsvgState, src: *const RsvgState);
@@ -510,30 +520,6 @@ pub fn get_stop_opacity(state: *const RsvgState) -> Result<Option<opacity::Opaci
}
}
-pub fn get_stroke<'a>(state: *const RsvgState) -> Option<&'a PaintServer> {
- unsafe {
- let ps = rsvg_state_get_stroke(state);
-
- if ps.is_null() {
- None
- } else {
- Some(&*ps)
- }
- }
-}
-
-pub fn get_fill<'a>(state: *const RsvgState) -> Option<&'a PaintServer> {
- unsafe {
- let ps = rsvg_state_get_fill(state);
-
- if ps.is_null() {
- None
- } else {
- Some(&*ps)
- }
- }
-}
-
pub fn dominate(state: *mut RsvgState, src: *const RsvgState) {
unsafe {
rsvg_state_dominate(state, src);
@@ -697,6 +683,14 @@ make_property!(
"new" => New,
);
+make_property!(
+ Fill,
+ default: PaintServer::parse("#000", ()).unwrap(),
+ inherits_automatically: true,
+ newtype_parse: PaintServer,
+ parse_data_type: ()
+);
+
make_property!(
FillOpacity,
default: UnitInterval(1.0),
@@ -884,6 +878,14 @@ make_property!(
"crispEdges" => CrispEdges,
);
+make_property!(
+ Stroke,
+ default: PaintServer::parse("#000", ()).unwrap(),
+ inherits_automatically: true,
+ newtype_parse: PaintServer,
+ parse_data_type: ()
+);
+
make_property!(
StrokeDasharray,
default: Dasharray::default(),
@@ -1171,6 +1173,7 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
inherit(inherit_fn, &mut dst.color, &src.color);
inherit(inherit_fn, &mut dst.direction, &src.direction);
inherit(inherit_fn, &mut dst.display, &src.display);
+ inherit(inherit_fn, &mut dst.fill, &src.fill);
inherit(inherit_fn, &mut dst.fill_opacity, &src.fill_opacity);
inherit(inherit_fn, &mut dst.fill_rule, &src.fill_rule);
inherit(inherit_fn, &mut dst.flood_color, &src.flood_color);
@@ -1187,6 +1190,7 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
inherit(inherit_fn, &mut dst.marker_start, &src.marker_start);
inherit(inherit_fn, &mut dst.overflow, &src.overflow);
inherit(inherit_fn, &mut dst.shape_rendering, &src.shape_rendering);
+ inherit(inherit_fn, &mut dst.stroke, &src.stroke);
inherit(inherit_fn, &mut dst.stroke_dasharray, &src.stroke_dasharray);
inherit(
inherit_fn,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]