Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add default_font, change font api #66

Merged
merged 3 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 = []
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ cargo run -p demo

|Cargo feature|Description|Default?|
|---|---|----|
|`svg`|Render `.svg` files with [`vello_svg`](https://github.com/linebender/vello_svg)|Yes|
|`lottie`|Render `.json` Lottie files with [`velato`](https://github.com/linebender/velato)|Yes|
|`default_font`|Include a default font, containing only ASCII characters, at the cost of a 20kB binary size increase|Yes|
|`svg`|Render `.svg` files with [`vello_svg`](https://github.com/linebender/vello_svg)|No|
|`lottie`|Render `.json` Lottie files with [`velato`](https://github.com/linebender/velato)|No|
|`experimental-dotLottie`|Render `.lottie` Lottie files. **Work in Progress**|No|

## Examples
Expand Down
2 changes: 1 addition & 1 deletion examples/run_wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ repository.workspace = true
publish = false

[dependencies]
cargo-run-wasm = "0.3.2"
cargo-run-wasm = "0.4.0"
2 changes: 1 addition & 1 deletion examples/run_wasm/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
/// ```

fn main() {
cargo_run_wasm::run_wasm_with_css("body { margin: 0px; }");
cargo_run_wasm::run_wasm_cli_with_css("body { margin: 0px; }");
}
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the license for this file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OFL 1.1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are using both this crate with default_font and bevy/default_font, does your binary include both?

I do see that the file is relatively small, so it's probably fine.

Copy link
Member Author

@simbleau simbleau Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We aren't currently using bevy/default_font, not until bevyengine/bevy#14406 is merged at least.

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
Loading