12 个不稳定版本 (3 个重大更改)

0.4.0 2024年1月21日
0.4.0-rc.02024年1月20日
0.3.0 2023年12月28日
0.2.0 2023年10月22日
0.1.0-alpha.22023年9月30日

#77 in 可视化

Download history 33/week @ 2024-04-07 20/week @ 2024-04-14 177/week @ 2024-04-21 10/week @ 2024-04-28 18/week @ 2024-05-05 43/week @ 2024-05-12 20/week @ 2024-05-19 15/week @ 2024-05-26 24/week @ 2024-06-02 12/week @ 2024-06-09 12/week @ 2024-06-16 18/week @ 2024-06-23 66/week @ 2024-06-30 7/week @ 2024-07-07 19/week @ 2024-07-14 22/week @ 2024-07-21

每月下载量 114
用于 4 crates

MIT 许可证

6MB
4.5K SLoC

vsvg: 绘图仪图形的核心库

github Latest version Documentation GitHub

vsvg 是项目的核心crate。它实现了数据结构、I/O和算法,用于导入、创建、操作和导出用于绘图仪生成艺术的矢量图形。它在目的上与vpype的核心库类似,但有许多改进(见下文)。

此crate及其配套的vsvg-viewervsvg项目的一部分,并为whiskers交互式草图环境提供动力。

示例

use vsvg::{DocumentTrait, LayerTrait, PathTrait};

fn main() {
    /* == Document == */
    let mut doc = vsvg::Document::default();

    // push a path to layer 1
    doc.push_path(1, vec![(0., 0.), (100., 100.), (200., 0.), (0., 0.)]);

    /* == Layers == */
    let mut layer = vsvg::Layer::default();
    layer.metadata_mut().name = "Layer 2".to_string();

    // vsvg uses kurbo internally, and its API is compatible with it
    layer.push_path(kurbo::Circle::new((50., 50.), 30.));
    doc.layers_mut().insert(2, layer);

    /* == Path == */
    // Amongst various ways to create a path, the SVG <path> syntax is supported.
    let mut path = vsvg::Path::from_svg("M 200 200 L 200 400 Q 500 300 200 200 Z").unwrap();
    path.metadata_mut().color = vsvg::Color::DARK_GREEN;
    path.metadata_mut().stroke_width = 3.0;
    doc.push_path(3, path);

    // save to SVG
    doc.to_svg_file("basic.svg").unwrap();
}

这生成了以下SVG

demo SVG

vpype相比

此crate提供与核心vpype包及其Document/LineCollection结构类似的函数。然而,它带来了一系列改进(见下文)。将来,一个覆盖vsvg的Python包装器将取代vpype的核心包,从而实现vpype 2.0

安装

cargo add vsvg

快速

"快速"意味着比vpype快得多。考虑以下命令

vpype read 300_beziers.svg show

在我的电脑(2021年MacBook Pro M1 Max)上,vpype大约需要570ms才能启动。然后它需要另外140ms来加载包含300条贝塞尔曲线的基准文件。然后启动查看器(这部分实际上相当快)。

截至 today vsvg 需要 ~3.6ms 来启动和加载相同的SVG文件。它感觉几乎是瞬间的。

在另一个测试中,使用一个相当病态的90MB SVG,vsvg需要1.4秒来加载文件,而vpype则需要超过30秒。

支持贝塞尔曲线

vsvg使用的核心路径数据结构是kurbo::BezPath。它与SVG中的<path>元素类似,由一系列绘图命令组成,如“移动到”、“画线到”、“二次贝塞尔到”、“三次贝塞尔到”和“闭合”。这与vpype的方法有很大的不同,在vpype中,所有内容都被线性化为多边形。这种路径表示的主要优点是在所有曲线元素中,与多边形相比,精度更高且更紧凑。

whiskers中的bezpath示例提供了关于如何在vsvg中使用kurbo::BezPath的见解。

请注意,kurbo::BezPath不包括圆弧/圆/椭圆命令。当绘制这些基本形状(或加载包含它们的SVG文件)时,它们会被转换成三次贝塞尔曲线。尽管这种近似并不完全准确,但与多边形相比,它要好得多。例如,一个圆通常用4个三次贝塞尔曲线(16个坐标)来近似,而对于较低的精度,则需要数百个线段。

复合路径

kurbo::BezPath数据结构的一个微妙但决定性的优点是它可以包含多个子路径,也就是Inkscape中的“组合”路径操作。这是通过使用多个“移动到”命令实现的。这意味着可以以语义正确的方式模拟出带有孔的形状,例如,孔实际上没有被填充。以前,这样的形状是通过不同的、无关的路径表示的。

此外,这将为处理带有孔的多边形的阴影算法提供支持,例如,孔没有被实际填充。目前使用vpype是无法做到这一点的。vsketchShape目前可以实现这一点,但代价是大量内部/外部复杂性。

改进的线性化

vsvg保留了将曲线元素转换为多边形(即线性化)的能力,因为这一步骤仍被某些操作所需要。例如,导出G代码(一个尚未实现的功能)通常需要完全线性化的路径数据。同样,vsvg-viewercrate需要线性化的路径进行渲染。

线性化过程比vpype更好,具有改进的容差处理。段的大小根据曲率进行调整,而不是遵守绝对最大段长度,这在曲线几乎是直线时可以最小化所需的点数。

为了方便地支持线性化,vsvg提供了一系列数据结构(FlattenedDocument/FlattenedLayer/FlattenedPath),这些数据结构通常与基于kurbo::BezPath的主层次结构的行为相同。

路径级元数据

vsvg维护了每个路径的元数据,如颜色和线宽。这比vpype有所改进,因为vpype只提供每层元数据。

WebAssembly就绪

尽管我还没有整理出细节,但整个vsvg项目都与WebAssembly目标兼容。这意味着vsvg大多数本机功能都可以在Web上提供,包括显示和交互性。这为构建基于Web的工具、生成器等提供了大量非常好的机会。

这是vpype的未来吗?

也许吧。至少我非常愿意这样做。

vpype 目前由两个包组成: vpypevpype-cli。前者实现了“引擎”和API,然后被 vpype-cli 和插件使用以提供CLI接口。这个项目探索的是完全用Rust重写 vpype 包的机会,在这个过程中,该包将被适当地重命名为 vpype-core。这将大大提高 vpype 的性能,因为Rust编译为本地代码并且具有更好的并发性。

依赖项

~18–27MB
~412K SLoC