Skip to content

Commit

Permalink
refactor: add default_font, change font api
Browse files Browse the repository at this point in the history
  • Loading branch information
simbleau committed Jul 20, 2024
1 parent 864cbc9 commit 4b4c76d
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 81 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,17 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe

## Unreleased

### Added

- There is now a `default_font` feature that uses the same `FiraMono-subset.ttf` font used in the bevy/default_font feature.

### Changed

- The font API has changed significantly. Please visit `examples/text` for further usage. This is to prepare for additional text features such as linebreak behavior, bounded text, and text justification.
- `VelloText` has been renamed to `VelloTextSection`.
- `VelloText.content` has been renamed to `VelloText.value`.
- There is now a `VelloTextStyle` struct and it is a required field of `VelloText`.
- `VelloFont` has been removed from `VelloTextBundle` and moved into `VelloTextStyle`.
- The field `VelloAssetBundle.vector` was renamed to `VelloAssetBundle.asset`.
- Renamed `VelloAssetAlignment` to `VelloAssetAnchor`. Fields were renamed `alignment` were renamed to `asset_anchor`.
- Renamed `VelloTextAlignment` to `VelloTextAnchor`. Fields were renamed `alignment` were renamed to `text_anchor`.
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ once_cell = "1.19.0"
wasm-bindgen-test = "0.3.42"

[features]
default = []
default = ["default_font"]
svg = []
lottie = []
experimental-dotLottie = ["lottie"]
default_font = []
2 changes: 1 addition & 1 deletion examples/text/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bevy_vello = { path = "../../" }
bevy_vello = { path = "../../", features = ["default_font"] }
bevy = { workspace = true }
62 changes: 28 additions & 34 deletions examples/text/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ fn main() {
(setup_camera, setup_screenspace_text, setup_worldspace_text),
);
embedded_asset!(app, "assets/Rubik-Medium.ttf");
embedded_asset!(app, "assets/Rubik-Medium.ttf");
app.run();
}

