Skip to main content

Crate roughr

Crate roughr 

Source
Expand description

This crate is a rustlang port of Rough.js npm package written by @pshihn.

This package exposes functions to generate rough drawing primitives which looks like hand drawn sketches. This is the core create of operations to create rough drawings. It exposes its own primitive drawing types for lines curves, arcs, polygons, circles, ellipses and even svg paths. Works on Point2D type from euclid crate

On its own this crate can not draw on any context. One needs to use existing drawing libraries such as piet, raqote, tiny-skia etc in combination with roughr. In this workspace an example adapter is implemented for piet. Below examples are output of rough_piet adapter.

§📦 Cargo.toml

[dependencies]
roughr = "0.14"

§🔧 Example

§Rectangle

ⓘ
let options = OptionsBuilder::default()
    .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
    .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
    .fill_style(FillStyle::Hachure)
    .fill_weight(DPI * 0.01)
    .build()
    .unwrap();
let generator = KurboGenerator::new(options);
let rect_width = 100.0;
let rect_height = 50.0;
let rect = generator.rectangle::<f32>(
    (WIDTH as f32 - rect_width) / 2.0,
    (HEIGHT as f32 - rect_height) / 2.0,
    rect_width,
    rect_height,
);
let background_color = Color::from_hex_str("96C0B7").unwrap();

rc.fill(
    Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
    &background_color,
);
rect.draw(&mut rc);

§🖨️ Output Rectangle

rectangle

§Circle

ⓘ
let options = OptionsBuilder::default()
    .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
    .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
    .fill_style(FillStyle::Hachure)
    .fill_weight(DPI * 0.01)
    .build()
    .unwrap();
let generator = KurboGenerator::new(options);
let circle_paths = generator.circle::<f32>(
    (WIDTH as f32) / 2.0,
    (HEIGHT as f32) / 2.0,
    HEIGHT as f32 - 10.0f32,
);
let background_color = Color::from_hex_str("96C0B7").unwrap();

rc.fill(
    Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
    &background_color,
);
circle_paths.draw(&mut rc);

§🖨️ Output Circle

circle

§Ellipse

ⓘ
let options = OptionsBuilder::default()
    .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
    .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
    .fill_style(FillStyle::Hachure)
    .fill_weight(DPI * 0.01)
    .build()
    .unwrap();
let generator = KurboGenerator::new(options);
let ellipse_paths = generator.ellipse::<f32>(
    (WIDTH as f32) / 2.0,
    (HEIGHT as f32) / 2.0,
    WIDTH as f32 - 10.0,
    HEIGHT as f32 - 10.0,
);
let background_color = Color::from_hex_str("96C0B7").unwrap();

rc.fill(
    Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
    &background_color,
);
ellipse_paths.draw(&mut rc);

§🖨️ Output Ellipse

ellipse

§Svg Path

ⓘ
let options = OptionsBuilder::default()
    .stroke(Srgba::from_raw(&[114u8, 87u8, 82u8, 255u8]).into_format())
    .fill(Srgba::from_raw(&[254u8, 246u8, 201u8, 255u8]).into_format())
    .fill_style(FillStyle::Hachure)
    .fill_weight(DPI * 0.01)
    .build()
    .unwrap();
let generator = KurboGenerator::new(options);
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();
let heart_svg_path_drawing = generator.path::<f32>(heart_svg_path);
let background_color = Color::from_hex_str("96C0B7").unwrap();

rc.fill(
    Rect::new(0.0, 0.0, WIDTH as f64, HEIGHT as f64),
    &background_color,
);
heart_svg_path_drawing.draw(&mut rc);

§🖨️ Output Svg Path

svgheart

§Filler Implementation Status

  • Hachure
  • Zigzag
  • Cross-Hatch
  • Dots
  • Dashed
  • Zigzag-Line

§🎛️ Options

Every drawing is controlled by an Options value, built with OptionsBuilder. All fields have defaults, so set only what you want to change. The most useful ones are roughness, bowing, stroke, stroke_width, fill, fill_style, hachure_gap and seed.

Each image below draws the same shape with only one option changed, from left to right. The field docs of Options explain every option and its default. To try options interactively, run the drawing_app example of rough_iced.

Outline

roughness

bowing

max_randomness_offset

stroke_width

disable_multi_stroke

preserve_vertices

stroke_line_dash

seed

Curves and SVG paths

curve_fitting

curve_step_count

curve_tightness

simplification

Fill

fill_style

hachure_angle

hachure_gap

fill_weight

dash_offset

dash_gap

zigzag_offset

disable_multi_stroke_fill

§🧾 Drawing SVG files

path takes SVG path data, the d attribute of a <path> element. To sketch a whole SVG file, which may also contain shapes like <rect> and <circle>, transforms and styles, first convert it to plain paths with usvg, then draw every path with its own colors:

ⓘ
let tree = usvg::Tree::from_data(&svg_bytes, &usvg::Options::default())?;
// For each usvg::Path in the tree:
let data = path.data().clone().transform(path.abs_transform()).unwrap();
let options = OptionsBuilder::default()
    .fill(/* the path's fill color */)
    .stroke(/* the path's stroke color */)
    .build()?;
let drawing = SkiaGenerator::new(options).path::<f32>(to_svg_path_data(&data));
drawing.draw(&mut pixmap.as_mut());

The complete, runnable version is the svg example of rough_tiny_skia:

cargo run -p rough_tiny_skia --example svg -- input.svg output.png

svg

§🔭 Examples

For more examples have a look at the examples folder.

Modules§

core
filler
generator
geometry
points_on_path
renderer

Structs§

Angle
Representation of the <angle> type.
AspectRatio
Representation of the preserveAspectRatio attribute.
Color
Representation of the <color> type.
FilterValueListParser
A pull-based <filter-value-list> parser.
FontShorthand
The values of a font shorthand.
FuncIRI
Representation of the <FuncIRI> type.
IRI
Representation of the <IRI> type.
Length
Representation of the <length> type.
LengthListParser
A pull-based <list-of-length> parser.
Number
An SVG number.
NumberListParser
A pull-based <list-of-numbers> parser.
PaintOrder
Representation of the paint-order property.
PathParser
A pull-based path data parser.
PointsParser
A pull-based <list-of-points> parser.
SimplifyingPathParser
A simplifying Path Data parser.
Transform
Representation of the <transform> type.
TransformListParser
A pull-based <transform-list> parser.
TransformOrigin
Representation of the <transform-origin> type.
ViewBox
Representation of the <viewBox> type.

Enums§

Align
Representation of the align value of the preserveAspectRatio attribute.
AngleUnit
List of all SVG angle units.
DirectionalPosition
List of all SVG directional positions.
EnableBackground
Representation of the enable-background attribute.
Error
List of all errors.
FilterValue
Representation of the <filter-function> | <url> type.
FilterValueListParserError
A list of possible FilterValueListParser errors.
FontFamily
A type of font family.
LengthUnit
List of all SVG length units.
Paint
Representation of the <paint> type.
PaintFallback
Representation of the fallback part of the <paint> type.
PaintOrderKind
paint-order property variants.
PathSegment
Representation of a path segment.
SimplePathSegment
Representation of a simple path segment.
TransformListToken
Transform list token.
TransformOriginError
List of possible TransformOrigin parsing errors.
ViewBoxError
List of possible ViewBox parsing errors.

Traits§

Float
Generic trait for floating point numbers
FromPrimitive
A generic trait for converting a number to a value.
Trig
Trait for basic trigonometry functions, so they can be used on generic numeric types

Functions§

parse_font_families
Parses a list of font families and generic families from a string.

Type Aliases§

Point2D
Srgba
Non-linear sRGB with an alpha component.