summaryrefslogtreecommitdiffstats
path: root/wgpu/src/layer
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--wgpu/src/layer.rs617
-rw-r--r--wgpu/src/layer/image.rs30
-rw-r--r--wgpu/src/layer/mesh.rs97
-rw-r--r--wgpu/src/layer/pipeline.rs17
-rw-r--r--wgpu/src/layer/text.rs70
5 files changed, 300 insertions, 531 deletions
diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs
index cc767c25..5c23669a 100644
--- a/wgpu/src/layer.rs
+++ b/wgpu/src/layer.rs
@@ -1,343 +1,326 @@
-//! Organize rendering primitives into a flattened list of layers.
-mod image;
-mod pipeline;
-mod text;
-
-pub mod mesh;
-
-pub use image::Image;
-pub use mesh::Mesh;
-pub use pipeline::Pipeline;
-pub use text::Text;
-
-use crate::core;
-use crate::core::alignment;
-use crate::core::{
- Color, Font, Pixels, Point, Rectangle, Size, Transformation, Vector,
-};
-use crate::graphics;
+use crate::core::renderer;
+use crate::core::{Background, Color, Point, Rectangle, Transformation};
use crate::graphics::color;
-use crate::graphics::Viewport;
-use crate::primitive::{self, Primitive};
+use crate::graphics::text::{Editor, Paragraph};
+use crate::graphics::Mesh;
+use crate::image::{self, Image};
use crate::quad::{self, Quad};
+use crate::text::{self, Text};
+use crate::triangle;
-/// A group of primitives that should be clipped together.
-#[derive(Debug)]
-pub struct Layer<'a> {
- /// The clipping bounds of the [`Layer`].
- pub bounds: Rectangle,
+use std::cell::{self, RefCell};
+use std::rc::Rc;
- /// The quads of the [`Layer`].
- pub quads: quad::Batch,
-
- /// The triangle meshes of the [`Layer`].
- pub meshes: Vec<Mesh<'a>>,
-
- /// The text of the [`Layer`].
- pub text: Vec<Text<'a>>,
+pub enum Layer<'a> {
+ Live(&'a Live),
+ Cached(cell::Ref<'a, Cached>),
+}
- /// The images of the [`Layer`].
- pub images: Vec<Image>,
+pub enum LayerMut<'a> {
+ Live(&'a mut Live),
+ Cached(cell::RefMut<'a, Cached>),
+}
- /// The custom pipelines of this [`Layer`].
- pub pipelines: Vec<Pipeline>,
+pub struct Stack {
+ live: Vec<Live>,
+ cached: Vec<Rc<RefCell<Cached>>>,
+ order: Vec<Kind>,
+ transformations: Vec<Transformation>,
+ previous: Vec<usize>,
+ current: usize,
+ live_count: usize,
}
-impl<'a> Layer<'a> {
- /// Creates a new [`Layer`] with the given clipping bounds.
- pub fn new(bounds: Rectangle) -> Self {
+impl Stack {
+ pub fn new() -> Self {
Self {
- bounds,
- quads: quad::Batch::default(),
- meshes: Vec::new(),
- text: Vec::new(),
- images: Vec::new(),
- pipelines: Vec::new(),
+ live: vec![Live::default()],
+ cached: Vec::new(),
+ order: vec![Kind::Live],
+ transformations: vec![Transformation::IDENTITY],
+ previous: Vec::new(),
+ current: 0,
+ live_count: 1,
}
}
- /// Creates a new [`Layer`] for the provided overlay text.
- ///
- /// This can be useful for displaying debug information.
- pub fn overlay(lines: &'a [impl AsRef<str>], viewport: &Viewport) -> Self {
- let mut overlay =
- Layer::new(Rectangle::with_size(viewport.logical_size()));
-
- for (i, line) in lines.iter().enumerate() {
- let text = text::Cached {
- content: line.as_ref(),
- bounds: Rectangle::new(
- Point::new(11.0, 11.0 + 25.0 * i as f32),
- Size::INFINITY,
- ),
- color: Color::new(0.9, 0.9, 0.9, 1.0),
- size: Pixels(20.0),
- line_height: core::text::LineHeight::default(),
- font: Font::MONOSPACE,
- horizontal_alignment: alignment::Horizontal::Left,
- vertical_alignment: alignment::Vertical::Top,
- shaping: core::text::Shaping::Basic,
- clip_bounds: Rectangle::with_size(Size::INFINITY),
- };
-
- overlay.text.push(Text::Cached(text.clone()));
-
- overlay.text.push(Text::Cached(text::Cached {
- bounds: text.bounds + Vector::new(-1.0, -1.0),
- color: Color::BLACK,
- ..text
- }));
- }
+ pub fn draw_quad(&mut self, quad: renderer::Quad, background: Background) {
+ let transformation = self.transformations.last().unwrap();
+ let bounds = quad.bounds * *transformation;
+
+ let quad = Quad {
+ position: [bounds.x, bounds.y],
+ size: [bounds.width, bounds.height],
+ border_color: color::pack(quad.border.color),
+ border_radius: quad.border.radius.into(),
+ border_width: quad.border.width,
+ shadow_color: color::pack(quad.shadow.color),
+ shadow_offset: quad.shadow.offset.into(),
+ shadow_blur_radius: quad.shadow.blur_radius,
+ };
+
+ self.live[self.current].quads.add(quad, &background);
+ }
- overlay
+ pub fn draw_paragraph(
+ &mut self,
+ paragraph: &Paragraph,
+ position: Point,
+ color: Color,
+ clip_bounds: Rectangle,
+ ) {
+ let paragraph = Text::Paragraph {
+ paragraph: paragraph.downgrade(),
+ position,
+ color,
+ clip_bounds,
+ transformation: self.transformations.last().copied().unwrap(),
+ };
+
+ self.live[self.current].text.push(paragraph);
}
- /// Distributes the given [`Primitive`] and generates a list of layers based
- /// on its contents.
- pub fn generate(
- primitives: &'a [Primitive],
- viewport: &Viewport,
- ) -> Vec<Self> {
- let first_layer =
- Layer::new(Rectangle::with_size(viewport.logical_size()));
-
- let mut layers = vec![first_layer];
-
- for primitive in primitives {
- Self::process_primitive(
- &mut layers,
- Transformation::IDENTITY,
- primitive,
- 0,
- );
- }
+ pub fn draw_editor(
+ &mut self,
+ editor: &Editor,
+ position: Point,
+ color: Color,
+ clip_bounds: Rectangle,
+ ) {
+ let paragraph = Text::Editor {
+ editor: editor.downgrade(),
+ position,
+ color,
+ clip_bounds,
+ transformation: self.transformations.last().copied().unwrap(),
+ };
+
+ self.live[self.current].text.push(paragraph);
+ }
- layers
+ pub fn draw_text(
+ &mut self,
+ text: crate::core::Text,
+ position: Point,
+ color: Color,
+ clip_bounds: Rectangle,
+ ) {
+ let transformation = self.transformation();
+
+ let paragraph = Text::Cached {
+ content: text.content,
+ bounds: Rectangle::new(position, text.bounds) * transformation,
+ color,
+ size: text.size * transformation.scale_factor(),
+ line_height: text.line_height,
+ font: text.font,
+ horizontal_alignment: text.horizontal_alignment,
+ vertical_alignment: text.vertical_alignment,
+ shaping: text.shaping,
+ clip_bounds: clip_bounds * transformation,
+ };
+
+ self.live[self.current].text.push(paragraph);
}
- fn process_primitive(
- layers: &mut Vec<Self>,
- transformation: Transformation,
- primitive: &'a Primitive,
- current_layer: usize,
+ pub fn draw_image(
+ &mut self,
+ handle: crate::core::image::Handle,
+ filter_method: crate::core::image::FilterMethod,
+ bounds: Rectangle,
) {
- match primitive {
- Primitive::Paragraph {
- paragraph,
- position,
- color,
- clip_bounds,
- } => {
- let layer = &mut layers[current_layer];
-
- layer.text.push(Text::Paragraph {
- paragraph: paragraph.clone(),
- position: *position,
- color: *color,
- clip_bounds: *clip_bounds,
- transformation,
- });
- }
- Primitive::Editor {
- editor,
- position,
- color,
- clip_bounds,
- } => {
- let layer = &mut layers[current_layer];
-
- layer.text.push(Text::Editor {
- editor: editor.clone(),
- position: *position,
- color: *color,
- clip_bounds: *clip_bounds,
- transformation,
- });
- }
- Primitive::Text {
- content,
- bounds,
- size,
- line_height,
- color,
- font,
- horizontal_alignment,
- vertical_alignment,
- shaping,
- clip_bounds,
- } => {
- let layer = &mut layers[current_layer];
-
- layer.text.push(Text::Cached(text::Cached {
- content,
- bounds: *bounds + transformation.translation(),
- size: *size * transformation.scale_factor(),
- line_height: *line_height,
- color: *color,
- font: *font,
- horizontal_alignment: *horizontal_alignment,
- vertical_alignment: *vertical_alignment,
- shaping: *shaping,
- clip_bounds: *clip_bounds * transformation,
- }));
- }
- graphics::Primitive::RawText(raw) => {
- let layer = &mut layers[current_layer];
+ let image = Image::Raster {
+ handle,
+ filter_method,
+ bounds: bounds * self.transformation(),
+ };
- layer.text.push(Text::Raw {
- raw: raw.clone(),
- transformation,
- });
- }
- Primitive::Quad {
- bounds,
- background,
- border,
- shadow,
- } => {
- let layer = &mut layers[current_layer];
- let bounds = *bounds * transformation;
-
- let quad = Quad {
- position: [bounds.x, bounds.y],
- size: [bounds.width, bounds.height],
- border_color: color::pack(border.color),
- border_radius: border.radius.into(),
- border_width: border.width,
- shadow_color: shadow.color.into_linear(),
- shadow_offset: shadow.offset.into(),
- shadow_blur_radius: shadow.blur_radius,
- };
-
- layer.quads.add(quad, background);
- }
- Primitive::Image {
- handle,
- filter_method,
- bounds,
- } => {
- let layer = &mut layers[current_layer];
-
- layer.images.push(Image::Raster {
- handle: handle.clone(),
- filter_method: *filter_method,
- bounds: *bounds * transformation,
- });
+ self.live[self.current].images.push(image);
+ }
+
+ pub fn draw_svg(
+ &mut self,
+ handle: crate::core::svg::Handle,
+ color: Option<Color>,
+ bounds: Rectangle,
+ ) {
+ let svg = Image::Vector {
+ handle,
+ color,
+ bounds: bounds * self.transformation(),
+ };
+
+ self.live[self.current].images.push(svg);
+ }
+
+ pub fn draw_mesh(&mut self, mut mesh: Mesh) {
+ match &mut mesh {
+ Mesh::Solid { transformation, .. }
+ | Mesh::Gradient { transformation, .. } => {
+ *transformation = *transformation * self.transformation();
}
- Primitive::Svg {
- handle,
- color,
+ }
+
+ self.live[self.current].meshes.push(mesh);
+ }
+
+ pub fn draw_layer(&mut self, mut layer: Live) {
+ layer.transformation = layer.transformation * self.transformation();
+
+ if self.live_count == self.live.len() {
+ self.live.push(layer);
+ } else {
+ self.live[self.live_count] = layer;
+ }
+
+ self.live_count += 1;
+ self.order.push(Kind::Live);
+ }
+
+ pub fn draw_cached_layer(&mut self, layer: &Rc<RefCell<Cached>>) {
+ {
+ let mut layer = layer.borrow_mut();
+ layer.transformation = self.transformation() * layer.transformation;
+ }
+
+ self.cached.push(layer.clone());
+ self.order.push(Kind::Cache);
+ }
+
+ pub fn push_clip(&mut self, bounds: Option<Rectangle>) {
+ self.previous.push(self.current);
+ self.order.push(Kind::Live);
+
+ self.current = self.live_count;
+ self.live_count += 1;
+
+ let bounds = bounds.map(|bounds| bounds * self.transformation());
+
+ if self.current == self.live.len() {
+ self.live.push(Live {
bounds,
- } => {
- let layer = &mut layers[current_layer];
-
- layer.images.push(Image::Vector {
- handle: handle.clone(),
- color: *color,
- bounds: *bounds * transformation,
- });
- }
- Primitive::Group { primitives } => {
- // TODO: Inspect a bit and regroup (?)
- for primitive in primitives {
- Self::process_primitive(
- layers,
- transformation,
- primitive,
- current_layer,
- );
- }
- }
- Primitive::Clip { bounds, content } => {
- let layer = &mut layers[current_layer];
- let translated_bounds = *bounds * transformation;
-
- // Only draw visible content
- if let Some(clip_bounds) =
- layer.bounds.intersection(&translated_bounds)
- {
- let clip_layer = Layer::new(clip_bounds);
- layers.push(clip_layer);
-
- Self::process_primitive(
- layers,
- transformation,
- content,
- layers.len() - 1,
- );
- }
- }
- Primitive::Transform {
- transformation: new_transformation,
- content,
- } => {
- Self::process_primitive(
- layers,
- transformation * *new_transformation,
- content,
- current_layer,
- );
- }
- Primitive::Cache { content } => {
- Self::process_primitive(
- layers,
- transformation,
- content,
- current_layer,
- );
+ ..Live::default()
+ });
+ } else {
+ self.live[self.current].bounds = bounds;
+ }
+ }
+
+ pub fn pop_clip(&mut self) {
+ self.current = self.previous.pop().unwrap();
+ }
+
+ pub fn push_transformation(&mut self, transformation: Transformation) {
+ self.transformations
+ .push(self.transformation() * transformation);
+ }
+
+ pub fn pop_transformation(&mut self) {
+ let _ = self.transformations.pop();
+ }
+
+ fn transformation(&self) -> Transformation {
+ self.transformations.last().copied().unwrap()
+ }
+
+ pub fn iter_mut(&mut self) -> impl Iterator<Item = LayerMut<'_>> {
+ let mut live = self.live.iter_mut();
+ let mut cached = self.cached.iter_mut();
+
+ self.order.iter().map(move |kind| match kind {
+ Kind::Live => LayerMut::Live(live.next().unwrap()),
+ Kind::Cache => {
+ LayerMut::Cached(cached.next().unwrap().borrow_mut())
}
- Primitive::Custom(custom) => match custom {
- primitive::Custom::Mesh(mesh) => match mesh {
- graphics::Mesh::Solid { buffers, size } => {
- let layer = &mut layers[current_layer];
-
- let bounds =
- Rectangle::with_size(*size) * transformation;
-
- // Only draw visible content
- if let Some(clip_bounds) =
- layer.bounds.intersection(&bounds)
- {
- layer.meshes.push(Mesh::Solid {
- transformation,
- buffers,
- clip_bounds,
- });
- }
- }
- graphics::Mesh::Gradient { buffers, size } => {
- let layer = &mut layers[current_layer];
-
- let bounds =
- Rectangle::with_size(*size) * transformation;
-
- // Only draw visible content
- if let Some(clip_bounds) =
- layer.bounds.intersection(&bounds)
- {
- layer.meshes.push(Mesh::Gradient {
- transformation,
- buffers,
- clip_bounds,
- });
- }
- }
- },
- primitive::Custom::Pipeline(pipeline) => {
- let layer = &mut layers[current_layer];
- let bounds = pipeline.bounds * transformation;
-
- if let Some(clip_bounds) =
- layer.bounds.intersection(&bounds)
- {
- layer.pipelines.push(Pipeline {
- bounds,
- viewport: clip_bounds,
- primitive: pipeline.primitive.clone(),
- });
- }
- }
- },
+ })
+ }
+
+ pub fn iter(&self) -> impl Iterator<Item = Layer<'_>> {
+ let mut live = self.live.iter();
+ let mut cached = self.cached.iter();
+
+ self.order.iter().map(move |kind| match kind {
+ Kind::Live => Layer::Live(live.next().unwrap()),
+ Kind::Cache => Layer::Cached(cached.next().unwrap().borrow()),
+ })
+ }
+
+ pub fn clear(&mut self) {
+ for live in &mut self.live[..self.live_count] {
+ live.bounds = None;
+ live.transformation = Transformation::IDENTITY;
+
+ live.quads.clear();
+ live.meshes.clear();
+ live.text.clear();
+ live.images.clear();
}
+
+ self.current = 0;
+ self.live_count = 1;
+
+ self.order.clear();
+ self.order.push(Kind::Live);
+
+ self.cached.clear();
+ self.previous.clear();
+ }
+}
+
+impl Default for Stack {
+ fn default() -> Self {
+ Self::new()
}
}
+
+#[derive(Default)]
+pub struct Live {
+ pub bounds: Option<Rectangle>,
+ pub transformation: Transformation,
+ pub quads: quad::Batch,
+ pub meshes: triangle::Batch,
+ pub text: text::Batch,
+ pub images: image::Batch,
+}
+
+impl Live {
+ pub fn into_cached(self) -> Cached {
+ Cached {
+ bounds: self.bounds,
+ transformation: self.transformation,
+ last_transformation: None,
+ quads: quad::Cache::Staged(self.quads),
+ meshes: triangle::Cache::Staged(self.meshes),
+ text: text::Cache::Staged(self.text),
+ images: self.images,
+ }
+ }
+}
+
+#[derive(Default)]
+pub struct Cached {
+ pub bounds: Option<Rectangle>,
+ pub transformation: Transformation,
+ pub last_transformation: Option<Transformation>,
+ pub quads: quad::Cache,
+ pub meshes: triangle::Cache,
+ pub text: text::Cache,
+ pub images: image::Batch,
+}
+
+impl Cached {
+ pub fn update(&mut self, live: Live) {
+ self.bounds = live.bounds;
+ self.transformation = live.transformation;
+
+ self.quads.update(live.quads);
+ self.meshes.update(live.meshes);
+ self.text.update(live.text);
+ self.images = live.images;
+ }
+}
+
+enum Kind {
+ Live,
+ Cache,
+}
diff --git a/wgpu/src/layer/image.rs b/wgpu/src/layer/image.rs
deleted file mode 100644
index facbe192..00000000
--- a/wgpu/src/layer/image.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use crate::core::image;
-use crate::core::svg;
-use crate::core::{Color, Rectangle};
-
-/// A raster or vector image.
-#[derive(Debug, Clone)]
-pub enum Image {
- /// A raster image.
- Raster {
- /// The handle of a raster image.
- handle: image::Handle,
-
- /// The filter method of a raster image.
- filter_method: image::FilterMethod,
-
- /// The bounds of the image.
- bounds: Rectangle,
- },
- /// A vector image.
- Vector {
- /// The handle of a vector image.
- handle: svg::Handle,
-
- /// The [`Color`] filter
- color: Option<Color>,
-
- /// The bounds of the image.
- bounds: Rectangle,
- },
-}
diff --git a/wgpu/src/layer/mesh.rs b/wgpu/src/layer/mesh.rs
deleted file mode 100644
index 5ed7c654..00000000
--- a/wgpu/src/layer/mesh.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-//! A collection of triangle primitives.
-use crate::core::{Rectangle, Transformation};
-use crate::graphics::mesh;
-
-/// A mesh of triangles.
-#[derive(Debug, Clone, Copy)]
-pub enum Mesh<'a> {
- /// A mesh of triangles with a solid color.
- Solid {
- /// The [`Transformation`] for the vertices of the [`Mesh`].
- transformation: Transformation,
-
- /// The vertex and index buffers of the [`Mesh`].
- buffers: &'a mesh::Indexed<mesh::SolidVertex2D>,
-
- /// The clipping bounds of the [`Mesh`].
- clip_bounds: Rectangle<f32>,
- },
- /// A mesh of triangles with a gradient color.
- Gradient {
- /// The [`Transformation`] for the vertices of the [`Mesh`].
- transformation: Transformation,
-
- /// The vertex and index buffers of the [`Mesh`].
- buffers: &'a mesh::Indexed<mesh::GradientVertex2D>,
-
- /// The clipping bounds of the [`Mesh`].
- clip_bounds: Rectangle<f32>,
- },
-}
-
-impl Mesh<'_> {
- /// Returns the origin of the [`Mesh`].
- pub fn transformation(&self) -> Transformation {
- match self {
- Self::Solid { transformation, .. }
- | Self::Gradient { transformation, .. } => *transformation,
- }
- }
-
- /// Returns the indices of the [`Mesh`].
- pub fn indices(&self) -> &[u32] {
- match self {
- Self::Solid { buffers, .. } => &buffers.indices,
- Self::Gradient { buffers, .. } => &buffers.indices,
- }
- }
-
- /// Returns the clip bounds of the [`Mesh`].
- pub fn clip_bounds(&self) -> Rectangle<f32> {
- match self {
- Self::Solid { clip_bounds, .. }
- | Self::Gradient { clip_bounds, .. } => *clip_bounds,
- }
- }
-}
-
-/// The result of counting the attributes of a set of meshes.
-#[derive(Debug, Clone, Copy, Default)]
-pub struct AttributeCount {
- /// The total amount of solid vertices.
- pub solid_vertices: usize,
-
- /// The total amount of solid meshes.
- pub solids: usize,
-
- /// The total amount of gradient vertices.
- pub gradient_vertices: usize,
-
- /// The total amount of gradient meshes.
- pub gradients: usize,
-
- /// The total amount of indices.
- pub indices: usize,
-}
-
-/// Returns the number of total vertices & total indices of all [`Mesh`]es.
-pub fn attribute_count_of<'a>(meshes: &'a [Mesh<'a>]) -> AttributeCount {
- meshes
- .iter()
- .fold(AttributeCount::default(), |mut count, mesh| {
- match mesh {
- Mesh::Solid { buffers, .. } => {
- count.solids += 1;
- count.solid_vertices += buffers.vertices.len();
- count.indices += buffers.indices.len();
- }
- Mesh::Gradient { buffers, .. } => {
- count.gradients += 1;
- count.gradient_vertices += buffers.vertices.len();
- count.indices += buffers.indices.len();
- }
- }
-
- count
- })
-}
diff --git a/wgpu/src/layer/pipeline.rs b/wgpu/src/layer/pipeline.rs
deleted file mode 100644
index 6dfe6750..00000000
--- a/wgpu/src/layer/pipeline.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-use crate::core::Rectangle;
-use crate::primitive::pipeline::Primitive;
-
-use std::sync::Arc;
-
-#[derive(Clone, Debug)]
-/// A custom primitive which can be used to render primitives associated with a custom pipeline.
-pub struct Pipeline {
- /// The bounds of the [`Pipeline`].
- pub bounds: Rectangle,
-
- /// The viewport of the [`Pipeline`].
- pub viewport: Rectangle,
-
- /// The [`Primitive`] to render.
- pub primitive: Arc<dyn Primitive>,
-}
diff --git a/wgpu/src/layer/text.rs b/wgpu/src/layer/text.rs
deleted file mode 100644
index b3a00130..00000000
--- a/wgpu/src/layer/text.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use crate::core::alignment;
-use crate::core::text;
-use crate::core::{Color, Font, Pixels, Point, Rectangle, Transformation};
-use crate::graphics;
-use crate::graphics::text::editor;
-use crate::graphics::text::paragraph;
-
-/// A text primitive.
-#[derive(Debug, Clone)]
-pub enum Text<'a> {
- /// A paragraph.
- #[allow(missing_docs)]
- Paragraph {
- paragraph: paragraph::Weak,
- position: Point,
- color: Color,
- clip_bounds: Rectangle,
- transformation: Transformation,
- },
- /// An editor.
- #[allow(missing_docs)]
- Editor {
- editor: editor::Weak,
- position: Point,
- color: Color,
- clip_bounds: Rectangle,
- transformation: Transformation,
- },
- /// Some cached text.
- Cached(Cached<'a>),
- /// Some raw text.
- #[allow(missing_docs)]
- Raw {
- raw: graphics::text::Raw,
- transformation: Transformation,
- },
-}
-
-#[derive(Debug, Clone)]
-pub struct Cached<'a> {
- /// The content of the [`Text`].
- pub content: &'a str,
-
- /// The layout bounds of the [`Text`].
- pub bounds: Rectangle,
-
- /// The color of the [`Text`], in __linear RGB_.
- pub color: Color,
-
- /// The size of the [`Text`] in logical pixels.
- pub size: Pixels,
-
- /// The line height of the [`Text`].
- pub line_height: text::LineHeight,
-
- /// The font of the [`Text`].
- pub font: Font,
-
- /// The horizontal alignment of the [`Text`].
- pub horizontal_alignment: alignment::Horizontal,
-
- /// The vertical alignment of the [`Text`].
- pub vertical_alignment: alignment::Vertical,
-
- /// The shaping strategy of the text.
- pub shaping: text::Shaping,
-
- /// The clip bounds of the text.
- pub clip_bounds: Rectangle,
-}