Expand All @@ -26,39 +25,41 @@ fn setup_camera(mut commands: Commands) {

fn setup_worldspace_text(mut commands: Commands, asset_server: ResMut<AssetServer>) {
commands.spawn(VelloTextBundle {
font: asset_server.load("embedded://text/assets/Rubik-Medium.ttf"),
text: VelloText {
content: "This text is centered\non x and y axes".to_string(),
size: 50.0,
brush: None,
text: VelloTextSection {
value: "Default font\nand multi-line support.".to_string(),
..default()
},
text_anchor: VelloTextAnchor::Center,
transform: Transform::from_xyz(100.0, 100.0, 0.0),
transform: Transform::from_xyz(0.0, 100.0, 0.0),
debug_visualizations: DebugVisualizations::Visible,
..default()
});

commands.spawn(VelloTextBundle {
font: asset_server.load("embedded://text/assets/Rubik-Medium.ttf"),
text: VelloText {
content: "WXYZ".to_string(),
size: 100.0,
brush: None,
text: VelloTextSection {
value: "Rubik-Medium Font".to_string(),
style: VelloTextStyle {
font: asset_server.load("embedded://text/assets/Rubik-Medium.ttf"),
font_size: 100.0,
..default()
},
},
transform: Transform::from_xyz(-100.0, -100.0, 0.0),
text_anchor: VelloTextAnchor::Center,
transform: Transform::from_xyz(0.0, -100.0, 0.0),
debug_visualizations: DebugVisualizations::Visible,
..default()
});
}

fn setup_screenspace_text(mut commands: Commands, asset_server: ResMut<AssetServer>) {
fn setup_screenspace_text(mut commands: Commands) {
// Vello text
commands.spawn(VelloTextBundle {
font: asset_server.load("embedded://text/assets/Rubik-Medium.ttf"),
text: VelloText {
content: "Text rendered by Vello!".to_string(),
size: 15.0,
brush: Some(peniko::Brush::Solid(peniko::Color::RED)),
text: VelloTextSection {
value: "World-space text rendered by Vello!".to_string(),
style: VelloTextStyle {
brush: peniko::Brush::Solid(peniko::Color::RED),
..default()
},
},
text_anchor: bevy_vello::text::VelloTextAnchor::TopLeft,
transform: Transform::from_xyz(100.0, 85.0, 0.0),
Expand All @@ -67,22 +68,15 @@ fn setup_screenspace_text(mut commands: Commands, asset_server: ResMut<AssetServ
..default()
});

// Bevy text (probably the better API)
// Bevy text
commands.spawn(
TextBundle::from_section(
"Text rendered by Bevy!",
TextStyle {
font: asset_server.load("embedded://text/assets/Rubik-Medium.ttf"),
font_size: 15.0,
TextBundle::from_section("Screen-space text rendered by Bevy!", TextStyle::default())
.with_style(Style {
position_type: PositionType::Absolute,
top: Val::Px(100.0),
left: Val::Px(100.0),
..default()
},
)
.with_style(Style {
position_type: PositionType::Absolute,
top: Val::Px(100.0),
left: Val::Px(100.0),
..default()
})
.with_text_justify(JustifyText::Left),
})
.with_text_justify(JustifyText::Left),
);
}
12 changes: 6 additions & 6 deletions src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Logic for rendering debug visualizations
use crate::{
text::VelloTextAnchor, CoordinateSpace, VelloAsset, VelloAssetAnchor, VelloFont, VelloText,
text::VelloTextAnchor, CoordinateSpace, VelloAsset, VelloAssetAnchor, VelloFont,
VelloTextSection,
};
use bevy::{color::palettes::css, math::Vec3Swizzles, prelude::*};

Expand Down Expand Up @@ -86,8 +87,7 @@ fn render_asset_debug(
fn render_text_debug(
query_world: Query<
(
&Handle<VelloFont>,
&VelloText,
&VelloTextSection,
&VelloTextAnchor,
&GlobalTransform,
&CoordinateSpace,
Expand All @@ -104,11 +104,11 @@ fn render_text_debug(
};

// Show world-space vectors
for (font, text, text_anchor, gtransform, space, _) in query_world
for (text, text_anchor, gtransform, space, _) in query_world
.iter()
.filter(|(_, _, _, _, _, d)| **d == DebugVisualizations::Visible)
.filter(|(_, _, _, _, d)| **d == DebugVisualizations::Visible)
{
if let Some(font) = fonts.get(font) {
if let Some(font) = fonts.get(text.style.font.id()) {
let rect = text.bb_in_world_space(font, gtransform);
let mut origin = gtransform.translation().xy();
match space {
Expand Down
6 changes: 2 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub mod prelude {
debug::DebugVisualizations,
integrations::{VectorFile, VelloAsset, VelloAssetAnchor},
render::VelloCanvasMaterial,
text::{VelloFont, VelloText, VelloTextAnchor},
text::{VelloFont, VelloTextAnchor, VelloTextSection, VelloTextStyle},
CoordinateSpace, VelloAssetBundle, VelloScene, VelloSceneBundle, VelloTextBundle,
};

Expand Down Expand Up @@ -91,10 +91,8 @@ pub struct VelloSceneBundle {

#[derive(Bundle, Default)]
pub struct VelloTextBundle {
/// Font to render
pub font: Handle<VelloFont>,
/// Text to render
pub text: VelloText,
pub text: VelloTextSection,
/// How the text is positioned relative to its [`Transform`].
pub text_anchor: VelloTextAnchor,
/// The coordinate space in which this text should be rendered.
Expand Down
9 changes: 8 additions & 1 deletion src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
debug::DebugVisualizationsPlugin, render::VelloRenderPlugin, text::VelloFontLoader, VelloAsset,
VelloFont,
};
use bevy::prelude::*;
use bevy::{asset::load_internal_binary_asset, prelude::*};

pub struct VelloPlugin;

Expand All @@ -19,5 +19,12 @@ impl Plugin for VelloPlugin {
app.add_plugins(crate::integrations::lottie::LottieIntegrationPlugin);
#[cfg(feature = "experimental-dotLottie")]
app.add_plugins(crate::integrations::dot_lottie::DotLottieIntegrationPlugin);
#[cfg(feature = "default_font")]
load_internal_binary_asset!(
app,
Handle::default(),
"text/FiraMono-subset.ttf",
|bytes: &[u8], _path: String| { VelloFont::new(bytes.to_vec()) }
);
}
}
13 changes: 5 additions & 8 deletions src/render/extract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
text::VelloTextAnchor, CoordinateSpace, VelloAsset, VelloAssetAnchor, VelloFont, VelloScene,
VelloText,
text::VelloTextAnchor, CoordinateSpace, VelloAsset, VelloAssetAnchor, VelloScene,
VelloTextSection,
};
use bevy::{
prelude::*,
Expand Down Expand Up @@ -166,17 +166,15 @@ pub fn scene_instances(

#[derive(Component, Clone)]
pub struct ExtractedRenderText {
pub font: Handle<VelloFont>,
pub text: VelloText,
pub text: VelloTextSection,
pub text_anchor: VelloTextAnchor,
pub transform: GlobalTransform,
pub render_mode: CoordinateSpace,
}

impl ExtractComponent for ExtractedRenderText {
type QueryData = (
&'static Handle<VelloFont>,
&'static VelloText,
&'static VelloTextSection,
&'static VelloTextAnchor,
&'static GlobalTransform,
&'static CoordinateSpace,
Expand All @@ -187,13 +185,12 @@ impl ExtractComponent for ExtractedRenderText {
type Out = Self;

fn extract_component(
(vello_font_handle, text, text_anchor, transform, render_mode): bevy::ecs::query::QueryItem<
(text, text_anchor, transform, render_mode): bevy::ecs::query::QueryItem<
'_,
Self::QueryData,
>,
) -> Option<Self> {
Some(Self {
font: vello_font_handle.clone(),
text: text.clone(),
text_anchor: *text_anchor,
transform: *transform,
Expand Down
7 changes: 2 additions & 5 deletions src/render/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,9 @@ pub fn render_scene(
scene_buffer.append(scene, Some(*affine));
}
RenderItem::Text(ExtractedRenderText {
font,
text,
text_anchor,
..
text, text_anchor, ..
}) => {
if let Some(font) = font_render_assets.get_mut(font) {
if let Some(font) = font_render_assets.get_mut(text.style.font.id()) {
font.render(&mut scene_buffer, *affine, text, *text_anchor);
}
}
Expand Down
Binary file added src/text/FiraMono-subset.ttf
Binary file not shown.
22 changes: 11 additions & 11 deletions src/text/font.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{vello_text::VelloText, VelloTextAnchor};
use super::{vello_text::VelloTextSection, VelloTextAnchor};
use bevy::{prelude::*, reflect::TypePath, render::render_asset::RenderAsset};
use std::sync::Arc;
use vello::{
Expand All @@ -7,13 +7,13 @@ use vello::{
Glyph,
},
kurbo::Affine,
peniko::{self, Blob, Brush, Color, Font},
peniko::{self, Blob, Font},
Scene,
};

const VARIATIONS: &[(&str, f32)] = &[];

#[derive(Asset, TypePath, Clone)]
#[derive(Asset, TypePath, Debug, Clone)]
pub struct VelloFont {
pub font: peniko::Font,
}
Expand All @@ -38,9 +38,9 @@ impl VelloFont {
}
}

pub fn sizeof(&self, text: &VelloText) -> Vec2 {
pub fn sizeof(&self, text: &VelloTextSection) -> Vec2 {
let font = FontRef::new(self.font.data.data()).expect("Vello font creation error");
let font_size = vello::skrifa::instance::Size::new(text.size);
let font_size = vello::skrifa::instance::Size::new(text.style.font_size);
let charmap = font.charmap();
let axes = font.axes();
// TODO: What do Variations here do? Any font nerds know? I'm definitely not doing this
Expand All @@ -54,7 +54,7 @@ impl VelloFont {
let mut pen_x = 0.0;
let mut pen_y: f32 = 0.0;
let mut width: f32 = 0.0;
for ch in text.content.chars() {
for ch in text.value.chars() {
if ch == '\n' {
pen_y += line_height;
pen_x = 0.0;
Expand All @@ -74,12 +74,12 @@ impl VelloFont {
&self,
scene: &mut Scene,
mut transform: Affine,
text: &VelloText,
text: &VelloTextSection,
text_anchor: VelloTextAnchor,
) {
let font = FontRef::new(self.font.data.data()).expect("Vello font creation error");

let font_size = vello::skrifa::instance::Size::new(text.size);
let font_size = vello::skrifa::instance::Size::new(text.style.font_size);
let charmap = font.charmap();
let axes = font.axes();
let var_loc = axes.location(VARIATIONS);
Expand All @@ -91,7 +91,7 @@ impl VelloFont {
let mut pen_y = 0f32;
let mut width = 0f32;
let glyphs: Vec<Glyph> = text
.content
.value
.chars()
.filter_map(|ch| {
if ch == '\n' {
Expand Down Expand Up @@ -149,10 +149,10 @@ impl VelloFont {

scene
.draw_glyphs(&self.font)
.font_size(text.size)
.font_size(text.style.font_size)
.transform(transform)
.normalized_coords(var_loc.coords())
.brush(&text.brush.clone().unwrap_or(Brush::Solid(Color::WHITE)))
.brush(&text.style.brush.clone())
.draw(vello::peniko::Fill::EvenOdd, glyphs.into_iter());
}
}
2 changes: 1 addition & 1 deletion src/text/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ mod vello_text;

pub use font::VelloFont;
pub(crate) use font_loader::VelloFontLoader;
pub use vello_text::{VelloText, VelloTextAnchor};
pub use vello_text::{VelloTextAnchor, VelloTextSection, VelloTextStyle};
Loading

0 comments on commit 4b4c76d

Please sign in to comment.