Cleanup before release
This commit is contained in:
parent
2daf883cad
commit
692e23ca33
8 changed files with 96 additions and 84 deletions
|
@ -1,7 +1,7 @@
|
||||||
use glyphon::{
|
use glyphon::{
|
||||||
Attrs, Buffer, Cache, Color, ContentType, CustomGlyph, RasterizationRequest, RasterizedCustomGlyph,
|
Attrs, Buffer, Cache, Color, ContentType, CustomGlyph, Family, FontSystem, Metrics,
|
||||||
Family, FontSystem, Metrics, Resolution, Shaping, SwashCache, TextArea, TextAtlas, TextBounds,
|
RasterizeCustomGlyphRequest, RasterizedCustomGlyph, Resolution, Shaping, SwashCache, TextArea,
|
||||||
TextRenderer, Viewport,
|
TextAtlas, TextBounds, TextRenderer, Viewport,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
|
@ -28,16 +28,13 @@ struct WindowState {
|
||||||
queue: wgpu::Queue,
|
queue: wgpu::Queue,
|
||||||
surface: wgpu::Surface<'static>,
|
surface: wgpu::Surface<'static>,
|
||||||
surface_config: SurfaceConfiguration,
|
surface_config: SurfaceConfiguration,
|
||||||
|
|
||||||
font_system: FontSystem,
|
font_system: FontSystem,
|
||||||
swash_cache: SwashCache,
|
swash_cache: SwashCache,
|
||||||
viewport: glyphon::Viewport,
|
viewport: glyphon::Viewport,
|
||||||
atlas: glyphon::TextAtlas,
|
atlas: glyphon::TextAtlas,
|
||||||
text_renderer: glyphon::TextRenderer,
|
text_renderer: glyphon::TextRenderer,
|
||||||
text_buffer: glyphon::Buffer,
|
text_buffer: glyphon::Buffer,
|
||||||
|
rasterize_svg: Box<dyn Fn(RasterizeCustomGlyphRequest) -> Option<RasterizedCustomGlyph>>,
|
||||||
rasterize_svg: Box<dyn Fn(RasterizationRequest) -> Option<RasterizedCustomGlyph>>,
|
|
||||||
|
|
||||||
// Make sure that the winit window is last in the struct so that
|
// Make sure that the winit window is last in the struct so that
|
||||||
// it is dropped after the wgpu surface is dropped, otherwise the
|
// it is dropped after the wgpu surface is dropped, otherwise the
|
||||||
// program may crash when closed. This is probably a bug in wgpu.
|
// program may crash when closed. This is probably a bug in wgpu.
|
||||||
|
@ -106,46 +103,47 @@ impl WindowState {
|
||||||
let svg_0 = resvg::usvg::Tree::from_data(LION_SVG, &Default::default()).unwrap();
|
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 svg_1 = resvg::usvg::Tree::from_data(EAGLE_SVG, &Default::default()).unwrap();
|
||||||
|
|
||||||
let rasterize_svg = move |input: RasterizationRequest| -> Option<RasterizedCustomGlyph> {
|
let rasterize_svg =
|
||||||
// Select the svg data based on the custom glyph ID.
|
move |input: RasterizeCustomGlyphRequest| -> Option<RasterizedCustomGlyph> {
|
||||||
let (svg, content_type) = match input.id {
|
// Select the svg data based on the custom glyph ID.
|
||||||
0 => (&svg_0, ContentType::Mask),
|
let (svg, content_type) = match input.id {
|
||||||
1 => (&svg_1, ContentType::Color),
|
0 => (&svg_0, ContentType::Mask),
|
||||||
_ => return None,
|
1 => (&svg_1, ContentType::Color),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the scale based on the "glyph size".
|
||||||
|
let svg_size = svg.size();
|
||||||
|
let scale_x = input.width as f32 / svg_size.width();
|
||||||
|
let scale_y = input.height as f32 / svg_size.height();
|
||||||
|
|
||||||
|
let Some(mut pixmap) =
|
||||||
|
resvg::tiny_skia::Pixmap::new(input.width as u32, input.height as u32)
|
||||||
|
else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut transform = resvg::usvg::Transform::from_scale(scale_x, scale_y);
|
||||||
|
|
||||||
|
// Offset the glyph by the subpixel amount.
|
||||||
|
let offset_x = input.x_bin.as_float();
|
||||||
|
let offset_y = input.y_bin.as_float();
|
||||||
|
if offset_x != 0.0 || offset_y != 0.0 {
|
||||||
|
transform = transform.post_translate(offset_x, offset_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
resvg::render(svg, transform, &mut pixmap.as_mut());
|
||||||
|
|
||||||
|
let data: Vec<u8> = if let ContentType::Mask = content_type {
|
||||||
|
// Only use the alpha channel for symbolic icons.
|
||||||
|
pixmap.data().iter().skip(3).step_by(4).copied().collect()
|
||||||
|
} else {
|
||||||
|
pixmap.data().to_vec()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(RasterizedCustomGlyph { data, content_type })
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate the scale based on the "glyph size".
|
|
||||||
let svg_size = svg.size();
|
|
||||||
let scale_x = input.width as f32 / svg_size.width();
|
|
||||||
let scale_y = input.height as f32 / svg_size.height();
|
|
||||||
|
|
||||||
let Some(mut pixmap) =
|
|
||||||
resvg::tiny_skia::Pixmap::new(input.width as u32, input.height as u32)
|
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut transform = resvg::usvg::Transform::from_scale(scale_x, scale_y);
|
|
||||||
|
|
||||||
// Offset the glyph by the subpixel amount.
|
|
||||||
let offset_x = input.x_bin.as_float();
|
|
||||||
let offset_y = input.y_bin.as_float();
|
|
||||||
if offset_x != 0.0 || offset_y != 0.0 {
|
|
||||||
transform = transform.post_translate(offset_x, offset_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
resvg::render(svg, transform, &mut pixmap.as_mut());
|
|
||||||
|
|
||||||
let data: Vec<u8> = if let ContentType::Mask = content_type {
|
|
||||||
// Only use the alpha channel for symbolic icons.
|
|
||||||
pixmap.data().iter().skip(3).step_by(4).copied().collect()
|
|
||||||
} else {
|
|
||||||
pixmap.data().to_vec()
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(RasterizedCustomGlyph { data, content_type })
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
|
|
|
@ -244,6 +244,7 @@ impl winit::application::ApplicationHandler for Application {
|
||||||
bottom: top.floor() as i32 + physical_size.height,
|
bottom: top.floor() as i32 + physical_size.height,
|
||||||
},
|
},
|
||||||
default_color: FONT_COLOR,
|
default_color: FONT_COLOR,
|
||||||
|
custom_glyphs: &[],
|
||||||
};
|
};
|
||||||
|
|
||||||
let total_lines = b
|
let total_lines = b
|
||||||
|
|
17
src/cache.rs
17
src/cache.rs
|
@ -1,5 +1,11 @@
|
||||||
use crate::{GlyphToRender, Params};
|
use crate::{GlyphToRender, Params};
|
||||||
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
mem,
|
||||||
|
num::NonZeroU64,
|
||||||
|
ops::Deref,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutEntry,
|
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutEntry,
|
||||||
BindingResource, BindingType, BlendState, Buffer, BufferBindingType, ColorTargetState,
|
BindingResource, BindingType, BlendState, Buffer, BufferBindingType, ColorTargetState,
|
||||||
|
@ -10,12 +16,8 @@ use wgpu::{
|
||||||
TextureFormat, TextureSampleType, TextureView, TextureViewDimension, VertexFormat, VertexState,
|
TextureFormat, TextureSampleType, TextureView, TextureViewDimension, VertexFormat, VertexState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
/// A cache to share common resources (e.g., pipelines, layouts, shaders) between multiple text
|
||||||
use std::mem;
|
/// renderers.
|
||||||
use std::num::NonZeroU64;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Cache(Arc<Inner>);
|
pub struct Cache(Arc<Inner>);
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ struct Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cache {
|
impl Cache {
|
||||||
|
/// Creates a new `Cache` with the given `device`.
|
||||||
pub fn new(device: &Device) -> Self {
|
pub fn new(device: &Device) -> Self {
|
||||||
let sampler = device.create_sampler(&SamplerDescriptor {
|
let sampler = device.create_sampler(&SamplerDescriptor {
|
||||||
label: Some("glyphon sampler"),
|
label: Some("glyphon sampler"),
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct CustomGlyph {
|
||||||
/// The color of this glyph (only relevant if the glyph is rendered with the
|
/// The color of this glyph (only relevant if the glyph is rendered with the
|
||||||
/// type [`ContentType::Mask`])
|
/// type [`ContentType::Mask`])
|
||||||
///
|
///
|
||||||
/// Set to `None` to use [`TextArea::default_color`].
|
/// Set to `None` to use [`crate::TextArea::default_color`].
|
||||||
pub color: Option<Color>,
|
pub color: Option<Color>,
|
||||||
/// If `true`, then this glyph will be snapped to the nearest whole physical
|
/// If `true`, then this glyph will be snapped to the nearest whole physical
|
||||||
/// pixel and the resulting `SubpixelBin`'s in `RasterizationRequest` will always
|
/// pixel and the resulting `SubpixelBin`'s in `RasterizationRequest` will always
|
||||||
|
@ -31,7 +31,7 @@ pub struct CustomGlyph {
|
||||||
|
|
||||||
/// A request to rasterize a custom glyph
|
/// A request to rasterize a custom glyph
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct RasterizationRequest {
|
pub struct RasterizeCustomGlyphRequest {
|
||||||
/// The unique identifier of the glyph
|
/// The unique identifier of the glyph
|
||||||
pub id: CustomGlyphId,
|
pub id: CustomGlyphId,
|
||||||
/// The width of the glyph in physical pixels
|
/// The width of the glyph in physical pixels
|
||||||
|
@ -63,7 +63,11 @@ pub struct RasterizedCustomGlyph {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ mod viewport;
|
||||||
|
|
||||||
pub use cache::Cache;
|
pub use cache::Cache;
|
||||||
pub use custom_glyph::{
|
pub use custom_glyph::{
|
||||||
ContentType, CustomGlyph, CustomGlyphId, RasterizationRequest, RasterizedCustomGlyph,
|
ContentType, CustomGlyph, CustomGlyphId, RasterizeCustomGlyphRequest, RasterizedCustomGlyph,
|
||||||
};
|
};
|
||||||
pub use error::{PrepareError, RenderError};
|
pub use error::{PrepareError, RenderError};
|
||||||
pub use text_atlas::{ColorMode, TextAtlas};
|
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
|
/// 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.
|
/// match the `left` and `top` values.
|
||||||
pub bounds: TextBounds,
|
pub bounds: TextBounds,
|
||||||
// The default color of the text area.
|
/// The default color of the text area.
|
||||||
pub default_color: Color,
|
pub default_color: Color,
|
||||||
|
/// Additional custom glyphs to render.
|
||||||
/// Additional custom glyphs to render
|
|
||||||
pub custom_glyphs: &'a [CustomGlyph],
|
pub custom_glyphs: &'a [CustomGlyph],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
text_render::GlyphonCacheKey, Cache, ContentType, RasterizationRequest, RasterizedCustomGlyph,
|
text_render::GlyphonCacheKey, Cache, ContentType, RasterizeCustomGlyphRequest, FontSystem,
|
||||||
FontSystem, GlyphDetails, GpuCacheStatus, SwashCache,
|
GlyphDetails, GpuCacheStatus, RasterizedCustomGlyph, SwashCache,
|
||||||
};
|
};
|
||||||
use etagere::{size2, Allocation, BucketedAtlasAllocator};
|
use etagere::{size2, Allocation, BucketedAtlasAllocator};
|
||||||
use lru::LruCache;
|
use lru::LruCache;
|
||||||
|
@ -124,7 +124,9 @@ impl InnerAtlas {
|
||||||
font_system: &mut FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache: &mut SwashCache,
|
cache: &mut SwashCache,
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
mut rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
|
mut rasterize_custom_glyph: impl FnMut(
|
||||||
|
RasterizeCustomGlyphRequest,
|
||||||
|
) -> Option<RasterizedCustomGlyph>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self.size >= self.max_texture_dimension_2d {
|
if self.size >= self.max_texture_dimension_2d {
|
||||||
return false;
|
return false;
|
||||||
|
@ -169,7 +171,7 @@ impl InnerAtlas {
|
||||||
(image.data, width, height)
|
(image.data, width, height)
|
||||||
}
|
}
|
||||||
GlyphonCacheKey::Custom(cache_key) => {
|
GlyphonCacheKey::Custom(cache_key) => {
|
||||||
let input = RasterizationRequest {
|
let input = RasterizeCustomGlyphRequest {
|
||||||
id: cache_key.glyph_id,
|
id: cache_key.glyph_id,
|
||||||
width: cache_key.width,
|
width: cache_key.width,
|
||||||
height: cache_key.height,
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ColorMode {
|
pub enum ColorMode {
|
||||||
/// Accurate color management.
|
/// Accurate color management.
|
||||||
|
@ -352,7 +354,9 @@ impl TextAtlas {
|
||||||
cache: &mut SwashCache,
|
cache: &mut SwashCache,
|
||||||
content_type: ContentType,
|
content_type: ContentType,
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
|
rasterize_custom_glyph: impl FnMut(
|
||||||
|
RasterizeCustomGlyphRequest,
|
||||||
|
) -> Option<RasterizedCustomGlyph>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let did_grow = match content_type {
|
let did_grow = match content_type {
|
||||||
ContentType::Mask => self.mask_atlas.grow(
|
ContentType::Mask => self.mask_atlas.grow(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
custom_glyph::CustomGlyphCacheKey, ColorMode, ContentType, RasterizationRequest, RasterizedCustomGlyph,
|
custom_glyph::CustomGlyphCacheKey, ColorMode, ContentType, FontSystem, GlyphDetails,
|
||||||
FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, PrepareError, RenderError, SwashCache,
|
GlyphToRender, GpuCacheStatus, PrepareError, RasterizeCustomGlyphRequest,
|
||||||
SwashContent, TextArea, TextAtlas, Viewport,
|
RasterizedCustomGlyph, RenderError, SwashCache, SwashContent, TextArea, TextAtlas, Viewport,
|
||||||
};
|
};
|
||||||
use cosmic_text::{Color, SubpixelBin};
|
use cosmic_text::{Color, SubpixelBin};
|
||||||
use std::{slice, sync::Arc};
|
use std::{slice, sync::Arc};
|
||||||
|
@ -104,7 +104,7 @@ impl TextRenderer {
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
text_areas: impl IntoIterator<Item = TextArea<'a>>,
|
text_areas: impl IntoIterator<Item = TextArea<'a>>,
|
||||||
cache: &mut SwashCache,
|
cache: &mut SwashCache,
|
||||||
rasterize_custom_glyph: impl FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
|
rasterize_custom_glyph: impl FnMut(RasterizeCustomGlyphRequest) -> Option<RasterizedCustomGlyph>,
|
||||||
) -> Result<(), PrepareError> {
|
) -> Result<(), PrepareError> {
|
||||||
self.prepare_with_depth_and_custom(
|
self.prepare_with_depth_and_custom(
|
||||||
device,
|
device,
|
||||||
|
@ -130,7 +130,9 @@ impl TextRenderer {
|
||||||
text_areas: impl IntoIterator<Item = TextArea<'a>>,
|
text_areas: impl IntoIterator<Item = TextArea<'a>>,
|
||||||
cache: &mut SwashCache,
|
cache: &mut SwashCache,
|
||||||
mut metadata_to_depth: impl FnMut(usize) -> f32,
|
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> {
|
) -> Result<(), PrepareError> {
|
||||||
self.glyph_vertices.clear();
|
self.glyph_vertices.clear();
|
||||||
|
|
||||||
|
@ -193,7 +195,7 @@ impl TextRenderer {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = RasterizationRequest {
|
let input = RasterizeCustomGlyphRequest {
|
||||||
id: glyph.id,
|
id: glyph.id,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -202,9 +204,7 @@ impl TextRenderer {
|
||||||
scale: text_area.scale,
|
scale: text_area.scale,
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(output) = (rasterize_custom_glyph)(input) else {
|
let output = (rasterize_custom_glyph)(input)?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
output.validate(&input, None);
|
output.validate(&input, None);
|
||||||
|
|
||||||
|
@ -268,11 +268,8 @@ impl TextRenderer {
|
||||||
font_system,
|
font_system,
|
||||||
_rasterize_custom_glyph|
|
_rasterize_custom_glyph|
|
||||||
-> Option<GetGlyphImageResult> {
|
-> Option<GetGlyphImageResult> {
|
||||||
let Some(image) =
|
let image =
|
||||||
cache.get_image_uncached(font_system, physical_glyph.cache_key)
|
cache.get_image_uncached(font_system, physical_glyph.cache_key)?;
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let content_type = match image.content {
|
let content_type = match image.content {
|
||||||
SwashContent::Color => ContentType::Color,
|
SwashContent::Color => ContentType::Color,
|
||||||
|
@ -429,7 +426,7 @@ fn prepare_glyph<R>(
|
||||||
mut rasterize_custom_glyph: R,
|
mut rasterize_custom_glyph: R,
|
||||||
) -> Result<Option<GlyphToRender>, PrepareError>
|
) -> Result<Option<GlyphToRender>, PrepareError>
|
||||||
where
|
where
|
||||||
R: FnMut(RasterizationRequest) -> Option<RasterizedCustomGlyph>,
|
R: FnMut(RasterizeCustomGlyphRequest) -> Option<RasterizedCustomGlyph>,
|
||||||
{
|
{
|
||||||
if atlas.mask_atlas.glyph_cache.contains(&cache_key) {
|
if atlas.mask_atlas.glyph_cache.contains(&cache_key) {
|
||||||
atlas.mask_atlas.promote(cache_key);
|
atlas.mask_atlas.promote(cache_key);
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use crate::{Cache, Params, Resolution};
|
use crate::{Cache, Params, Resolution};
|
||||||
|
use std::{mem, slice};
|
||||||
use wgpu::{BindGroup, Buffer, BufferDescriptor, BufferUsages, Device, Queue};
|
use wgpu::{BindGroup, Buffer, BufferDescriptor, BufferUsages, Device, Queue};
|
||||||
|
|
||||||
use std::mem;
|
/// Controls the visible area of all text for a given renderer. Any text outside of the visible
|
||||||
use std::slice;
|
/// 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)]
|
#[derive(Debug)]
|
||||||
pub struct Viewport {
|
pub struct Viewport {
|
||||||
params: Params,
|
params: Params,
|
||||||
|
@ -13,6 +16,7 @@ pub struct Viewport {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Viewport {
|
impl Viewport {
|
||||||
|
/// Creates a new `Viewport` with the given `device` and `cache`.
|
||||||
pub fn new(device: &Device, cache: &Cache) -> Self {
|
pub fn new(device: &Device, cache: &Cache) -> Self {
|
||||||
let params = Params {
|
let params = Params {
|
||||||
screen_resolution: Resolution {
|
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) {
|
pub fn update(&mut self, queue: &Queue, resolution: Resolution) {
|
||||||
if self.params.screen_resolution != resolution {
|
if self.params.screen_resolution != resolution {
|
||||||
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 {
|
pub fn resolution(&self) -> Resolution {
|
||||||
self.params.screen_resolution
|
self.params.screen_resolution
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue