dessin

Crates.iodessin
lib.rsdessin
version0.8.23
created_at2021-07-21 12:57:55.286082+00
updated_at2025-08-26 07:17:21.657852+00
descriptionBuild complex drawing for PDF, SVG, Images or Dioxus
homepage
repositoryhttps://github.com/432-technologies/dessin
max_upload_size
id425511
size328,779
morillon françois (SadCl0wn)

documentation

README

dessin

dessin is library aimed at building complex drawings, combine them, move them and export them as PDF or SVG.

Details about the [macro][crate::macros].

Example

use dessin::prelude::*;
use palette::{named, Srgb};

#[derive(Default, Shape)]
struct MyShape {
  text: String,
}
impl MyShape {
  fn say_this(&mut self, what: &str) {
    self.text = format!("{} And check this out: `{what}`", self.text);
  }
}
impl From<MyShape> for Shape {
  fn from(MyShape { text }: MyShape) -> Self {
    dessin!(*Text(fill = Srgb::<f32>::from_format(named::RED).into_linear(), { text })).into()
  }
}

fn main() {
  let dessin = dessin!(for x in 0..10 {
    let radius = x as f32 * 10.;

    dessin!([
      *Circle(
        fill = Srgb::<f32>::from_format(named::RED).into_linear(),
        { radius },
        translate = [x as f32 * 5., 10.],
      ),
      *Text(fill = Srgb::<f32>::from_format(named::BLACK).into_linear(), font_size = 10., text = "Hi !",),
    ])
  });

  let dessin = dessin!([
    { dessin }(scale = [2., 2.]),
    MyShape(say_this = "Hello world"),
  ]);
}

Components

[Base components][crate::shapes] are defined in the shapes module.

[Components using base ones][crate::contrib] are defined in the contrib module.

In dessin, a component is just a struct/enum that can be converted to a [Shape][crate::shapes::Shape], and implements the [Default][std::default::Default] trait.

This means that a component can be as simple as:

use dessin::prelude::*;

#[derive(Default)]
struct MyComponent {}

impl From<MyComponent> for Shape {
	fn from(my_component: MyComponent) -> Shape {
		dessin!(
			// Implementation...
		)
	}
}

Since the [dessin!][dessin_macros::dessin] macro is only syntactic sugar for creating a [Shape][crate::shapes::Shape], all parameters are simply rust function with the following signature: fn (&mut self, argument_value: ArgumentType) {...}.

It can be tedious to create these function for all parameters, so the derive macro [Shape][dessin_macro::shape] is here to do exactly that.

So

	#[derive(Default, Shape)]
struct MyComponent {
	// This auto implements ShapeOp for MyComponent using `my_local_transform` as the storage.
	#[local_transform]
		my_local_transform: Transform2<f32>,

	// Generate a function for u32
	value: u32,

	// Does not generate a function for this field
	#[shape(skip)]
	skip_value: u32,

	// Generates a function for Into<u32>
	#[shape(into)]
	into_value: u32,

	// Generates a function that does not take any arguments, but set `my_bool` to true
	#[shape(bool)]
	my_bool: bool,
}

becomes


	#[derive(Default)]
struct MyComponent {
	my_local_transform: Transform2<f32>,
	value: u32,
	skip_value: u32,
	into_value: u32,
	my_bool: bool,
}

impl ShapeOp for MyComponent { /* skip impl */ }

impl MyComponent {
	pub fn value(&mut self, value: u32) -> &mut Self {
        /* skip impl */
    }
	pub fn into_value<T: Into<u32>>(&mut self, value: T) -> &mut Self {
        /* skip impl */
    }
	pub fn my_bool(&mut self) -> &mut Self {
        /* skip impl */
    }
}

To be precise, all functions generated by this derive macro, return &mut Self to chain function together. Generated functions have the same name as their corresponding field. This derive macro also generate corresponding with_xxxx, taking self instead of &mut self and returning Self.

One still does need to implement From<MyComponent> for Shape { ... } manually.

Implement own export format.

Documentation can be found in the [export] module.

License: MIT

Commit count: 266

cargo fmt