douglau / footile Goto Github PK
View Code? Open in Web Editor NEWA 2D vector graphics library written in Rust
License: Apache License 2.0
A 2D vector graphics library written in Rust
License: Apache License 2.0
In the documentation it says:
pub fn absolute(self) -> Self
Use absolute coordinates for subsequent operations.
This is the default setting.
But testing out the code, relative is the default.
For reusing a Plotter
to reduce number of allocations, it's necessary to clear the contained Raster
before each composite. The way this must be done currently is:
let mut pr = p.raster();
pr.clear();
p = Plotter::new(pr);
p.set_transform(Transform::{...}); // Reset the transform
It would be more elegant to have an API to do either:
p.raster_mut().clear();
or
p.clear();
Example triggers panic: #20
use footile::{Plotter, PathOp::*};
mod png;
fn main() -> Result<(), std::io::Error> {
let path = vec![
Move(8.0, 4.0),
Line(8.0, 3.0),
Cubic(8.0, 3.0, 8.0, 3.0, 9.0, 3.75),
Line(8.0, 3.75),
Line(8.5, 3.75),
Line(8.5, 3.5),
Close(),
];
let mut p = Plotter::new(64, 64);
png::write_mask(p.fill(&path, footile::FillRule::NonZero), "./overlapping.png")
}
thread 'main' panicked at 'assertion failed: dy > Fixed::ZERO', src/fig.rs:121:9
12: 0x560a45c0b21b - footile::fig::Edge::new::ha025b804eef6ddc7 at src/fig.rs:121 13: 0x560a45c0e249 - footile::fig::Scanner::edge_regular::hded8104148dc4b5a at src/fig.rs:636 14: 0x560a45c0dc4a - footile::fig::Scanner::update_edges::h8eb063b97b6c4e32 at src/fig.rs:594 15: 0x560a45c0d058 - footile::fig::Scanner::scan_vertex::hb7e7c4706bd86814 at src/fig.rs:483 16: 0x560a45c0cd71 - footile::fig::Fig::fill::h494ccc1f0bc5b08e at src/fig.rs:439 17: 0x560a45b93381 - footile::plotter::Plotter::fill::hf6b17fb11e1691d2 at /home/aldaron/lordaldaron/footile/src/plotter.rs:331 18: 0x560a45b90b7a - overlapping::main::h878a2bc11f333978 at examples/overlapping.rs:17
When creating a larger Raster, it should be possible to composite small masks. This will greatly reduce compositing time.
Allow all stroke parameters to vary while stroking. Use a second iterator which is zipped with Iterator to specify them.
Path2D cannot be generated dynamically
It would be helpful if PathOp derived Debug, Copy, Clone, etc.
Transforming within a path allows rotation, etc.
The following code generates two images that don't render correctly.
use footile::{FillRule, Plotter, PathBuilder};
fn main() -> Result<(), std::io::Error> {
let mut p = Plotter::new(64, 64);
let path = PathBuilder::new()
.absolute()
.move_to(15.562022, 10.953022)
.line_to(15.562022, 38.120804)
.line_to(11.504303, 28.536913) // extra pixel here
.line_to(11.504303, 10.953022)
.build();
p.fill(path.iter(), FillRule::NonZero).write_png("test_a.png")?;
let path = PathBuilder::new()
.absolute()
.move_to(37.02108, 10.953022)
.line_to(41.546997, 10.953022)
.line_to(41.546997, 28.536913)
.line_to(41.0788, 38.120804)
.line_to(37.48928, 38.120804)
.line_to(37.02108, 28.536913)
.line_to(37.02108, 10.953022)
.build();
p.fill(path.iter(), FillRule::NonZero).write_png("test_b.png")
}
Here they are:
test_a has a pixel with a greater fill value than it should and test_b has a pixel with a lower fill value than it should.
Currently, Raster and Mask widths are assumed to be divisible by 4.
Hello,
I found out that leaving enabled the use-simd
feature, every example fails to run when compiled in normal unoptimized mode. But only heptagram
and drop
fails to run when compiled in --release
mode.
But disabling the use-simd
feature makes them all work in normal mode. But interestingly drop
and fishy
fails in --release
mode.
This may hint to a bug in one of the unsafe code blocks.
Since drop fails in 3 of the 4 combinations of feature and mode, this is the relevant gdb output from running them:
use-simd
enabledcargo build --example drop && gdb ./target/debug/examples/drop
(gdb) run
Starting program: .../footile/target/debug/examples/drop
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGILL, Illegal instruction.
core::core_arch::x86::sse2::_mm_slli_si128_impl (a=..., imm8=8) at /rustc/fc50f328b0353b285421b8ff5d4100966387a997/src/libcore/../stdsimd/crates/core_arch/src/x86/sse2.rs:429
429 /rustc/fc50f328b0353b285421b8ff5d4100966387a997/src/libcore/../stdsimd/crates/core_arch/src/x86/sse2.rs: No such file or directory.
cargo build --release --example drop && gdb ./target/release/examples/drop
(gdb) run
Starting program: .../footile/target/release/examples/drop
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGILL, Illegal instruction.
0x00005555555613a2 in <footile::gray8::Gray8 as footile::pixel::PixFmt>::over ()
(gdb)
use-simd
disabledcargo build --release --example drop && gdb ./target/release/examples/drop
(gdb) run
Starting program: .../footile/target/release/examples/drop
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGILL, Illegal instruction.
0x0000555555560a52 in <footile::gray8::Gray8 as footile::pixel::PixFmt>::over ()
(gdb)
Ubuntu 18.04 kernel 4.15.0-48-generic
CPU:
processor : 5
vendor_id : AuthenticAMD
cpu family : 16
model : 10
model name : AMD Phenom(tm) II X6 1055T Processor
stepping : 0
microcode : 0x10000dc
cpu MHz : 803.788
cache size : 512 KB
physical id : 0
siblings : 6
core id : 3
cpu cores : 6
apicid : 5
initial apicid : 3
fpu : yes
fpu_exception : yes
cpuid level : 6
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt cpb hw_pstate vmmcall npt lbrv svm_lock nrip_save pausefilter
bugs : tlb_mmatch apic_c1e fxsave_leak sysret_ss_attrs null_seg amd_e400 spectre_v1 spectre_v2
bogomips : 5625.75
TLB size : 1024 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate cpb
This is an important piece of functionality for a 2d library. I have been playing around with the code needed to support this kind of thing here: https://github.com/jrmuizel/sw-composite/blob/master/src/lib.rs
Feel free to crib anything from it that you'd like.
This matches Cairo, Skia and most other graphics libraries. It also allows for much better performance because we avoid the division on each blend.
Allow using a clip mask to Plotter improve fill/compositing performance.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.