roughr/lib.rs
1// This crate is entirely safe
2#![forbid(unsafe_code)]
3// Ensures that `pub` means published in the public API.
4// This property is useful for reasoning about breaking API changes.
5#![deny(unreachable_pub)]
6
7//!
8//! This crate is a rustlang port of [Rough.js](https://github.com/rough-stuff/rough) npm package written by
9//! [@pshihn](https://github.com/pshihn).
10//!
11//! This package exposes functions to generate rough drawing primitives which looks like hand drawn sketches.
12//! This is the core create of operations to create rough drawings. It exposes its own primitive drawing types for lines
13//! curves, arcs, polygons, circles, ellipses and even svg paths.
14//! Works on [Point2D](https://docs.rs/euclid/0.22.7/euclid/struct.Point2D.html) type from [euclid](https://github.com/servo/euclid) crate
15//!
16//! On its own this crate can not draw on any context. One needs to use existing drawing libraries such as [piet](https://github.com/linebender/piet),
17//! [raqote](https://github.com/jrmuizel/raqote), [tiny-skia](https://github.com/RazrFalcon/tiny-skia) etc in combination with
18//! roughr. In this workspace an example adapter is implemented for [piet](https://github.com/linebender/piet). Below examples are
19//! output of [rough_piet](https://github.com/orhanbalci/rough-rs/tree/main/rough_piet) adapter.
20//!
21//! ## 📦 Cargo.toml
22//!
23//! ```toml
24//! [dependencies]
25//! roughr = "0.1"
26//! ```
27//!
28//! ## 🔧 Example
29//!
30//! ### Rectangle
31//!
32//! ```ignore
33//! let options = OptionsBuilder::default()
34//! .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
35//! .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
36//! .fill_style(FillStyle::Hachure)
37//! .fill_weight(DPI * 0.01)
38//! .build()
39//! .unwrap();
40//! let generator = KurboGenerator::new(options);
41//! let rect_width = 100.0;
42//! let rect_height = 50.0;
43//! let rect = generator.rectangle::<f32>(
44//! (WIDTH as f32 - rect_width) / 2.0,
45//! (HEIGHT as f32 - rect_height) / 2.0,
46//! rect_width,
47//! rect_height,
48//! );
49//! let background_color = Color::from_hex_str("96C0B7").unwrap();
50//!
51//! rc.fill(
52//! Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
53//! &background_color,
54//! );
55//! rect.draw(&mut rc);
56//! ```
57//!
58//! ### 🖨️ Output Rectangle
59//! 
60//!
61//! ### Circle
62//!
63//! ```ignore
64//! let options = OptionsBuilder::default()
65//! .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
66//! .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
67//! .fill_style(FillStyle::Hachure)
68//! .fill_weight(DPI * 0.01)
69//! .build()
70//! .unwrap();
71//! let generator = KurboGenerator::new(options);
72//! let circle_paths = generator.circle::<f32>(
73//! (WIDTH as f32) / 2.0,
74//! (HEIGHT as f32) / 2.0,
75//! HEIGHT as f32 - 10.0f32,
76//! );
77//! let background_color = Color::from_hex_str("96C0B7").unwrap();
78//!
79//! rc.fill(
80//! Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
81//! &background_color,
82//! );
83//! circle_paths.draw(&mut rc);
84//! ```
85//!
86//! ### 🖨️ Output Circle
87//! 
88//!
89//!
90//! ### Ellipse
91//!
92//! ```ignore
93//! let options = OptionsBuilder::default()
94//! .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
95//! .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
96//! .fill_style(FillStyle::Hachure)
97//! .fill_weight(DPI * 0.01)
98//! .build()
99//! .unwrap();
100//! let generator = KurboGenerator::new(options);
101//! let ellipse_paths = generator.ellipse::<f32>(
102//! (WIDTH as f32) / 2.0,
103//! (HEIGHT as f32) / 2.0,
104//! WIDTH as f32 - 10.0,
105//! HEIGHT as f32 - 10.0,
106//! );
107//! let background_color = Color::from_hex_str("96C0B7").unwrap();
108//!
109//! rc.fill(
110//! Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
111//! &background_color,
112//! );
113//! ellipse_paths.draw(&mut rc);
114//! ```
115//!
116//! ### 🖨️ Output Ellipse
117//! 
118//!
119//!
120//! ### Svg Path
121//!
122//! ```ignore
123//! let options = OptionsBuilder::default()
124//! .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
125//! .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
126//! .fill_style(FillStyle::Hachure)
127//! .fill_weight(DPI * 0.01)
128//! .build()
129//! .unwrap();
130//! let generator = KurboGenerator::new(options);
131//! let heart_svg_path = "M140 20C73 20 20 74 20 140c0 135 136 170 228 303 88-132 229-173 229-303 0-66-54-120-120-120-48 0-90 28-109 69-19-41-60-69-108-69z".into();
132//! let heart_svg_path_drawing = generator.path::<f32>(heart_svg_path);
133//! let background_color = Color::from_hex_str("96C0B7").unwrap();
134//!
135//! rc.fill(
136//! Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
137//! &background_color,
138//! );
139//! heart_svg_path_drawing.draw(&mut rc);
140//! ```
141//!
142//! ### 🖨️ Output Svg Path
143//! 
144//!
145//! ## Filler Implementation Status
146//! - [x] Hachure
147//! - [x] Zigzag
148//! - [x] Cross-Hatch
149//! - [x] Dots
150//! - [x] Dashed
151//! - [x] Zigzag-Line
152//!
153//! ## 🔭 Examples
154//!
155//! For more examples have a look at the
156//! [examples](https://github.com/orhanbalci/rough-rs/tree/main/rough_piet/examples) folder.
157
158#[macro_use]
159extern crate derive_builder;
160
161pub mod core;
162pub mod filler;
163pub mod generator;
164pub mod geometry;
165pub mod points_on_path;
166pub mod renderer;
167
168pub use euclid::Point2D;
169pub use palette::Srgba;
170pub use svgtypes::*;