bevy_text 0.19.0-rc.2

Provides text functionality for Bevy Engine
Documentation
//! This crate provides the tools for positioning and rendering text in Bevy.
//!
//! # `Font`
//!
//! Fonts contain information for drawing glyphs, which are shapes that typically represent a single character,
//! but in some cases part of a "character" (grapheme clusters) or more than one character (ligatures).
//!
//! A font *face* is part of a font family,
//! and is distinguished by its style (e.g. italic), its weight (e.g. bold) and its stretch (e.g. condensed).
//!
//! In Bevy, [`Font`]s are loaded by the [`FontLoader`] as [assets](bevy_asset::AssetPlugin).
//!
//! # `TextPipeline`
//!
//! The [`TextPipeline`] resource does all of the heavy lifting for rendering text.
//!
//! UI `Text` is first measured by creating a [`TextMeasureInfo`] in [`TextPipeline::create_text_measure`],
//! which is called by the `measure_text_system` system of `bevy_ui`.
//!
//! Note that text measurement is only relevant in a UI context.
//!
//! With the actual text bounds defined, the `bevy_ui::widget::text::text_system` system (in a UI context)
//! or `bevy_sprite::text2d::update_text2d_layout` system (in a 2d world space context)
//! passes it into [`TextPipeline::update_text_layout_info`], which:
//!
//! 1. updates a [`Layout`](parley::Layout) from the [`TextSpan`]s, generating new [`FontAtlas`]es if necessary.
//! 2. iterates over each glyph in the [`Layout`](parley::Layout) to create a [`PositionedGlyph`],
//!    retrieving glyphs from the cache, or rasterizing to a [`FontAtlas`] if necessary.
//! 3. [`PositionedGlyph`]s are stored in a [`TextLayoutInfo`],
//!    which contains all the information that downstream systems need for rendering.

extern crate alloc;

mod bounds;
mod cursor;
mod editing;
mod error;
mod font;
mod font_atlas;
mod font_atlas_set;
mod font_loader;
mod glyph;
mod parley_context;
mod pipeline;
mod text;
mod text_access;
mod text_edit;

pub use bounds::*;
pub use cursor::*;
pub use editing::*;
pub use error::*;
pub use font::*;
pub use font_atlas::*;
pub use font_atlas_set::*;
pub use font_loader::*;
pub use glyph::*;
pub use parley_context::*;
pub use pipeline::*;
pub use text::*;
pub use text_access::*;
pub use text_edit::*;

/// The text prelude.
///
/// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude {
    #[doc(hidden)]
    pub use crate::{
        Font, FontHinting, FontSize, FontSmoothing, FontSource, FontStyle, FontWeight, FontWidth,
        Justify, LineBreak, Strikethrough, StrikethroughColor, TextColor, TextError, TextFont,
        TextLayout, TextSpan, Underline, UnderlineColor,
    };
}

use bevy_app::prelude::*;
use bevy_asset::AssetApp;
use bevy_ecs::prelude::*;

/// The raw data for the default font used by `bevy_text`
#[cfg(feature = "default_font")]
pub const DEFAULT_FONT_DATA: &[u8] = include_bytes!("FiraMono-subset.ttf");

/// Adds text rendering support to an app.
///
/// When the `bevy_text` feature is enabled with the `bevy` crate, this
/// plugin is included by default in the `DefaultPlugins`.
///
/// ## Clipboard support
///
/// [`EditableText`] supports copy, cut, and paste via [`bevy_clipboard::Clipboard`].
/// By default, clipboard operations use an in-process fallback buffer rather than the OS clipboard.
/// To enable OS clipboard integration, activate the `system_clipboard` feature on this crate:
///
/// ```toml
/// bevy_text = { version = "...", features = ["system_clipboard"] }
/// ```
///
/// When using the top-level `bevy` crate, `bevy/system_clipboard` enables this transitively.
#[derive(Default)]
pub struct TextPlugin;

/// System set in [`PostUpdate`] where all 2d text update systems are executed.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub struct Text2dUpdateSystems;

/// System set where [`EditableText::pending_edits`] are applied.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub struct EditableTextSystems;

impl Plugin for TextPlugin {
    fn build(&self, app: &mut App) {
        if !app.is_plugin_added::<bevy_clipboard::ClipboardPlugin>() {
            app.add_plugins(bevy_clipboard::ClipboardPlugin);
        }
        app.init_asset::<Font>()
            .init_asset_loader::<FontLoader>()
            .init_resource::<FontAtlasSet>()
            .init_resource::<TextPipeline>()
            .init_resource::<FontCx>()
            .init_resource::<LayoutCx>()
            .init_resource::<ScaleCx>()
            .init_resource::<TextIterScratch>()
            .init_resource::<RemSize>()
            .add_systems(
                PostUpdate,
                (
                    detect_text_needs_rerender,
                    load_font_assets_into_font_collection,
                )
                    .chain(),
            )
            .add_systems(Last, trim_source_cache)
            .add_systems(
                PostUpdate,
                apply_text_edits
                    .after(load_font_assets_into_font_collection)
                    .in_set(EditableTextSystems),
            );

        #[cfg(feature = "default_font")]
        {
            use bevy_asset::{AssetId, Assets};
            let mut assets = app.world_mut().resource_mut::<Assets<Font>>();
            let asset = Font::from_bytes(DEFAULT_FONT_DATA.to_vec(), "bevy default font");
            assets.insert(AssetId::default(), asset).unwrap();
        };
    }
}