Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove transform attribute from images and paths #668

Merged
merged 9 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion crates/resvg/src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,6 @@ fn apply_image(

let uimage = usvg::Image {
id: String::new(),
transform: usvg::Transform::default(),
visibility: usvg::Visibility::Visible,
view_box,
rendering_mode: fe.rendering_mode,
Expand Down
6 changes: 1 addition & 5 deletions crates/resvg/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub enum ImageKind {
}

pub struct Image {
pub transform: tiny_skia::Transform,
pub view_box: usvg::ViewBox,
pub quality: tiny_skia::FilterQuality,
pub kind: ImageKind,
Expand All @@ -22,7 +21,6 @@ pub fn convert(image: &usvg::Image, children: &mut Vec<Node>) -> Option<BBoxes>
let object_bbox = image.view_box.rect.to_rect();
let bboxes = BBoxes {
object: usvg::BBox::from(object_bbox),
transformed_object: usvg::BBox::from(object_bbox.transform(image.transform)?),
layer: usvg::BBox::from(object_bbox),
};

Expand All @@ -47,7 +45,6 @@ pub fn convert(image: &usvg::Image, children: &mut Vec<Node>) -> Option<BBoxes>
};

children.push(Node::Image(Image {
transform: image.transform,
view_box: image.view_box,
quality,
kind,
Expand Down Expand Up @@ -84,7 +81,7 @@ fn render_vector(
let mut sub_pixmap = tiny_skia::Pixmap::new(pixmap.width(), pixmap.height()).unwrap();

let source_transform = transform;
let transform = transform.pre_concat(image.transform).pre_concat(ts);
let transform = transform.pre_concat(ts);

tree.render(transform, &mut sub_pixmap.as_mut());

Expand Down Expand Up @@ -241,7 +238,6 @@ mod raster_images {
None
};

let transform = transform.pre_concat(image.transform);
pixmap.fill_rect(rect.to_rect(), &paint, transform, mask.as_ref());

Some(())
Expand Down
17 changes: 1 addition & 16 deletions crates/resvg/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,26 @@ use crate::render::Context;
use crate::tree::{BBoxes, Node};

pub struct FillPath {
pub transform: tiny_skia::Transform,
pub paint: Paint,
pub rule: tiny_skia::FillRule,
pub anti_alias: bool,
pub path: Rc<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 fn convert(upath: &usvg::Path, children: &mut Vec<Node>) -> Option<BBoxes> {
let transform = upath.transform;
let anti_alias = upath.rendering_mode.use_shape_antialiasing();

let fill_path = upath.fill.as_ref().and_then(|ufill| {
convert_fill_path(
ufill,
upath.data.clone(),
transform,
upath.text_bbox,
anti_alias,
)
Expand All @@ -42,7 +38,6 @@ pub fn convert(upath: &usvg::Path, children: &mut Vec<Node>) -> Option<BBoxes> {
convert_stroke_path(
ustroke,
upath.data.clone(),
transform,
upath.text_bbox,
anti_alias,
)
Expand All @@ -63,8 +58,6 @@ pub fn convert(upath: &usvg::Path, children: &mut Vec<Node>) -> Option<BBoxes> {
bboxes.object = bboxes.object.expand(o_bbox);
}

bboxes.transformed_object = bboxes.object.transform(upath.transform)?;

// Do not add hidden paths, but preserve the bbox.
// visibility=hidden still affects the bbox calculation.
if upath.visibility != usvg::Visibility::Visible {
Expand Down Expand Up @@ -95,7 +88,6 @@ pub fn convert(upath: &usvg::Path, children: &mut Vec<Node>) -> Option<BBoxes> {
fn convert_fill_path(
ufill: &usvg::Fill,
path: Rc<tiny_skia::Path>,
transform: tiny_skia::Transform,
text_bbox: Option<tiny_skia::NonZeroRect>,
anti_alias: bool,
) -> Option<(FillPath, usvg::BBox, usvg::BBox)> {
Expand All @@ -118,7 +110,6 @@ fn convert_fill_path(
crate::paint_server::convert(&ufill.paint, ufill.opacity, object_bbox.to_non_zero_rect())?;

let path = FillPath {
transform,
paint,
rule,
anti_alias,
Expand All @@ -131,7 +122,6 @@ fn convert_fill_path(
fn convert_stroke_path(
ustroke: &usvg::Stroke,
path: Rc<tiny_skia::Path>,
transform: tiny_skia::Transform,
text_bbox: Option<tiny_skia::NonZeroRect>,
anti_alias: bool,
) -> Option<(StrokePath, usvg::BBox, usvg::BBox)> {
Expand Down Expand Up @@ -173,9 +163,7 @@ fn convert_stroke_path(

// TODO: explain
// TODO: expand by stroke width for round/bevel joins
let resolution_scale = tiny_skia::PathStroker::compute_resolution_scale(&transform);
let resolution_scale = resolution_scale.max(10.0);
let stroked_path = path.stroke(&stroke, resolution_scale)?;
let stroked_path = path.stroke(&stroke, 1.0)?;

let mut layer_bbox = usvg::BBox::from(stroked_path.bounds());
if let Some(text_bbox) = text_bbox {
Expand All @@ -186,7 +174,6 @@ fn convert_stroke_path(
// TODO: preserve stroked path

let path = StrokePath {
transform,
paint,
stroke,
anti_alias,
Expand Down Expand Up @@ -227,7 +214,6 @@ pub fn render_fill_path(
paint.anti_alias = path.anti_alias;
paint.blend_mode = blend_mode;

let transform = transform.pre_concat(path.transform);
pixmap.fill_path(&path.path, &paint, path.rule, transform, None);

Some(())
Expand Down Expand Up @@ -266,7 +252,6 @@ pub fn render_stroke_path(

// TODO: fallback to a stroked path when possible

let transform = transform.pre_concat(path.transform);
pixmap.stroke_path(&path.path, &paint, &path.stroke, transform, None);

Some(())
Expand Down
9 changes: 1 addition & 8 deletions crates/resvg/src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ pub struct BBoxes {
/// Just a shape/image bbox as per SVG spec.
pub object: usvg::BBox,

/// The same as above, but transformed using object's transform.
pub transformed_object: usvg::BBox,

/// Similar to `object`, but expanded to fit the stroke as well.
pub layer: usvg::BBox,
}
Expand All @@ -167,7 +164,7 @@ fn convert_group(
};

let (filters, filter_bbox) =
crate::filter::convert(&ugroup.filters, bboxes.transformed_object.to_rect());
crate::filter::convert(&ugroup.filters, bboxes.object.to_rect());

// TODO: figure out a nicer solution
// Ignore groups with filters but invalid filter bboxes.
Expand All @@ -192,7 +189,6 @@ fn convert_group(
};

bboxes.object = bboxes.object.transform(ugroup.transform)?;
bboxes.transformed_object = bboxes.transformed_object.transform(ugroup.transform)?;
bboxes.layer = bboxes.layer.transform(ugroup.transform)?;

children.push(Node::Group(group));
Expand Down Expand Up @@ -222,7 +218,6 @@ fn convert_empty_group(ugroup: &usvg::Group, children: &mut Vec<Node>) -> Option
let bboxes = BBoxes {
// TODO: find a better solution
object: usvg::BBox::default(),
transformed_object: usvg::BBox::default(),
layer: usvg::BBox::from(layer_bbox),
};

Expand All @@ -236,8 +231,6 @@ fn convert_children(parent: usvg::Node, children: &mut Vec<Node>) -> Option<BBox
for node in parent.children() {
if let Some(bboxes2) = convert_node_inner(node, children) {
bboxes.object = bboxes.object.expand(bboxes2.object);
bboxes.transformed_object =
bboxes.transformed_object.expand(bboxes2.transformed_object);
bboxes.layer = bboxes.layer.expand(bboxes2.layer);
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/usvg-parser/src/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,6 @@ fn convert_path(

parent.append_kind(NodeKind::Path(Path {
id,
transform: Default::default(),
visibility,
fill,
stroke,
Expand Down
1 change: 0 additions & 1 deletion crates/usvg-parser/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ pub(crate) fn convert(node: SvgNode, state: &converter::State, parent: &mut Node

parent.append_kind(NodeKind::Image(Image {
id,
transform: Default::default(),
visibility,
view_box,
rendering_mode,
Expand Down
1 change: 0 additions & 1 deletion crates/usvg-parser/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ pub(crate) fn convert(

let text = Text {
id,
transform: Transform::default(),
rendering_mode,
positions: pos_list,
rotate: rotate_list,
Expand Down
5 changes: 1 addition & 4 deletions crates/usvg-text-layout/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ impl TextToPath for Text {
// Create a group will all paths that was created during text-to-path conversion.
let group = Node::new(NodeKind::Group(Group {
id: self.id.clone(),
transform: self.transform,
..Group::default()
}));

Expand Down Expand Up @@ -95,8 +94,7 @@ fn convert_text(root: Node, fontdb: &fontdb::Database) {
for node in &text_nodes {
let mut new_node = None;
if let NodeKind::Text(ref text) = *node.borrow() {
let mut absolute_ts = node.parent().unwrap().abs_transform();
absolute_ts = absolute_ts.pre_concat(text.transform);
let absolute_ts = node.parent().unwrap().abs_transform();
new_node = text.convert(fontdb, absolute_ts);
}

Expand Down Expand Up @@ -707,7 +705,6 @@ fn convert_span(

let path = Path {
id: String::new(),
transform: Transform::default(),
visibility: span.visibility,
fill,
stroke: span.stroke.clone(),
Expand Down
38 changes: 8 additions & 30 deletions crates/usvg-tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,16 +732,6 @@ impl NodeKind {
NodeKind::Text(ref e) => e.id.as_str(),
}
}

/// Returns node's transform.
pub fn transform(&self) -> Transform {
match self {
NodeKind::Group(ref e) => e.transform,
NodeKind::Path(ref e) => e.transform,
NodeKind::Image(ref e) => e.transform,
NodeKind::Text(ref e) => e.transform,
}
}
}

/// A group container.
Expand Down Expand Up @@ -844,9 +834,6 @@ pub struct Path {
/// Can be empty.
pub id: String,

/// Element transform.
pub transform: Transform,

/// Element visibility.
pub visibility: Visibility,

Expand Down Expand Up @@ -892,7 +879,6 @@ impl Path {
pub fn new(data: Rc<tiny_skia_path::Path>) -> Self {
Path {
id: String::new(),
transform: Transform::default(),
visibility: Visibility::Visible,
fill: None,
stroke: None,
Expand Down Expand Up @@ -940,9 +926,6 @@ pub struct Image {
/// Can be empty.
pub id: String,

/// Element transform.
pub transform: Transform,

/// Element visibility.
pub visibility: Visibility,

Expand Down Expand Up @@ -1216,12 +1199,6 @@ pub trait NodeExt {
/// will be returned.
fn id(&self) -> std::cell::Ref<str>;

/// Returns node's transform.
///
/// If a current node doesn't support transformation - a default
/// transform will be returned.
fn transform(&self) -> Transform;

/// Returns node's absolute transform.
///
/// If a current node doesn't support transformation - a default
Expand Down Expand Up @@ -1270,15 +1247,12 @@ impl NodeExt for Node {
std::cell::Ref::map(self.borrow(), |v| v.id())
}

#[inline]
fn transform(&self) -> Transform {
self.borrow().transform()
}

fn abs_transform(&self) -> Transform {
let mut ts_list = Vec::new();
for p in self.ancestors() {
ts_list.push(p.transform());
if let NodeKind::Group(ref group) = *p.borrow() {
ts_list.push(group.transform);
}
}

let mut abs_ts = Transform::default();
Expand Down Expand Up @@ -1314,7 +1288,11 @@ fn calc_node_bbox(node: &Node, ts: Transform) -> Option<BBox> {
let mut bbox = BBox::default();

for child in node.children() {
let child_transform = ts.pre_concat(child.transform());
let child_transform = if let NodeKind::Group(ref group) = *child.borrow() {
ts.pre_concat(group.transform)
} else {
ts
};
if let Some(c_bbox) = calc_node_bbox(&child, child_transform) {
bbox = bbox.expand(c_bbox);
}
Expand Down
5 changes: 1 addition & 4 deletions crates/usvg-tree/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::rc::Rc;

use strict_num::NonZeroPositiveF32;

use crate::{Fill, PaintOrder, Stroke, TextRendering, Transform, Visibility};
use crate::{Fill, PaintOrder, Stroke, TextRendering, Visibility};

/// A font stretch property.
#[allow(missing_docs)]
Expand Down Expand Up @@ -312,9 +312,6 @@ pub struct Text {
/// Can be empty.
pub id: String,

/// Element transform.
pub transform: Transform,

/// Rendering mode.
///
/// `text-rendering` in SVG.
Expand Down
4 changes: 2 additions & 2 deletions crates/usvg/docs/spec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ A group will have at least one of the attributes present.
Default: geometricPrecision
* `visibility` = `hidden | collapse`? +
Default: visible
* `transform` = <<transform-type,<transform> >>?
* `transform` = <<transform-type,<transform> >>? +
Can only be set on paths inside of `clipPath`.

[[image-element]]

Expand All @@ -354,7 +355,6 @@ A group will have at least one of the attributes present.
Default: optimizeQuality
* `visibility` = `hidden | collapse`? +
Default: visible
* `transform` = <<transform-type,<transform> >>?

== Filter primitives

Expand Down
Loading
Loading