pub trait PaintScene: Any {
// Required methods
fn append(&mut self, transform: Affine, scene: &Scene) -> Result<(), ()>;
fn fill_path(
&mut self,
transform: Affine,
fill_rule: Fill,
path: &impl ExactPathElements,
);
fn stroke_path(
&mut self,
transform: Affine,
stroke_params: &Stroke,
path: &impl ExactPathElements,
);
fn set_brush(
&mut self,
brush: impl Into<StandardBrush>,
paint_transform: Affine,
);
fn set_blurred_rounded_rect_brush(
&mut self,
paint_transform: Affine,
color: Color,
rect: &Rect,
radius: f32,
std_dev: f32,
);
fn push_layer(
&mut self,
clip_transform: Affine,
clip_path: Option<&impl ExactPathElements>,
blend_mode: Option<BlendMode>,
opacity: Option<f32>,
);
fn pop_layer(&mut self);
// Provided methods
fn set_solid_brush(&mut self, color: Color) { ... }
fn fill_blurred_rounded_rect(
&mut self,
transform: Affine,
color: Color,
rect: &Rect,
radius: f32,
std_dev: f32,
) { ... }
fn push_clip_layer(
&mut self,
clip_transform: Affine,
path: &impl ExactPathElements,
) { ... }
fn push_blend_layer(&mut self, blend_mode: BlendMode) { ... }
fn push_opacity_layer(&mut self, opacity: f32) { ... }
}Expand description
A 2d scene or canvas.
These types are used to prepare a sequence of vector shapes to later be drawn by a Renderer.
From a Renderer, you can create a canvas which renders to a given texture using Renderer::create_scene.
Alternatively, you can use Scene, a reusable PaintScene, for cases such as a single SVG, or a GUI widget.
The canvas this type represents combines three separate concerns. These are:
- The brush, which describes what will be drawn by the following commands.
This can be a solid colour (
set_solid_brush), a gradient, an image (bothset_brush), or a blurred rounded rectangle (set_blurred_rounded_rect_brush). The brush’s coordinate system is currently relative to the drawn path’s coordinate system. - The area over which this brush is to be drawn.
This can either be a filled path (
fill_path) - The layer stack, which allows for multiple 2d contexts to be blended together, with clipping.
This separation of brush and drawing area is an experimental aspect of this API. More traditional drawing APIs either combines these concerns into single methods, or splits these out even further (those would be a “stateless” or “stateful” API, respectively). This middle ground is intended to allow drawing multiple shapes with a single brush, so as to allow brush-specific work to be re-used, without having a mechanism like a brush id.
This design is explicitly an experiment, pending empirical verification.
§Scene area
The canvas represented by this trait logically represents an unbounded area.
However, from a practical perspective, the area which might be visible depends on the specific scene type.
If it will be rendered to a texture (i.e. created using Renderer::create_scene) then only the texture’s viewport is relevant.
If this is a Scene, then when it is actually rendered (by being appended to a scene created
using Renderer::create_scene) it could be transformed, so any part of the scene could be visible.
As such, the inferred clipping from the scene viewports is limited.
Required Methods§
Sourcefn append(&mut self, transform: Affine, scene: &Scene) -> Result<(), ()>
fn append(&mut self, transform: Affine, scene: &Scene) -> Result<(), ()>
Insert the contents of Scene into the drawing sequence at this point, with the 2d affine
transform applied to its contents.
This will change the currently active brush, so you must reset the brush after calling this method. (TODO: Change the brush design, because that’s stupid!)
§Errors
This returns an error if:
sceneis hinted, butselfcannot guarantee that the hinting properties would be maintained. Hinted scenes can be appended to the final, renderer-specific, implementations ofPaintSceneor to other hintedScenes.sceneis hinted, but the transform would remove the hinting property. For hinted scenes, the only valid transforms are integer translations.scenedoes not apply to the same renderer asself.scenehas unbalanced layers (TODO: This isn’t implemented yet).
Sourcefn fill_path(
&mut self,
transform: Affine,
fill_rule: Fill,
path: &impl ExactPathElements,
)
fn fill_path( &mut self, transform: Affine, fill_rule: Fill, path: &impl ExactPathElements, )
Fill the interior of shape with the current brush.
The shape may contain multiple subpaths (e.g., for shapes with holes like a donut).
Each subpath is implicitly closed if needed with a straight line.
For self-intersecting or nested subpaths, the fill_rule determines which areas are considered interior.
Both shape and the current brush will be transformed using the 2d affine transform.
See the documentation on Fill’s variants for details on when you might choose a given fill rule.
Sourcefn stroke_path(
&mut self,
transform: Affine,
stroke_params: &Stroke,
path: &impl ExactPathElements,
)
fn stroke_path( &mut self, transform: Affine, stroke_params: &Stroke, path: &impl ExactPathElements, )
Stroke along path with the current brush, following the given stroke parameters.
Both the stroked area and the current brush will be transformed using the 2d affine transform.
Dashes configured in the stroke parameter will be expanded.
Sourcefn set_brush(
&mut self,
brush: impl Into<StandardBrush>,
paint_transform: Affine,
)
fn set_brush( &mut self, brush: impl Into<StandardBrush>, paint_transform: Affine, )
Set the current brush to brush.
This method is used to set the brush for images and gradients.
The paint_transform will be applied to only the brush contents, in
addition to the transform applied to the object.
For solid colors, this has no effect, and so you may prefer set_solid_brush.
Sourcefn set_blurred_rounded_rect_brush(
&mut self,
paint_transform: Affine,
color: Color,
rect: &Rect,
radius: f32,
std_dev: f32,
)
fn set_blurred_rounded_rect_brush( &mut self, paint_transform: Affine, color: Color, rect: &Rect, radius: f32, std_dev: f32, )
Set the current brush to represent a rounded rectangle blurred with an approximate gaussian filter.
This method is currently unimplemented on all backends, so should not be used.
For performance reasons, shapes drawn with this brush should not extend more than approximately
2.5 times std_dev away from the edges of rect (as any such points will not be perceptably
painted to, but calculations will still be performed for them).
This method effectively draws the blurred rounded rectangle clipped to the
shapes drawn with this brush.
This clipping is useful for drawing box shadows, where the shadow should only
be drawn outside the box.
If just the blurred rounded rectangle is desired, without any clipping,
use the simpler fill_blurred_rounded_rect.
For many users, that method will be easier to use.
For details on the algorithm used, see the 2020 Blog Post describing the technique, Blurred rounded rectangles.
Sourcefn push_layer(
&mut self,
clip_transform: Affine,
clip_path: Option<&impl ExactPathElements>,
blend_mode: Option<BlendMode>,
opacity: Option<f32>,
)
fn push_layer( &mut self, clip_transform: Affine, clip_path: Option<&impl ExactPathElements>, blend_mode: Option<BlendMode>, opacity: Option<f32>, )
Pushes a new layer clipped by the specified shape (if provided) and composed with previous layers using the specified blend mode.
Every drawing command after this call will be clipped by the shape
until the layer is popped.
For layers which are only added for clipping, you should
use push_clip_layer instead.
Opacity must be between 0.0 and 1.0, if provided. Layers with an opacity of zero may be optimised out, but this is not currently guaranteed.
However, the transforms are not saved or modified by the layer stack.
That is, the transform argument to this function only applies a transform to the clip shape.
Provided Methods§
Sourcefn set_solid_brush(&mut self, color: Color)
fn set_solid_brush(&mut self, color: Color)
Set the current brush to a solid color.
Sourcefn fill_blurred_rounded_rect(
&mut self,
transform: Affine,
color: Color,
rect: &Rect,
radius: f32,
std_dev: f32,
)
fn fill_blurred_rounded_rect( &mut self, transform: Affine, color: Color, rect: &Rect, radius: f32, std_dev: f32, )
Draw a rounded rectangle blurred with an approximate gaussian filter. This method resets the current brush.
This method is currently unimplemented on some backends, so should not be used.
If the rounded rectangle needs to be clipped, you can instead use
set_blurred_rounded_rect_brush.
The drawing is cut off 2.5 times std_dev away from the edges of rect for performance
reasons, as any points outside of that area would not be perceptably painted to.
For details on the algorithm used, see the 2020 Blog Post describing the technique, Blurred rounded rectangles.
Sourcefn push_clip_layer(
&mut self,
clip_transform: Affine,
path: &impl ExactPathElements,
)
fn push_clip_layer( &mut self, clip_transform: Affine, path: &impl ExactPathElements, )
Pushes a new layer clipped by the specified clip shape.
Every drawing command after this call will be clipped by the shape until the layer is popped.
However, the transforms are not saved or modified by the layer stack.
That is, the transform argument to this function only applies a transform to the clip shape.
Sourcefn push_blend_layer(&mut self, blend_mode: BlendMode)
fn push_blend_layer(&mut self, blend_mode: BlendMode)
Pushes a new layer which is not clipped and composed with previous layers using the given blend mode.
Every drawing command after this call will be composed as described until the layer is popped.
Sourcefn push_opacity_layer(&mut self, opacity: f32)
fn push_opacity_layer(&mut self, opacity: f32)
Pushes a new layer which is not clipped and composed with previous layers with its opacity multiplied by the given value.
Opacity must be between 0.0 and 1.0. Layers with an opacity of zero may be optimised out, but this is not currently guaranteed.
Every drawing command after this call will be composed as described until the layer is popped.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.