Commit edd5ef64 authored by RazrFalcon's avatar RazrFalcon

Added initial filters support.

parent f8db2209
......@@ -29,6 +29,7 @@ This changelog also contains important changes in dependencies.
- (qt-api) SVG from QByteArray loading when data is invalid.
- (usvg) `display` attribute processing.
- (usvg) Recursive `mask` resolving.
- (svgdom) Namespaces resolving.
- (usvg) `inherit` attribute value resolving.
### Removed
......
......@@ -29,8 +29,10 @@ travis-ci = { repository = "RazrFalcon/resvg" }
[dependencies]
log = "0.4.5"
palette = { version = "0.4.1", default-features = false }
rgb = "0.8.9"
#usvg = "0.2"
usvg = { git = "https://github.com/RazrFalcon/usvg", rev = "14342a5" }
usvg = { git = "https://github.com/RazrFalcon/usvg", rev = "99bfc15" }
#usvg = { path = "../usvg" }
unicode-segmentation = "1.2.1"
......
......@@ -63,7 +63,7 @@ of the SVG Tiny 1.2 subset. In simple terms - it correctly renders only primitiv
*resvg* is aiming to support only the [static](http://www.w3.org/TR/SVG11/feature#SVG-static)
SVG subset. E.g. no `a`, `script`, `view`, `cursor` elements, no events and no animations.
Also, `filter`, `marker`, `textPath` and
Also, `marker`, `textPath` and
[embedded fonts](https://www.w3.org/TR/SVG11/feature#Font) are not yet implemented.
Results of the static subset of the [SVG test suite](https://www.w3.org/Graphics/SVG/Test/20110816/):
......
......@@ -4,8 +4,17 @@ List of features required from the 2D graphics library to implement a backend fo
- Composition modes:
- Clear
- Darken
- DestinationIn
- DestinationOut
- Lighten
- Multiply
- Screen
- SourceAtop
- SourceIn
- SourceOut
- SourceOver
- Xor
- Filling:
- With color
- With linear or radial gradient
......@@ -34,7 +43,7 @@ List of features required from the 2D graphics library to implement a backend fo
- Text
- Anti-aliasing
- Font properties:
- Family resolving (like `'Arial', monospace`)
- Family resolving (like `'Timer New Roman', monospace`)
- Style: *normal*, *italic* and *oblique*
- Weight
- Stretch
......
### Elements
- Filter based
- `feConvolveMatrix`
- `feDiffuseLighting`
- `feDisplacementMap`
- `feMorphology`
- `feSpecularLighting`
- `feDistantLight`
- `fePointLight`
- `feSpotLight`
- Font based
- `font`
- `glyph`
- `missing-glyph`
- `hkern`
- `vkern`
- `font-face`
- `font-face-src`
- `font-face-uri`
- `font-face-format`
- `font-face-name`
- `marker`
- `color-profile`
### Attributes
- [enable-background](https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty) (deprecated)
- [in](https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveInAttribute)
with `BackgroundImage`, `BackgroundAlpha`, `FillPaint`, `StrokePaint`
- `image-rendering`
- `shape-rendering`
- `text-rendering`
- clip (deprecated)
- color-interpolation
This diff is collapsed.
......@@ -106,7 +106,7 @@ fn draw_raster(
surface_data[i + 0] = (((tb >> 8) + tb) >> 8) as u8;
surface_data[i + 1] = (((tg >> 8) + tg) >> 8) as u8;
surface_data[i + 2] = (((tr >> 8) + tr) >> 8) as u8;
surface_data[i + 3] = a as u8;
surface_data[i + 3] = a as u8; // TODO: is needed?
} else {
surface_data[i + 0] = img_pixels[idx + 2];
surface_data[i + 1] = img_pixels[idx + 1];
......
......@@ -40,6 +40,7 @@ macro_rules! try_create_surface {
mod clippath;
mod ext;
mod fill;
mod filter;
mod gradient;
mod image;
mod mask;
......@@ -294,7 +295,7 @@ fn render_group_impl(
cr: &cairo::Context,
) -> Option<Rect> {
let sub_surface = layers.get()?;
let sub_surface = sub_surface.borrow_mut();
let mut sub_surface = sub_surface.borrow_mut();
let sub_cr = cairo::Context::new(&*sub_surface);
sub_cr.set_matrix(cr.get_matrix());
......@@ -317,6 +318,15 @@ fn render_group_impl(
}
}
if let Some(ref id) = g.filter {
if let Some(filter_node) = node.tree().defs_by_id(id) {
if let usvg::NodeKind::Filter(ref filter) = *filter_node.borrow() {
let ts = usvg::Transform::from_native(&cr.get_matrix());
filter::apply(filter, bbox, &ts, &mut *sub_surface);
}
}
}
let curr_matrix = cr.get_matrix();
cr.set_matrix(cairo::Matrix::identity());
cr.set_source_surface(&*sub_surface, 0.0, 0.0);
......
This diff is collapsed.
......@@ -32,6 +32,7 @@ macro_rules! try_create_image {
mod clippath;
mod fill;
mod filter;
mod gradient;
mod image;
mod mask;
......@@ -170,6 +171,7 @@ pub fn render_node_to_canvas(
apply_viewbox_transform(view_box, img_size, painter);
let curr_ts = painter.get_transform();
let mut ts = utils::abs_transform(node);
ts.append(&node.transform());
......@@ -293,6 +295,15 @@ fn render_group_impl(
sub_p.end();
if let Some(ref id) = g.filter {
if let Some(filter_node) = node.tree().defs_by_id(id) {
if let usvg::NodeKind::Filter(ref filter) = *filter_node.borrow() {
let ts = usvg::Transform::from_native(&p.get_transform());
filter::apply(filter, bbox, &ts, &mut sub_img);
}
}
}
if let Some(opacity) = g.opacity {
p.set_opacity(*opacity);
}
......
This diff is collapsed.
......@@ -2,6 +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/.
pub mod filter;
pub mod image;
pub mod mask;
pub mod text;
......@@ -4,6 +4,7 @@
//! 2D geometric primitives.
use std::cmp;
use std::f64;
use std::fmt;
......@@ -91,6 +92,7 @@ fn size_scale(s1: ScreenSize, s2: ScreenSize, expand: bool) -> ScreenSize {
}
}
/// Additional `Rect` methods.
pub trait RectExt {
/// Creates a new `Rect` for bounding box calculation.
......@@ -103,6 +105,9 @@ pub trait RectExt {
/// Returns rect's size in screen units.
fn to_screen_size(&self) -> ScreenSize;
/// Returns rect in screen units.
fn to_screen_rect(&self) -> ScreenRect;
}
impl RectExt for Rect {
......@@ -130,8 +135,106 @@ impl RectExt for Rect {
fn to_screen_size(&self) -> ScreenSize {
self.size().to_screen_size()
}
fn to_screen_rect(&self) -> ScreenRect {
ScreenRect::new(self.x as i32, self.y as i32,
cmp::max(0, self.width as i32) as u32,
cmp::max(0, self.height as i32) as u32)
}
}
/// A 2D screen rect representation.
#[allow(missing_docs)]
#[derive(Clone, Copy, PartialEq)]
pub struct ScreenRect {
pub x: i32,
pub y: i32,
pub width: u32,
pub height: u32,
}
impl ScreenRect {
/// Creates a new `Rect` from values.
pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self {
ScreenRect { x, y, width, height }
}
/// Returns rect's size.
pub fn size(&self) -> ScreenSize {
ScreenSize::new(self.width, self.height)
}
pub fn left(&self) -> i32 {
self.x
}
pub fn right(&self) -> i32 {
self.x + self.width as i32
}
pub fn top(&self) -> i32 {
self.y
}
pub fn bottom(&self) -> i32 {
self.y + self.height as i32
}
/// Checks that rect contains a point.
pub fn contains(&self, x: i32, y: i32) -> bool {
if x < self.x || x > self.x + self.width as i32 - 1 {
return false;
}
if y < self.y || y > self.y + self.height as i32 - 1 {
return false;
}
true
}
pub fn fit_to_rect(&self, bounds: ScreenRect) -> Self {
let mut r = *self;
if r.x < 0 { r.x = 0; }
if r.y < 0 { r.y = 0; }
if r.right() > bounds.width as i32 {
r.width = cmp::max(0, bounds.width as i32 - r.x) as u32;
}
if r.bottom() > bounds.height as i32 {
r.height = cmp::max(0, bounds.height as i32 - r.y) as u32;
}
r
}
pub fn to_rect(&self) -> Rect {
Rect::new(self.x as f64, self.y as f64, self.width as f64, self.height as f64)
}
}
impl fmt::Debug for ScreenRect {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ScreenRect({} {} {} {})", self.x, self.y, self.width, self.height)
}
}
impl fmt::Display for ScreenRect {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<(i32, i32, u32, u32)> for ScreenRect {
fn from(v: (i32, i32, u32, u32)) -> Self {
Self::new(v.0, v.1, v.2, v.3)
}
}
#[inline]
fn f64_min(v1: f64, v2: f64) -> f64 {
if v1 < v2 { v1 } else { v2 }
......
......@@ -17,11 +17,13 @@ And as an embeddable library to paint SVG on an application native canvas.
#![doc(html_root_url = "https://docs.rs/resvg/0.3.0")]
//#![forbid(unsafe_code)]
#![warn(missing_docs)]
//#![warn(missing_docs)]
#[macro_use] pub extern crate usvg;
#[macro_use] extern crate log;
extern crate unicode_segmentation;
extern crate rgb;
extern crate palette;
#[cfg(feature = "cairo-backend")] pub extern crate cairo;
#[cfg(feature = "cairo-backend")] extern crate pango;
......
a-color-interpolation-filters-001.svg
a-filter-001.svg
e-feBlend-001.svg
e-feBlend-002.svg
e-feBlend-003.svg
e-feBlend-004.svg
e-feBlend-005.svg
e-feBlend-006.svg
e-feBlend-007.svg
e-feBlend-008.svg
e-feComposite-001.svg
e-feComposite-002.svg
e-feComposite-003.svg
e-feComposite-004.svg
e-feComposite-005.svg
e-feComposite-006.svg
e-feComposite-007.svg
e-feComposite-008.svg
e-feComposite-009.svg
e-feComposite-010.svg
e-feComposite-011.svg
e-feFlood-001.svg
e-feFlood-002.svg
e-feFlood-003.svg
e-feFlood-004.svg
e-feFlood-005.svg
e-feFlood-006.svg
e-feGaussianBlur-001.svg
e-feGaussianBlur-002.svg
e-feGaussianBlur-003.svg
e-feGaussianBlur-004.svg
e-feGaussianBlur-005.svg
e-feGaussianBlur-006.svg
e-feGaussianBlur-007.svg
e-feGaussianBlur-008.svg
e-feGaussianBlur-009.svg
e-feGaussianBlur-010.svg
e-feMerge-001.svg
e-feMerge-002.svg
e-feOffset-001.svg
e-feOffset-002.svg
e-feOffset-003.svg
e-feOffset-004.svg
e-feOffset-005.svg
e-feOffset-006.svg
e-feOffset-007.svg
e-feTile-001.svg
e-feTile-002.svg
e-feTile-003.svg
e-feTile-004.svg
e-feTile-005.svg
e-feTile-006.svg
e-filter-001.svg
e-filter-002.svg
e-filter-003.svg
e-filter-004.svg
e-filter-005.svg
e-filter-006.svg
e-filter-007.svg
e-filter-008.svg
e-filter-009.svg
e-filter-010.svg
e-filter-011.svg
e-filter-012.svg
e-filter-013.svg
e-filter-014.svg
e-filter-015.svg
e-filter-016.svg
e-filter-017.svg
e-filter-018.svg
e-filter-019.svg
e-filter-020.svg
e-filter-021.svg
e-filter-022.svg
e-filter-023.svg
e-filter-024.svg
e-filter-025.svg
e-filter-026.svg
e-filter-027.svg
e-filter-028.svg
e-filter-029.svg
e-filter-030.svg
e-filter-031.svg
e-filter-032.svg
e-filter-033.svg
e-filter-034.svg
e-filter-035.svg
e-filter-036.svg
e-filter-037.svg
e-filter-038.svg
e-filter-039.svg
e-filter-040.svg
e-filter-041.svg
e-filter-042.svg
e-filter-043.svg
e-filter-044.svg
e-filter-045.svg
e-filter-046.svg
e-filter-047.svg
e-filter-048.svg
e-filter-049.svg
e-filter-050.svg
e-filter-051.svg
a-color-interpolation-filters-001.svg
a-filter-001.svg
e-feBlend-001.svg
e-feBlend-002.svg
e-feBlend-003.svg
e-feBlend-004.svg
e-feBlend-005.svg
e-feBlend-006.svg
e-feBlend-007.svg
e-feBlend-008.svg
e-feComposite-001.svg
e-feComposite-002.svg
e-feComposite-003.svg
e-feComposite-004.svg
e-feComposite-005.svg
e-feComposite-006.svg
e-feComposite-007.svg
e-feComposite-008.svg
e-feComposite-009.svg
e-feComposite-010.svg
e-feComposite-011.svg
e-feFlood-001.svg
e-feFlood-002.svg
e-feFlood-003.svg
e-feFlood-004.svg
e-feFlood-005.svg
e-feFlood-006.svg
e-feGaussianBlur-001.svg
e-feGaussianBlur-002.svg
e-feGaussianBlur-003.svg
e-feGaussianBlur-004.svg
e-feGaussianBlur-005.svg
e-feGaussianBlur-006.svg
e-feGaussianBlur-007.svg
e-feGaussianBlur-008.svg
e-feGaussianBlur-009.svg
e-feGaussianBlur-010.svg
e-feMerge-001.svg
e-feMerge-002.svg
e-feOffset-001.svg
e-feOffset-002.svg
e-feOffset-003.svg
e-feOffset-004.svg
e-feOffset-005.svg
e-feOffset-006.svg
e-feOffset-007.svg
e-feTile-001.svg
e-feTile-002.svg
e-feTile-003.svg
e-feTile-004.svg
e-feTile-005.svg
e-feTile-006.svg
e-filter-001.svg
e-filter-002.svg
e-filter-003.svg
e-filter-004.svg
e-filter-005.svg
e-filter-006.svg
e-filter-007.svg
e-filter-008.svg
e-filter-009.svg
e-filter-010.svg
e-filter-011.svg
e-filter-012.svg
e-filter-013.svg
e-filter-014.svg
e-filter-015.svg
e-filter-016.svg
e-filter-017.svg
e-filter-018.svg
e-filter-019.svg
e-filter-020.svg
e-filter-021.svg
e-filter-022.svg
e-filter-023.svg
e-filter-024.svg
e-filter-025.svg
e-filter-026.svg
e-filter-027.svg
e-filter-028.svg
e-filter-029.svg
e-filter-030.svg
e-filter-031.svg
e-filter-032.svg
e-filter-033.svg
e-filter-034.svg
e-filter-035.svg
e-filter-036.svg
e-filter-037.svg
e-filter-038.svg
e-filter-039.svg
e-filter-040.svg
e-filter-041.svg
e-filter-042.svg
e-filter-043.svg
e-filter-044.svg
e-filter-045.svg
e-filter-046.svg
e-filter-047.svg
e-filter-048.svg
e-filter-049.svg
e-filter-050.svg
e-filter-051.svg
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment