Skip to main content

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//! ![rectangle](https://raw.githubusercontent.com/orhanbalci/rough-rs/main/roughr/assets/rectangle.png)
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//! ![circle](https://raw.githubusercontent.com/orhanbalci/rough-rs/main/roughr/assets/circle.png)
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//! ![ellipse](https://raw.githubusercontent.com/orhanbalci/rough-rs/main/roughr/assets/ellipse.png)
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//! ![svgheart](https://raw.githubusercontent.com/orhanbalci/rough-rs/main/roughr/assets/heart_svg_path.png)
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::*;