Skip to content

Commit

Permalink
Replace Rc with Arc, allow RAW & SVG ImageKind
Browse files Browse the repository at this point in the history
  • Loading branch information
zimond committed Jun 2, 2023
1 parent 6be2f2d commit 9a44a3c
Show file tree
Hide file tree
Showing 24 changed files with 185 additions and 147 deletions.
6 changes: 4 additions & 2 deletions crates/resvg/examples/custom_href_resolver.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::Arc;

use usvg::TreeParsing;

fn main() {
Expand All @@ -6,11 +8,11 @@ fn main() {
let ferris_image = std::sync::Arc::new(std::fs::read("./examples/ferris.png").unwrap());

// We know that our SVG won't have DataUrl hrefs, just return None for such case.
let resolve_data = Box::new(|_: &str, _: std::sync::Arc<Vec<u8>>, _: &usvg::Options| None);
let resolve_data = Arc::new(|_: &str, _: std::sync::Arc<Vec<u8>>, _: &usvg::Options| None);

// Here we handle xlink:href attribute as string,
// let's use already loaded Ferris image to match that string.
let resolve_string = Box::new(move |href: &str, _: &usvg::Options| match href {
let resolve_string = Arc::new(move |href: &str, _: &usvg::Options| match href {
"ferris_image" => Some(usvg::ImageKind::PNG(ferris_image.clone())),
_ => None,
});
Expand Down
7 changes: 4 additions & 3 deletions crates/resvg/examples/custom_usvg_tree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::rc::Rc;
use std::sync::Arc;

fn main() {
let size = usvg::Size::from_wh(200.0, 200.0).unwrap();
Expand Down Expand Up @@ -37,11 +37,12 @@ fn main() {
};

let fill = Some(usvg::Fill {
paint: usvg::Paint::LinearGradient(Rc::new(gradient)),
paint: usvg::Paint::LinearGradient(Arc::new(gradient)),
..usvg::Fill::default()
});

let mut path = usvg::Path::new(Rc::new(tiny_skia::PathBuilder::from_rect(

let mut path = usvg::Path::new(Arc::new(tiny_skia::PathBuilder::from_rect(
tiny_skia::Rect::from_xywh(20.0, 20.0, 160.0, 160.0).unwrap(),
)));
path.fill = fill;
Expand Down
6 changes: 3 additions & 3 deletions crates/resvg/examples/draw_bboxes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::rc::Rc;
use std::sync::Arc;

use usvg::{fontdb, NodeExt, TreeParsing, TreeTextToPath};

Expand Down Expand Up @@ -61,13 +61,13 @@ fn main() {
});

for bbox in bboxes {
let mut path = usvg::Path::new(Rc::new(tiny_skia::PathBuilder::from_rect(bbox)));
let mut path = usvg::Path::new(Arc::new(tiny_skia::PathBuilder::from_rect(bbox)));
path.stroke = stroke.clone();
tree.root.append_kind(usvg::NodeKind::Path(path));
}

for bbox in text_bboxes {
let mut path = usvg::Path::new(Rc::new(tiny_skia::PathBuilder::from_rect(bbox)));
let mut path = usvg::Path::new(Arc::new(tiny_skia::PathBuilder::from_rect(bbox)));
path.stroke = stroke2.clone();
tree.root.append_kind(usvg::NodeKind::Path(path));
}
Expand Down
4 changes: 2 additions & 2 deletions crates/resvg/src/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::rc::Rc;
use std::sync::Arc;

use crate::render::Context;
use crate::tree::{Node, OptionLog};
Expand All @@ -14,7 +14,7 @@ pub struct ClipPath {
}

pub fn convert(
upath: Option<Rc<usvg::ClipPath>>,
upath: Option<Arc<usvg::ClipPath>>,
object_bbox: tiny_skia::Rect,
) -> Option<ClipPath> {
let upath = upath?;
Expand Down
20 changes: 10 additions & 10 deletions crates/resvg/src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::rc::Rc;
use std::sync::Arc;

use rgb::{FromSlice, RGBA8};
use tiny_skia::IntRect;
Expand Down Expand Up @@ -99,7 +99,7 @@ pub struct Filter {
}

pub fn convert(
ufilters: &[Rc<usvg::filter::Filter>],
ufilters: &[Arc<usvg::filter::Filter>],
object_bbox: Option<tiny_skia::Rect>,
) -> (Vec<Filter>, Option<tiny_skia::Rect>) {
let object_bbox = object_bbox.and_then(|bbox| bbox.to_non_zero_rect());
Expand Down Expand Up @@ -389,7 +389,7 @@ struct Image {
/// Filter primitive result.
///
/// All images have the same size which is equal to the current filter region.
image: Rc<tiny_skia::Pixmap>,
image: Arc<tiny_skia::Pixmap>,

/// Image's region that has actual data.
///
Expand All @@ -408,7 +408,7 @@ impl Image {
fn from_image(image: tiny_skia::Pixmap, color_space: usvg::filter::ColorInterpolation) -> Self {
let (w, h) = (image.width(), image.height());
Image {
image: Rc::new(image),
image: Arc::new(image),
region: IntRect::from_xywh(0, 0, w, h).unwrap(),
color_space,
}
Expand All @@ -429,7 +429,7 @@ impl Image {
}

Ok(Image {
image: Rc::new(image),
image: Arc::new(image),
region,
color_space,
})
Expand All @@ -439,7 +439,7 @@ impl Image {
}

fn take(self) -> Result<tiny_skia::Pixmap, Error> {
match Rc::try_unwrap(self.image) {
match Arc::try_unwrap(self.image) {
Ok(v) => Ok(v),
Err(v) => Ok((*v).clone()),
}
Expand Down Expand Up @@ -620,7 +620,7 @@ fn apply_inner(
};

result = Image {
image: Rc::new(pixmap),
image: Arc::new(pixmap),
region: subregion,
color_space,
};
Expand Down Expand Up @@ -652,7 +652,7 @@ fn calc_region(
}

pub fn calc_filters_region(
filters: &[Rc<usvg::filter::Filter>],
filters: &[Arc<usvg::filter::Filter>],
object_bbox: Option<tiny_skia::NonZeroRect>,
) -> Option<tiny_skia::NonZeroRect> {
let mut global_region = usvg::BBox::default();
Expand Down Expand Up @@ -738,7 +738,7 @@ fn get_input(
let image = source.clone();

Ok(Image {
image: Rc::new(image),
image: Arc::new(image),
region,
color_space: usvg::filter::ColorInterpolation::SRGB,
})
Expand All @@ -753,7 +753,7 @@ fn get_input(
}

Ok(Image {
image: Rc::new(image),
image: Arc::new(image),
region,
color_space: usvg::filter::ColorInterpolation::SRGB,
})
Expand Down
7 changes: 6 additions & 1 deletion crates/resvg/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn convert(image: &usvg::Image, children: &mut Vec<Node>) -> Option<BBoxes>
}

let kind = match image.kind {
usvg::ImageKind::SVG(ref utree) => ImageKind::Vector(Tree::from_usvg(utree)),
usvg::ImageKind::SVG(_) => return None,
#[cfg(feature = "raster-images")]
_ => ImageKind::Raster(raster_images::decode_raster(image)?),
#[cfg(not(feature = "raster-images"))]
Expand Down Expand Up @@ -108,6 +108,8 @@ fn render_vector(

#[cfg(feature = "raster-images")]
mod raster_images {
use usvg::fontdb::Database;

use super::Image;
use crate::render::TinySkiaPixmapMutExt;
use crate::tree::OptionLog;
Expand All @@ -124,6 +126,9 @@ mod raster_images {
usvg::ImageKind::GIF(ref data) => {
decode_gif(data).log_none(|| log::warn!("Failed to decode a GIF image."))
}
usvg::ImageKind::RAW(w, h, ref data) => {
tiny_skia::Pixmap::from_vec((&**data).clone(), tiny_skia::IntSize::from_wh(w, h)?)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/resvg/src/mask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::rc::Rc;
use std::sync::Arc;

use crate::render::Context;
use crate::tree::{Node, OptionLog};
Expand All @@ -16,7 +16,7 @@ pub struct Mask {
pub children: Vec<Node>,
}

pub fn convert(umask: Option<Rc<usvg::Mask>>, object_bbox: tiny_skia::Rect) -> Option<Mask> {
pub fn convert(umask: Option<Arc<usvg::Mask>>, object_bbox: tiny_skia::Rect) -> Option<Mask> {
let umask = umask?;

let mut content_transform = tiny_skia::Transform::default();
Expand Down
10 changes: 5 additions & 5 deletions crates/resvg/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::rc::Rc;
use std::sync::Arc;

use crate::paint_server::Paint;
use crate::render::Context;
Expand All @@ -13,15 +13,15 @@ pub struct FillPath {
pub paint: Paint,
pub rule: tiny_skia::FillRule,
pub anti_alias: bool,
pub path: Rc<tiny_skia::Path>,
pub path: Arc<tiny_skia::Path>,
}

pub struct StrokePath {
pub transform: tiny_skia::Transform,
pub paint: Paint,
pub stroke: tiny_skia::Stroke,
pub anti_alias: bool,
pub path: Rc<tiny_skia::Path>,
pub path: Arc<tiny_skia::Path>,
}

pub fn convert(upath: &usvg::Path, children: &mut Vec<Node>) -> Option<BBoxes> {
Expand Down Expand Up @@ -94,7 +94,7 @@ pub fn convert(upath: &usvg::Path, children: &mut Vec<Node>) -> Option<BBoxes> {

fn convert_fill_path(
ufill: &usvg::Fill,
path: Rc<tiny_skia::Path>,
path: Arc<tiny_skia::Path>,
transform: tiny_skia::Transform,
text_bbox: Option<tiny_skia::NonZeroRect>,
anti_alias: bool,
Expand Down Expand Up @@ -130,7 +130,7 @@ fn convert_fill_path(

fn convert_stroke_path(
ustroke: &usvg::Stroke,
path: Rc<tiny_skia::Path>,
path: Arc<tiny_skia::Path>,
transform: tiny_skia::Transform,
text_bbox: Option<tiny_skia::NonZeroRect>,
anti_alias: bool,
Expand Down
6 changes: 3 additions & 3 deletions crates/usvg-parser/src/clippath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;

use usvg_tree::{ClipPath, Group, Node, NodeKind, Transform, Units};

Expand All @@ -14,7 +14,7 @@ pub(crate) fn convert(
node: SvgNode,
state: &converter::State,
cache: &mut converter::Cache,
) -> Option<Rc<ClipPath>> {
) -> Option<Arc<ClipPath>> {
// A `clip-path` attribute must reference a `clipPath` element.
if node.tag_name() != Some(EId::ClipPath) {
return None;
Expand Down Expand Up @@ -56,7 +56,7 @@ pub(crate) fn convert(
converter::convert_clip_path_elements(node, &clip_state, cache, &mut clip.root);

if clip.root.has_children() {
let clip = Rc::new(clip);
let clip = Arc::new(clip);
cache
.clip_paths
.insert(node.element_id().to_string(), clip.clone());
Expand Down
10 changes: 5 additions & 5 deletions crates/usvg-parser/src/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;

use svgtypes::{Length, LengthUnit as Unit};
use usvg_tree::*;
Expand All @@ -30,9 +30,9 @@ pub struct State<'a> {

#[derive(Default)]
pub struct Cache {
pub clip_paths: HashMap<String, Rc<ClipPath>>,
pub masks: HashMap<String, Rc<Mask>>,
pub filters: HashMap<String, Rc<usvg_tree::filter::Filter>>,
pub clip_paths: HashMap<String, Arc<ClipPath>>,
pub masks: HashMap<String, Arc<Mask>>,
pub filters: HashMap<String, Arc<usvg_tree::filter::Filter>>,
pub paint: HashMap<String, Paint>,

// used for ID generation
Expand Down Expand Up @@ -642,7 +642,7 @@ fn remove_empty_groups(tree: &mut Tree) {

fn convert_path(
node: SvgNode,
path: Rc<tiny_skia_path::Path>,
path: Arc<tiny_skia_path::Path>,
state: &State,
cache: &mut Cache,
parent: &mut Node,
Expand Down
12 changes: 6 additions & 6 deletions crates/usvg-parser/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
//! A collection of SVG filters.
use std::collections::HashSet;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;

use strict_num::PositiveF32;
use svgtypes::{Length, LengthUnit as Unit};
Expand Down Expand Up @@ -35,7 +35,7 @@ pub(crate) fn convert(
node: SvgNode,
state: &converter::State,
cache: &mut converter::Cache,
) -> Result<Vec<Rc<Filter>>, ()> {
) -> Result<Vec<Arc<Filter>>, ()> {
let value = match node.attribute::<&str>(AId::Filter) {
Some(v) => v,
None => return Ok(Vec::new()),
Expand All @@ -45,7 +45,7 @@ pub(crate) fn convert(
let mut filters = Vec::new();

let create_base_filter_func =
|kind, filters: &mut Vec<Rc<Filter>>, cache: &mut converter::Cache| {
|kind, filters: &mut Vec<Arc<Filter>>, cache: &mut converter::Cache| {
// Filter functions, unlike `filter` elements, do not have a filter region.
// We're currently do not support an unlimited region, so we simply use a fairly large one.
// This if far from ideal, but good for now.
Expand All @@ -57,7 +57,7 @@ pub(crate) fn convert(
_ => NonZeroRect::from_xywh(-0.1, -0.1, 1.2, 1.2).unwrap(),
};

filters.push(Rc::new(Filter {
filters.push(Arc::new(Filter {
id: cache.gen_filter_id(),
units: Units::ObjectBoundingBox,
primitive_units: Units::UserSpaceOnUse,
Expand Down Expand Up @@ -156,7 +156,7 @@ fn convert_url(
node: SvgNode,
state: &converter::State,
cache: &mut converter::Cache,
) -> Result<Option<Rc<Filter>>, ()> {
) -> Result<Option<Arc<Filter>>, ()> {
if let Some(filter) = cache.filters.get(node.element_id()) {
return Ok(Some(filter.clone()));
}
Expand Down Expand Up @@ -212,7 +212,7 @@ fn convert_url(
return Err(());
}

let filter = Rc::new(Filter {
let filter = Arc::new(Filter {
id: node.element_id().to_string(),
units,
primitive_units,
Expand Down
Loading

0 comments on commit 9a44a3c

Please sign in to comment.