Skip to content

Commit

Permalink
load sub svg in resvg
Browse files Browse the repository at this point in the history
  • Loading branch information
zimond committed May 29, 2024
1 parent 22a0b37 commit 4a35916
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 44 deletions.
8 changes: 5 additions & 3 deletions crates/resvg/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +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 usvg::load_sub_svg;

use crate::render::TinySkiaPixmapMutExt;
use crate::tree::{BBoxes, Node, Tree};

Expand Down Expand Up @@ -34,7 +36,9 @@ pub fn convert(image: &usvg::Image, children: &mut Vec<Node>) -> Option<BBoxes>
}

let kind = match image.kind {
usvg::ImageKind::SVG(_) => return None,
usvg::ImageKind::SVG(ref data) => ImageKind::Vector(Tree::from_usvg(
&load_sub_svg(&data, &usvg::Options::default()).unwrap(),
)),
#[cfg(feature = "raster-images")]
_ => ImageKind::Raster(raster_images::decode_raster(image)?),
#[cfg(not(feature = "raster-images"))]
Expand Down Expand Up @@ -105,8 +109,6 @@ 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 Down
2 changes: 1 addition & 1 deletion crates/usvg-parser/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,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: String::new(),
units: Units::ObjectBoundingBox,
primitive_units: Units::UserSpaceOnUse,
Expand Down
50 changes: 25 additions & 25 deletions crates/usvg-parser/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl ImageHrefResolver {
/// The actual images would not be decoded. It's up to the renderer.
pub fn default_data_resolver() -> ImageHrefDataResolverFn {
Arc::new(
move |mime: &str, data: Arc<Vec<u8>>, opts: &Options| match mime {
move |mime: &str, data: Arc<Vec<u8>>, _opts: &Options| match mime {
"image/jpg" | "image/jpeg" => Some(ImageKind::JPEG(data)),
"image/png" => Some(ImageKind::PNG(data)),
"image/gif" => Some(ImageKind::GIF(data)),
Expand All @@ -69,12 +69,12 @@ impl ImageHrefResolver {
let height: u32 = u32::from_be_bytes(height_vec);
Some(ImageKind::RAW(width, height, Arc::new(buf.to_vec())))
}
"image/svg+xml" => load_sub_svg(&data, opts),
"image/svg+xml" => Some(ImageKind::SVG(Arc::new(data.to_vec()))),
"text/plain" => match get_image_data_format(&data) {
Some(ImageFormat::JPEG) => Some(ImageKind::JPEG(data)),
Some(ImageFormat::PNG) => Some(ImageKind::PNG(data)),
Some(ImageFormat::GIF) => Some(ImageKind::GIF(data)),
_ => load_sub_svg(&data, opts),
_ => Some(ImageKind::SVG(Arc::new(data.to_vec()))),
},
_ => None,
},
Expand Down Expand Up @@ -105,7 +105,7 @@ impl ImageHrefResolver {
Some(ImageFormat::JPEG) => Some(ImageKind::JPEG(Arc::new(data))),
Some(ImageFormat::PNG) => Some(ImageKind::PNG(Arc::new(data))),
Some(ImageFormat::GIF) => Some(ImageKind::GIF(Arc::new(data))),
Some(ImageFormat::SVG) => load_sub_svg(&data, opts),
Some(ImageFormat::SVG) => Some(ImageKind::SVG(Arc::new(data))),
_ => {
log::warn!("'{}' is not a PNG, JPEG, GIF or SVG(Z) image.", href);
None
Expand Down Expand Up @@ -249,27 +249,27 @@ fn get_image_data_format(data: &[u8]) -> Option<ImageFormat> {
///
/// Unlike `Tree::from_*` methods, this one will also remove all `image` elements
/// from the loaded SVG, as required by the spec.
pub(crate) fn load_sub_svg(data: &[u8], _: &Options) -> Option<ImageKind> {
// let mut sub_opt = Options::default();
// sub_opt.resources_dir = None;
// sub_opt.dpi = opt.dpi;
// sub_opt.font_size = opt.font_size;
// sub_opt.languages = opt.languages.clone();
// sub_opt.shape_rendering = opt.shape_rendering;
// sub_opt.text_rendering = opt.text_rendering;
// sub_opt.image_rendering = opt.image_rendering;
// sub_opt.default_size = opt.default_size;

// let tree = match Tree::from_data(data, &sub_opt) {
// Ok(tree) => tree,
// Err(_) => {
// log::warn!("Failed to load subsvg image.");
// return None;
// }
// };

// sanitize_sub_svg(&tree);
Some(ImageKind::SVG(Arc::new(data.to_vec())))
pub fn load_sub_svg(data: &[u8], opt: &Options) -> Option<Tree> {
let mut sub_opt = Options::default();
sub_opt.resources_dir = None;
sub_opt.dpi = opt.dpi;
sub_opt.font_size = opt.font_size;
sub_opt.languages = opt.languages.clone();
sub_opt.shape_rendering = opt.shape_rendering;
sub_opt.text_rendering = opt.text_rendering;
sub_opt.image_rendering = opt.image_rendering;
sub_opt.default_size = opt.default_size;

let tree = match Tree::from_data(data, &sub_opt) {
Ok(tree) => tree,
Err(_) => {
log::warn!("Failed to load subsvg image.");
return None;
}
};

sanitize_sub_svg(&tree);
Some(tree)
}

// TODO: technically can simply override Options::image_href_resolver?
Expand Down
2 changes: 1 addition & 1 deletion crates/usvg-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ mod units;
mod use_node;

pub use crate::options::*;
pub use image::ImageHrefResolver;
pub use image::{load_sub_svg, ImageHrefResolver};
pub use roxmltree;
pub use svgtree::{AId, EId};

Expand Down
10 changes: 5 additions & 5 deletions crates/usvg-text-layout/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ fn convert_text(root: Node, fontdb: &fontdb::Database) {
text_nodes.push(node.clone());
}

if let NodeKind::Image(ref mut image) = *node.borrow_mut() {
if let ImageKind::SVG(ref mut tree) = image.kind {
tree.convert_text(fontdb);
}
}
// if let NodeKind::Image(ref mut image) = *node.borrow_mut() {
// if let ImageKind::SVG(ref mut tree) = image.kind {
// tree.convert_text(fontdb);
// }
// }

node.subroots(|subroot| convert_text(subroot, fontdb))
}
Expand Down
1 change: 1 addition & 0 deletions crates/usvg-tree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ readme = "README.md"
workspace = "../.."

[dependencies]
kurbo = "0.9.5"
rctree = "0.5"
strict-num = "0.1.1"
svgtypes = "0.13"
Expand Down
9 changes: 5 additions & 4 deletions crates/usvg-tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ pub enum ImageKind {
/// A preprocessed SVG tree. Can be rendered as is.
SVG(Arc<Vec<u8>>),
/// RAW image data
RAW(u32, u32, Arc<Vec<u8>>)
RAW(u32, u32, Arc<Vec<u8>>),
}

impl std::fmt::Debug for ImageKind {
Expand Down Expand Up @@ -1034,9 +1034,10 @@ fn has_text_nodes(root: &Node) -> bool {

if let NodeKind::Image(ref image) = *node.borrow() {
if let ImageKind::SVG(ref tree) = image.kind {
if has_text_nodes(&tree.root) {
has_text = true;
}
// if has_text_nodes(&tree.root) {
// has_text = true;
// }
has_text = false;
}
}

Expand Down
10 changes: 5 additions & 5 deletions crates/usvg/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,22 @@ impl WriterContext<'_> {
id
}

fn push_defs_id<T>(&mut self, node: &Rc<T>, id: String) {
let key = Rc::as_ptr(node) as usize;
fn push_defs_id<T>(&mut self, node: &Arc<T>, id: String) {
let key = Arc::as_ptr(node) as usize;
if !self.id_map.contains_key(&key) {
self.id_map.insert(key, id);
}
}

fn get_defs_id<T>(&self, node: &Rc<T>) -> Option<&str> {
let key = Rc::as_ptr(node) as usize;
fn get_defs_id<T>(&self, node: &Arc<T>) -> Option<&str> {
let key = Arc::as_ptr(node) as usize;
debug_assert!(self.id_map.contains_key(&key));
self.id_map.get(&key).map(|v| v.as_str())
}

fn prepare_defs_id<T, F: Fn(&mut WriterContext) -> String>(
&mut self,
node: &Rc<T>,
node: &Arc<T>,
id: &str,
xml: &mut XmlWriter,
f: F,
Expand Down

0 comments on commit 4a35916

Please sign in to comment.