Revision control
Copy as Markdown
Other Tools
use aa_stroke::{StrokeStyle, LineCap, LineJoin, Point, Stroker, tri_rasterize::rasterize_to_mask};
fn write_image(data: &[u8], path: &str, width: u32, height: u32) {
use std::path::Path;
use std::fs::File;
use std::io::BufWriter;
/*let mut png_data: Vec<u8> = vec![0; (width * height * 3) as usize];
let mut i = 0;
for pixel in data {
png_data[i] = ((pixel >> 16) & 0xff) as u8;
png_data[i + 1] = ((pixel >> 8) & 0xff) as u8;
png_data[i + 2] = ((pixel >> 0) & 0xff) as u8;
i += 3;
}*/
let path = Path::new(path);
let file = File::create(path).unwrap();
let w = &mut BufWriter::new(file);
let mut encoder = png::Encoder::new(w, width, height); // Width is 2 pixels and height is 1.
encoder.set_color(png::ColorType::Grayscale);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header().unwrap();
writer.write_image_data(&data).unwrap(); // Save
}
// WpfGfx uses CShapeBase which has a set of Figures
// Figures have FigureFlags which include FigureFlagClosed
// so that we can know ahead of time whether the figure/subpath
// is closed
// How do we handle transformed paths? D2D seems to only support transforms that
// can be applied before stroking. (one's with uniform scale?)
fn main() {
let mut stroker = Stroker::new(&StrokeStyle{
cap: LineCap::Round,
join: LineJoin::Bevel,
width: 20.,
..Default::default()});
stroker.move_to(Point::new(20., 20.), false);
stroker.line_to(Point::new(100., 100.));
stroker.line_to_capped(Point::new(110., 20.));
stroker.move_to(Point::new(120., 20.), true);
stroker.line_to(Point::new(120., 50.));
stroker.line_to(Point::new(140., 50.));
stroker.close();
stroker.move_to(Point::new(20., 160.), true);
stroker.curve_to(Point::new(100., 160.), Point::new(100., 180.), Point::new(20., 180.));
stroker.close();
let stroked = stroker.finish();
dbg!(&stroked);
println!("num of vertices {}", stroked.len());
let mask = rasterize_to_mask(&stroked, 200, 200);
write_image(&mask,"out.png", 200, 200);
/*
struct Target;
impl CFlatteningSink for Target {
fn AcceptPointAndTangent(&mut self,
pt: &GpPointR,
// The point
vec: &GpPointR,
// The tangent there
fLast: bool
// Is this the last point on the curve?
) -> HRESULT {
todo!()
}
fn AcceptPoint(&mut self,
pt: &GpPointR,
// The point
t: f64,
// Parameter we're at
fAborted: &mut bool) -> HRESULT {
println!("{} {}", pt.x, pt.y);
return S_OK;
}
}
let bezier = CBezier::new([GpPointR { x: 0., y: 0. },
GpPointR { x: 0., y: 0. },
GpPointR { x: 0., y: 0. },
GpPointR { x: 100., y: 100. }]);
let mut t = Target{};
let mut f = CBezierFlattener::new(&bezier, &mut t, 0.1);
f.Flatten(false);*/
}