Cleanup before release

This commit is contained in:
grovesNL 2024-09-16 23:25:27 -06:00 committed by Josh Groves
parent 2daf883cad
commit 692e23ca33
8 changed files with 96 additions and 84 deletions

View file

@ -1,7 +1,7 @@
use glyphon::{
Attrs, Buffer, Cache, Color, ContentType, CustomGlyph, RasterizationRequest, RasterizedCustomGlyph,
Family, FontSystem, Metrics, Resolution, Shaping, SwashCache, TextArea, TextAtlas, TextBounds,
TextRenderer, Viewport,
Attrs, Buffer, Cache, Color, ContentType, CustomGlyph, Family, FontSystem, Metrics,
RasterizeCustomGlyphRequest, RasterizedCustomGlyph, Resolution, Shaping, SwashCache, TextArea,
TextAtlas, TextBounds, TextRenderer, Viewport,
};
use std::sync::Arc;
use wgpu::{
@ -28,16 +28,13 @@ struct WindowState {
queue: wgpu::Queue,
surface: wgpu::Surface<'static>,
surface_config: SurfaceConfiguration,
font_system: FontSystem,
swash_cache: SwashCache,
viewport: glyphon::Viewport,
atlas: glyphon::TextAtlas,
text_renderer: glyphon::TextRenderer,
text_buffer: glyphon::Buffer,
rasterize_svg: Box<dyn Fn(RasterizationRequest) -> Option<RasterizedCustomGlyph>>,
rasterize_svg: Box<dyn Fn(RasterizeCustomGlyphRequest) -> Option<RasterizedCustomGlyph>>,
// Make sure that the winit window is last in the struct so that
// it is dropped after the wgpu surface is dropped, otherwise the
// program may crash when closed. This is probably a bug in wgpu.
@ -106,7 +103,8 @@ impl WindowState {
let svg_0 = resvg::usvg::Tree::from_data(LION_SVG, &Default::default()).unwrap();
let svg_1 = resvg::usvg::Tree::from_data(EAGLE_SVG, &Default::default()).unwrap();
let rasterize_svg = move |input: RasterizationRequest| -> Option<RasterizedCustomGlyph> {
let rasterize_svg =
move |input: RasterizeCustomGlyphRequest| -> Option<RasterizedCustomGlyph> {
// Select the svg data based on the custom glyph ID.
let (svg, content_type) = match input.id {
0 => (&svg_0, ContentType::Mask),

View file

@ -244,6 +244,7 @@ impl winit::application::ApplicationHandler for Application {
bottom: top.floor() as i32 + physical_size.height,
},
default_color: FONT_COLOR,
custom_glyphs: &[],
};
let total_lines = b

View file

@ -1,5 +1,11 @@
use crate::{GlyphToRender, Params};
use std::{
borrow::Cow,
mem,
num::NonZeroU64,
ops::Deref,
sync::{Arc, RwLock},
};
use wgpu::{
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutEntry,
BindingResource, BindingType, BlendState, Buffer, BufferBindingType, ColorTargetState,
@ -10,12 +16,8 @@ use wgpu::{
TextureFormat, TextureSampleType, TextureView, TextureViewDimension, VertexFormat, VertexState,
};
use std::borrow::Cow;
use std::mem;
use std::num::NonZeroU64;
use std::ops::Deref;
use std::sync::{Arc, RwLock};
/// A cache to share common resources (e.g., pipelines, layouts, shaders) between multiple text
/// renderers.
#[derive(Debug, Clone)]
pub struct Cache(Arc<Inner>);
@ -38,6 +40,7 @@ struct Inner {
}
impl Cache {
/// Creates a new `Cache` with the given `device`.
pub fn new(device: &Device) -> Self {
let sampler = device.create_sampler(&SamplerDescriptor {
label: Some("glyphon sampler"),

View file

@ -19,7 +19,7 @@ pub struct CustomGlyph {
/// The color of this glyph (only relevant if the glyph is rendered with the
/// type [`ContentType::Mask`])
///
/// Set to `None` to use [`TextArea::default_color`].
/// Set to `None` to use [`crate::TextArea::default_color`].
pub color: Option<Color>,
/// If `true`, then this glyph will be snapped to the nearest whole physical
/// pixel and the resulting `SubpixelBin`'s in `RasterizationRequest` will always
@ -31,7 +31,7 @@ pub struct CustomGlyph {
/// A request to rasterize a custom glyph
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RasterizationRequest {
pub struct RasterizeCustomGlyphRequest {
/// The unique identifier of the glyph
pub id: CustomGlyphId,
/// The width of the glyph in physical pixels
@ -63,7 +63,11 @@ pub struct RasterizedCustomGlyph {
}
impl RasterizedCustomGlyph {
pub(crate) fn validate(&self, input: &RasterizationRequest, expected_type: Option<ContentType>) {
pub(crate) fn validate(
&self,
input: &RasterizeCustomGlyphRequest,
expected_type: Option<ContentType>,
) {
if let Some(expected_type) = expected_type {
assert_eq!(self.content_type, expected_type, "Custom glyph rasterizer must always produce the same content type for a given input. Expected {:?}, got {:?}. Input: {:?}", expected_type, self.content_type, input);
}

View file

@ -13,7 +13,7 @@ mod viewport;
pub use cache::Cache;
pub use custom_glyph::{
ContentType, CustomGlyph, CustomGlyphId, RasterizationRequest, RasterizedCustomGlyph,
ContentType, CustomGlyph, CustomGlyphId, RasterizeCustomGlyphRequest, RasterizedCustomGlyph,
};
pub use error::{PrepareError, RenderError};
pub use text_atlas::{ColorMode, TextAtlas};
@ -117,9 +117,8 @@ pub struct TextArea<'a> {
/// The visible bounds of the text area. This is used to clip the text and doesn't have to
/// match the `left` and `top` values.
pub bounds: TextBounds,
// The default color of the text area.
/// The default color of the text area.
pub default_color: Color,
/// Additional custom glyphs to render
/// Additional custom glyphs to render.
pub custom_glyphs: &'a [CustomGlyph],
}

View file

@ -1,6 +1,6 @@
use crate::{
text_render::GlyphonCacheKey, Cache, ContentType, RasterizationRequest, RasterizedCustomGlyph,
FontSystem, GlyphDetails, GpuCacheStatus, SwashCache,
text_render::GlyphonCacheKey, Cache, ContentType, RasterizeCustomGlyphRequest, FontSystem,
GlyphDetails, GpuCacheStatus, RasterizedCustomGlyph, SwashCache,
};
use etagere::{size2, Allocation, BucketedAtlasAllocator};
use lru::LruCache;
@ -124,7 +124,9 @@ impl InnerAtlas {
font_system: &mut FontSystem,
cache: &mut SwashCache,
scale_factor: f32,
mut rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
mut rasterize_custom_glyph: impl FnMut(
RasterizeCustomGlyphRequest,
) -> Option<RasterizedCustomGlyph>,
) -> bool {
if self.size >= self.max_texture_dimension_2d {
return false;
@ -169,7 +171,7 @@ impl InnerAtlas {
(image.data, width, height)
}
GlyphonCacheKey::Custom(cache_key) => {
let input = RasterizationRequest {
let input = RasterizeCustomGlyphRequest {
id: cache_key.glyph_id,
width: cache_key.width,
height: cache_key.height,
@ -264,7 +266,7 @@ impl Kind {
}
}
/// The color mode of an [`Atlas`].
/// The color mode of a [`TextAtlas`].
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColorMode {
/// Accurate color management.
@ -352,7 +354,9 @@ impl TextAtlas {
cache: &mut SwashCache,
content_type: ContentType,
scale_factor: f32,
rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
rasterize_custom_glyph: impl FnMut(
RasterizeCustomGlyphRequest,
) -> Option<RasterizedCustomGlyph>,
) -> bool {
let did_grow = match content_type {
ContentType::Mask => self.mask_atlas.grow(

View file

@ -1,7 +1,7 @@
use crate::{
custom_glyph::CustomGlyphCacheKey, ColorMode, ContentType, RasterizationRequest, RasterizedCustomGlyph,
FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, PrepareError, RenderError, SwashCache,
SwashContent, TextArea, TextAtlas, Viewport,
custom_glyph::CustomGlyphCacheKey, ColorMode, ContentType, FontSystem, GlyphDetails,
GlyphToRender, GpuCacheStatus, PrepareError, RasterizeCustomGlyphRequest,
RasterizedCustomGlyph, RenderError, SwashCache, SwashContent, TextArea, TextAtlas, Viewport,
};
use cosmic_text::{Color, SubpixelBin};
use std::{slice, sync::Arc};
@ -104,7 +104,7 @@ impl TextRenderer {
viewport: &Viewport,
text_areas: impl IntoIterator<Item = TextArea<'a>>,
cache: &mut SwashCache,
rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
rasterize_custom_glyph: impl FnMut(RasterizeCustomGlyphRequest) -> Option<RasterizedCustomGlyph>,
) -> Result<(), PrepareError> {
self.prepare_with_depth_and_custom(
device,
@ -130,7 +130,9 @@ impl TextRenderer {
text_areas: impl IntoIterator<Item = TextArea<'a>>,
cache: &mut SwashCache,
mut metadata_to_depth: impl FnMut(usize) -> f32,
mut rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
mut rasterize_custom_glyph: impl FnMut(
RasterizeCustomGlyphRequest,
) -> Option<RasterizedCustomGlyph>,
) -> Result<(), PrepareError> {
self.glyph_vertices.clear();
@ -193,7 +195,7 @@ impl TextRenderer {
return None;
}
let input = RasterizationRequest {
let input = RasterizeCustomGlyphRequest {
id: glyph.id,
width,
height,
@ -202,9 +204,7 @@ impl TextRenderer {
scale: text_area.scale,
};
let Some(output) = (rasterize_custom_glyph)(input) else {
return None;
};
let output = (rasterize_custom_glyph)(input)?;
output.validate(&input, None);
@ -268,11 +268,8 @@ impl TextRenderer {
font_system,
_rasterize_custom_glyph|
-> Option<GetGlyphImageResult> {
let Some(image) =
cache.get_image_uncached(font_system, physical_glyph.cache_key)
else {
return None;
};
let image =
cache.get_image_uncached(font_system, physical_glyph.cache_key)?;
let content_type = match image.content {
SwashContent::Color => ContentType::Color,
@ -429,7 +426,7 @@ fn prepare_glyph<R>(
mut rasterize_custom_glyph: R,
) -> Result<Option<GlyphToRender>, PrepareError>
where
R: FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
R: FnMut(RasterizeCustomGlyphRequest) -> Option<RasterizedCustomGlyph>,
{
if atlas.mask_atlas.glyph_cache.contains(&cache_key) {
atlas.mask_atlas.promote(cache_key);

View file

@ -1,10 +1,13 @@
use crate::{Cache, Params, Resolution};
use std::{mem, slice};
use wgpu::{BindGroup, Buffer, BufferDescriptor, BufferUsages, Device, Queue};
use std::mem;
use std::slice;
/// Controls the visible area of all text for a given renderer. Any text outside of the visible
/// area will be clipped.
///
/// Many projects will only ever need a single `Viewport`, but it is possible to create multiple
/// `Viewport`s if you want to render text to specific areas within a window (without having to)
/// bound each `TextArea`).
#[derive(Debug)]
pub struct Viewport {
params: Params,
@ -13,6 +16,7 @@ pub struct Viewport {
}
impl Viewport {
/// Creates a new `Viewport` with the given `device` and `cache`.
pub fn new(device: &Device, cache: &Cache) -> Self {
let params = Params {
screen_resolution: Resolution {
@ -38,6 +42,7 @@ impl Viewport {
}
}
/// Updates the `Viewport` with the given `resolution`.
pub fn update(&mut self, queue: &Queue, resolution: Resolution) {
if self.params.screen_resolution != resolution {
self.params.screen_resolution = resolution;
@ -51,6 +56,7 @@ impl Viewport {
}
}
/// Returns the current resolution of the `Viewport`.
pub fn resolution(&self) -> Resolution {
self.params.screen_resolution
}