Skip to content

Commit

Permalink
Add Primitive::Text.
Browse files Browse the repository at this point in the history
Empirically, it has turned out that making text rendering consist of
writing blocks into a `Space` is a bad idea. It is slow, awkward to set
up since it requires mutating the `Universe`, and also probably not very
user-editable. Therefore, I'm adding a text rendering primitive. It will
initially support only builtin fonts, but I expect to add fonts as
universe members in the future, and probably migrate away from using
`embedded_graphics` for the rendering.

This is a minimal proof of concept.  Further work is needed make this
usable for all text applications; I expect to add the following:

* Explicitly chosen resolution, so that compositions with other blocks
  know what they're getting in to, and so that thickness of the text is
  well defined.
* Replace the `anchor_point` concept with a bounding box (which the text
  may be permitted to spill out of).
  • Loading branch information
kpreid committed Nov 18, 2023
1 parent 79968b2 commit 95a1578
Show file tree
Hide file tree
Showing 6 changed files with 606 additions and 7 deletions.
31 changes: 28 additions & 3 deletions all-is-cubes/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use core::fmt;

use crate::listen::{self, Listen, Listener};
use crate::math::{
Cube, FreeCoordinate, GridAab, GridCoordinate, GridPoint, GridRotation, Rgb, Rgba, VectorOps,
Vol,
Cube, FreeCoordinate, GridAab, GridCoordinate, GridPoint, GridRotation, GridVector, Rgb, Rgba,
VectorOps, Vol,
};
use crate::raycast::Ray;
use crate::space::{SetCubeError, Space, SpaceChange};
Expand All @@ -39,6 +39,8 @@ pub use modifier::*;
mod resolution;
pub use resolution::*;

pub mod text;

#[cfg(test)]
mod tests;

Expand Down Expand Up @@ -124,6 +126,21 @@ pub enum Primitive {
/// data model — so that if it is, say, serialized and loaded in a future version,
/// it is still recognized as [`AIR`]. Additionally, it's cheaper to compare this way.
Air,

/// A piece of text rendered as voxels.
///
/// To combine the text with other shapes, use [`Modifier::Composite`].
Text {
/// The text to draw, and the font and text-layout-dependent positioning.
text: text::Text,

/// Translation, in whole cubes, of the region of the text to draw.
///
/// For text within a single block, this should be zero.
/// For multi-block text, this should be equal to the difference between
/// the adjacent blocks' positions.
offset: GridVector,
},
}

/// Data of [`Primitive::Atom`]. The definition of a single [block](Block) that has uniform
Expand Down Expand Up @@ -535,6 +552,8 @@ impl Block {
voxels: Evoxels::Many(resolution, voxels),
}
}

Primitive::Text { ref text, offset } => text.evaluate(offset, depth, filter)?,
};

for (index, modifier) in self.modifiers().iter().enumerate() {
Expand All @@ -552,7 +571,7 @@ impl Block {
match *self.primitive() {
Primitive::Atom(Atom { color, .. }) => color,
Primitive::Air => AIR_EVALUATED.color,
Primitive::Indirect(_) | Primitive::Recur { .. } => {
Primitive::Indirect(_) | Primitive::Recur { .. } | Primitive::Text { .. } => {
panic!("Block::color not defined for non-atom blocks")
}
}
Expand Down Expand Up @@ -788,6 +807,11 @@ impl fmt::Debug for Primitive {
.field("resolution", resolution)
.finish(),
Self::Air => write!(f, "Air"),
Self::Text { text, offset } => f
.debug_struct("Text")
.field("offset", offset)
.field("text", text)
.finish(),
}
}
}
Expand Down Expand Up @@ -828,6 +852,7 @@ impl VisitRefs for Primitive {
visitor.visit(space);
attributes.visit_refs(visitor);
}
Primitive::Text { text, offset: _ } => text.visit_refs(visitor),
}
}
}
Expand Down

0 comments on commit 95a1578

Please sign in to comment.