Merge pull request #1 from hecrj/feature/update-glyph_brush
Update `glyph_brush` to `0.7`
This commit is contained in:
commit
783175e56b
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "glow_glyph"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A fast text renderer for glow, powered by glyph_brush"
|
||||
|
@ -12,7 +12,7 @@ readme = "README.md"
|
|||
|
||||
[dependencies]
|
||||
glow = "0.4"
|
||||
glyph_brush = "0.6"
|
||||
glyph_brush = "0.7"
|
||||
log = "0.4"
|
||||
bytemuck = "1.2"
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use glow::HasContext;
|
||||
use glow_glyph::{GlyphBrushBuilder, Region, Scale, Section};
|
||||
use glow_glyph::{ab_glyph, GlyphBrushBuilder, Region, Section, Text};
|
||||
use std::error::Error;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::init();
|
||||
|
||||
// Open window and create a surface
|
||||
|
@ -26,10 +27,11 @@ fn main() -> Result<(), String> {
|
|||
});
|
||||
|
||||
// Prepare glyph_brush
|
||||
let inconsolata: &[u8] = include_bytes!("Inconsolata-Regular.ttf");
|
||||
let mut glyph_brush = GlyphBrushBuilder::using_font_bytes(inconsolata)
|
||||
.expect("Load fonts")
|
||||
.build(&gl);
|
||||
let inconsolata = ab_glyph::FontArc::try_from_slice(include_bytes!(
|
||||
"Inconsolata-Regular.ttf"
|
||||
))?;
|
||||
|
||||
let mut glyph_brush = GlyphBrushBuilder::using_font(inconsolata).build(&gl);
|
||||
|
||||
// Render loop
|
||||
context.window().request_redraw();
|
||||
|
@ -66,11 +68,12 @@ fn main() -> Result<(), String> {
|
|||
unsafe { gl.clear(glow::COLOR_BUFFER_BIT) }
|
||||
|
||||
glyph_brush.queue(Section {
|
||||
text: "Hello glow_glyph!",
|
||||
screen_position: (30.0, 30.0),
|
||||
color: [0.0, 0.0, 0.0, 1.0],
|
||||
scale: Scale { x: 40.0, y: 40.0 },
|
||||
bounds: (size.width as f32, size.height as f32),
|
||||
text: vec![Text::default()
|
||||
.with_text("Hello wgpu_glyph!")
|
||||
.with_color([0.0, 0.0, 0.0, 1.0])
|
||||
.with_scale(40.0)],
|
||||
..Section::default()
|
||||
});
|
||||
|
||||
|
@ -79,11 +82,12 @@ fn main() -> Result<(), String> {
|
|||
.expect("Draw queued");
|
||||
|
||||
glyph_brush.queue(Section {
|
||||
text: "Hello glow_glyph!",
|
||||
screen_position: (30.0, 90.0),
|
||||
color: [1.0, 1.0, 1.0, 1.0],
|
||||
scale: Scale { x: 40.0, y: 40.0 },
|
||||
bounds: (size.width as f32, size.height as f32),
|
||||
text: vec![Text::default()
|
||||
.with_text("Hello wgpu_glyph!")
|
||||
.with_color([1.0, 1.0, 1.0, 1.0])
|
||||
.with_scale(40.0)],
|
||||
..Section::default()
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use glow::HasContext;
|
||||
use glow_glyph::{GlyphBrushBuilder, Scale, Section};
|
||||
use glow_glyph::{ab_glyph, GlyphBrushBuilder, Section, Text};
|
||||
use std::error::Error;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::init();
|
||||
|
||||
// Open window and create a surface
|
||||
|
@ -26,10 +27,11 @@ fn main() -> Result<(), String> {
|
|||
});
|
||||
|
||||
// Prepare glyph_brush
|
||||
let inconsolata: &[u8] = include_bytes!("Inconsolata-Regular.ttf");
|
||||
let mut glyph_brush = GlyphBrushBuilder::using_font_bytes(inconsolata)
|
||||
.expect("Load fonts")
|
||||
.build(&gl);
|
||||
let inconsolata = ab_glyph::FontArc::try_from_slice(include_bytes!(
|
||||
"Inconsolata-Regular.ttf"
|
||||
))?;
|
||||
|
||||
let mut glyph_brush = GlyphBrushBuilder::using_font(inconsolata).build(&gl);
|
||||
|
||||
// Render loop
|
||||
context.window().request_redraw();
|
||||
|
@ -72,20 +74,22 @@ fn main() -> Result<(), String> {
|
|||
unsafe { gl.clear(glow::COLOR_BUFFER_BIT) }
|
||||
|
||||
glyph_brush.queue(Section {
|
||||
text: "Hello glow_glyph!",
|
||||
screen_position: (30.0, 30.0),
|
||||
color: [0.0, 0.0, 0.0, 1.0],
|
||||
scale: Scale { x: 40.0, y: 40.0 },
|
||||
bounds: (size.width as f32, size.height as f32),
|
||||
text: vec![Text::default()
|
||||
.with_text("Hello wgpu_glyph!")
|
||||
.with_color([0.0, 0.0, 0.0, 1.0])
|
||||
.with_scale(40.0)],
|
||||
..Section::default()
|
||||
});
|
||||
|
||||
glyph_brush.queue(Section {
|
||||
text: "Hello glow_glyph!",
|
||||
screen_position: (30.0, 90.0),
|
||||
color: [1.0, 1.0, 1.0, 1.0],
|
||||
scale: Scale { x: 40.0, y: 40.0 },
|
||||
bounds: (size.width as f32, size.height as f32),
|
||||
text: vec![Text::default()
|
||||
.with_text("Hello wgpu_glyph!")
|
||||
.with_color([1.0, 1.0, 1.0, 1.0])
|
||||
.with_scale(40.0)],
|
||||
..Section::default()
|
||||
});
|
||||
|
||||
|
|
|
@ -1,67 +1,57 @@
|
|||
use core::hash::BuildHasher;
|
||||
|
||||
use glyph_brush::ab_glyph::Font;
|
||||
use glyph_brush::delegate_glyph_brush_builder_fns;
|
||||
use glyph_brush::{rusttype, DefaultSectionHasher};
|
||||
use rusttype::{Error, Font, SharedBytes};
|
||||
use glyph_brush::DefaultSectionHasher;
|
||||
|
||||
use super::GlyphBrush;
|
||||
|
||||
/// Builder for a [`GlyphBrush`](struct.GlyphBrush.html).
|
||||
pub struct GlyphBrushBuilder<'a, H = DefaultSectionHasher> {
|
||||
inner: glyph_brush::GlyphBrushBuilder<'a, H>,
|
||||
pub struct GlyphBrushBuilder<F, H = DefaultSectionHasher> {
|
||||
inner: glyph_brush::GlyphBrushBuilder<F, H>,
|
||||
}
|
||||
|
||||
impl<'a, H> From<glyph_brush::GlyphBrushBuilder<'a, H>>
|
||||
for GlyphBrushBuilder<'a, H>
|
||||
impl<F, H> From<glyph_brush::GlyphBrushBuilder<F, H>>
|
||||
for GlyphBrushBuilder<F, H>
|
||||
{
|
||||
fn from(inner: glyph_brush::GlyphBrushBuilder<'a, H>) -> Self {
|
||||
fn from(inner: glyph_brush::GlyphBrushBuilder<F, H>) -> Self {
|
||||
GlyphBrushBuilder { inner }
|
||||
}
|
||||
}
|
||||
impl<'a> GlyphBrushBuilder<'a> {
|
||||
/// Specifies the default font data used to render glyphs.
|
||||
/// Referenced with `FontId(0)`, which is default.
|
||||
#[inline]
|
||||
pub fn using_font_bytes<B: Into<SharedBytes<'a>>>(
|
||||
font_0_data: B,
|
||||
) -> Result<Self, Error> {
|
||||
let font = Font::from_bytes(font_0_data)?;
|
||||
|
||||
Ok(Self::using_font(font))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn using_fonts_bytes<B, V>(font_data: V) -> Result<Self, Error>
|
||||
where
|
||||
B: Into<SharedBytes<'a>>,
|
||||
V: Into<Vec<B>>,
|
||||
{
|
||||
let fonts = font_data
|
||||
.into()
|
||||
.into_iter()
|
||||
.map(Font::from_bytes)
|
||||
.collect::<Result<Vec<Font>, Error>>()?;
|
||||
|
||||
Ok(Self::using_fonts(fonts))
|
||||
}
|
||||
|
||||
impl GlyphBrushBuilder<()> {
|
||||
/// Specifies the default font used to render glyphs.
|
||||
/// Referenced with `FontId(0)`, which is default.
|
||||
#[inline]
|
||||
pub fn using_font(font_0: Font<'a>) -> Self {
|
||||
Self::using_fonts(vec![font_0])
|
||||
pub fn using_font<F: Font>(font: F) -> GlyphBrushBuilder<F> {
|
||||
Self::using_fonts(vec![font])
|
||||
}
|
||||
|
||||
pub fn using_fonts<V: Into<Vec<Font<'a>>>>(fonts: V) -> Self {
|
||||
pub fn using_fonts<F: Font>(fonts: Vec<F>) -> GlyphBrushBuilder<F> {
|
||||
GlyphBrushBuilder {
|
||||
inner: glyph_brush::GlyphBrushBuilder::using_fonts(fonts),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, H: BuildHasher> GlyphBrushBuilder<'a, H> {
|
||||
impl<F: Font, H: BuildHasher> GlyphBrushBuilder<F, H> {
|
||||
delegate_glyph_brush_builder_fns!(inner);
|
||||
|
||||
/// When multiple CPU cores are available spread rasterization work across
|
||||
/// all cores.
|
||||
///
|
||||
/// Significantly reduces worst case latency in multicore environments.
|
||||
///
|
||||
/// # Platform-specific behaviour
|
||||
///
|
||||
/// This option has no effect on wasm32.
|
||||
pub fn draw_cache_multithread(mut self, multithread: bool) -> Self {
|
||||
self.inner.draw_cache_builder =
|
||||
self.inner.draw_cache_builder.multithread(multithread);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the section hasher. `GlyphBrush` cannot handle absolute section
|
||||
/// hash collisions so use a good hash algorithm.
|
||||
///
|
||||
|
@ -72,14 +62,14 @@ impl<'a, H: BuildHasher> GlyphBrushBuilder<'a, H> {
|
|||
pub fn section_hasher<T: BuildHasher>(
|
||||
self,
|
||||
section_hasher: T,
|
||||
) -> GlyphBrushBuilder<'a, T> {
|
||||
) -> GlyphBrushBuilder<F, T> {
|
||||
GlyphBrushBuilder {
|
||||
inner: self.inner.section_hasher(section_hasher),
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a `GlyphBrush` in the given `glow::Context`.
|
||||
pub fn build(self, gl: &glow::Context) -> GlyphBrush<'a, H> {
|
||||
GlyphBrush::<H>::new(gl, self.inner)
|
||||
pub fn build(self, gl: &glow::Context) -> GlyphBrush<F, H> {
|
||||
GlyphBrush::<F, H>::new(gl, self.inner)
|
||||
}
|
||||
}
|
||||
|
|
238
src/lib.rs
238
src/lib.rs
|
@ -12,30 +12,31 @@ pub use region::Region;
|
|||
use pipeline::{Instance, Pipeline};
|
||||
|
||||
pub use builder::GlyphBrushBuilder;
|
||||
pub use glyph_brush::ab_glyph;
|
||||
pub use glyph_brush::{
|
||||
rusttype::{self, Font, Point, PositionedGlyph, Rect, Scale, SharedBytes},
|
||||
BuiltInLineBreaker, FontId, FontMap, GlyphCruncher, GlyphPositioner,
|
||||
HorizontalAlign, Layout, LineBreak, LineBreaker, OwnedSectionText,
|
||||
OwnedVariedSection, PositionedGlyphIter, Section, SectionGeometry,
|
||||
SectionText, VariedSection, VerticalAlign,
|
||||
BuiltInLineBreaker, Extra, FontId, GlyphCruncher, GlyphPositioner,
|
||||
HorizontalAlign, Layout, LineBreak, LineBreaker, Section, SectionGeometry,
|
||||
SectionGlyph, SectionGlyphIter, SectionText, Text, VerticalAlign,
|
||||
};
|
||||
|
||||
use ab_glyph::{Font, FontArc, Rect};
|
||||
|
||||
use core::hash::BuildHasher;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use glyph_brush::{BrushAction, BrushError, Color, DefaultSectionHasher};
|
||||
use glyph_brush::{BrushAction, BrushError, DefaultSectionHasher};
|
||||
use log::{log_enabled, warn};
|
||||
|
||||
/// Object allowing glyph drawing, containing cache state. Manages glyph positioning cacheing,
|
||||
/// glyph draw caching & efficient GPU texture cache updating and re-sizing on demand.
|
||||
///
|
||||
/// Build using a [`GlyphBrushBuilder`](struct.GlyphBrushBuilder.html).
|
||||
pub struct GlyphBrush<'font, H = DefaultSectionHasher> {
|
||||
pub struct GlyphBrush<F = FontArc, H = DefaultSectionHasher> {
|
||||
pipeline: Pipeline,
|
||||
glyph_brush: glyph_brush::GlyphBrush<'font, Instance, H>,
|
||||
glyph_brush: glyph_brush::GlyphBrush<Instance, Extra, F, H>,
|
||||
}
|
||||
|
||||
impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
||||
impl<F: Font, H: BuildHasher> GlyphBrush<F, H> {
|
||||
/// Queues a section/layout to be drawn by the next call of
|
||||
/// [`draw_queued`](struct.GlyphBrush.html#method.draw_queued). Can be
|
||||
/// called multiple times to queue multiple sections for drawing.
|
||||
|
@ -44,7 +45,7 @@ impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
|||
#[inline]
|
||||
pub fn queue<'a, S>(&mut self, section: S)
|
||||
where
|
||||
S: Into<Cow<'a, VariedSection<'a>>>,
|
||||
S: Into<Cow<'a, Section<'a>>>,
|
||||
{
|
||||
self.glyph_brush.queue(section)
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
|||
custom_layout: &G,
|
||||
) where
|
||||
G: GlyphPositioner,
|
||||
S: Into<Cow<'a, VariedSection<'a>>>,
|
||||
S: Into<Cow<'a, Section<'a>>>,
|
||||
{
|
||||
self.glyph_brush.queue_custom_layout(section, custom_layout)
|
||||
}
|
||||
|
@ -76,11 +77,11 @@ impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
|||
#[inline]
|
||||
pub fn queue_pre_positioned(
|
||||
&mut self,
|
||||
glyphs: Vec<(PositionedGlyph<'font>, Color, FontId)>,
|
||||
bounds: Rect<f32>,
|
||||
z: f32,
|
||||
glyphs: Vec<SectionGlyph>,
|
||||
extra: Vec<Extra>,
|
||||
bounds: Rect,
|
||||
) {
|
||||
self.glyph_brush.queue_pre_positioned(glyphs, bounds, z)
|
||||
self.glyph_brush.queue_pre_positioned(glyphs, extra, bounds)
|
||||
}
|
||||
|
||||
/// Retains the section in the cache as if it had been used in the last
|
||||
|
@ -94,7 +95,7 @@ impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
|||
section: S,
|
||||
custom_layout: &G,
|
||||
) where
|
||||
S: Into<Cow<'a, VariedSection<'a>>>,
|
||||
S: Into<Cow<'a, Section<'a>>>,
|
||||
G: GlyphPositioner,
|
||||
{
|
||||
self.glyph_brush
|
||||
|
@ -109,110 +110,28 @@ impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
|||
#[inline]
|
||||
pub fn keep_cached<'a, S>(&mut self, section: S)
|
||||
where
|
||||
S: Into<Cow<'a, VariedSection<'a>>>,
|
||||
S: Into<Cow<'a, Section<'a>>>,
|
||||
{
|
||||
self.glyph_brush.keep_cached(section)
|
||||
}
|
||||
|
||||
fn process_queued(&mut self, context: &glow::Context) {
|
||||
let pipeline = &mut self.pipeline;
|
||||
|
||||
let mut brush_action;
|
||||
|
||||
loop {
|
||||
brush_action = self.glyph_brush.process_queued(
|
||||
|rect, tex_data| {
|
||||
let offset = [rect.min.x as u16, rect.min.y as u16];
|
||||
let size = [rect.width() as u16, rect.height() as u16];
|
||||
|
||||
pipeline.update_cache(context, offset, size, tex_data);
|
||||
},
|
||||
Instance::from,
|
||||
);
|
||||
|
||||
match brush_action {
|
||||
Ok(_) => break,
|
||||
Err(BrushError::TextureTooSmall { suggested }) => {
|
||||
// TODO: Obtain max texture dimensions
|
||||
let max_image_dimension = 2048;
|
||||
|
||||
let (new_width, new_height) = if (suggested.0
|
||||
> max_image_dimension
|
||||
|| suggested.1 > max_image_dimension)
|
||||
&& (self.glyph_brush.texture_dimensions().0
|
||||
< max_image_dimension
|
||||
|| self.glyph_brush.texture_dimensions().1
|
||||
< max_image_dimension)
|
||||
{
|
||||
(max_image_dimension, max_image_dimension)
|
||||
} else {
|
||||
suggested
|
||||
};
|
||||
|
||||
if log_enabled!(log::Level::Warn) {
|
||||
warn!(
|
||||
"Increasing glyph texture size {old:?} -> {new:?}. \
|
||||
Consider building with `.initial_cache_size({new:?})` to avoid \
|
||||
resizing",
|
||||
old = self.glyph_brush.texture_dimensions(),
|
||||
new = (new_width, new_height),
|
||||
);
|
||||
}
|
||||
|
||||
pipeline
|
||||
.increase_cache_size(context, new_width, new_height);
|
||||
self.glyph_brush.resize_texture(new_width, new_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match brush_action.unwrap() {
|
||||
BrushAction::Draw(verts) => {
|
||||
self.pipeline.upload(context, &verts);
|
||||
}
|
||||
BrushAction::ReDraw => {}
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the available fonts.
|
||||
///
|
||||
/// The `FontId` corresponds to the index of the font data.
|
||||
#[inline]
|
||||
pub fn fonts(&self) -> &[Font<'_>] {
|
||||
pub fn fonts(&self) -> &[F] {
|
||||
self.glyph_brush.fonts()
|
||||
}
|
||||
|
||||
/// Adds an additional font to the one(s) initially added on build.
|
||||
///
|
||||
/// Returns a new [`FontId`](struct.FontId.html) to reference this font.
|
||||
pub fn add_font_bytes<'a: 'font, B: Into<SharedBytes<'a>>>(
|
||||
&mut self,
|
||||
font_data: B,
|
||||
) -> FontId {
|
||||
self.glyph_brush.add_font_bytes(font_data)
|
||||
}
|
||||
|
||||
/// Adds an additional font to the one(s) initially added on build.
|
||||
///
|
||||
/// Returns a new [`FontId`](struct.FontId.html) to reference this font.
|
||||
pub fn add_font<'a: 'font>(&mut self, font_data: Font<'a>) -> FontId {
|
||||
self.glyph_brush.add_font(font_data)
|
||||
pub fn add_font(&mut self, font: F) -> FontId {
|
||||
self.glyph_brush.add_font(font)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
||||
fn new(
|
||||
gl: &glow::Context,
|
||||
raw_builder: glyph_brush::GlyphBrushBuilder<'font, H>,
|
||||
) -> Self {
|
||||
let glyph_brush = raw_builder.build();
|
||||
let (cache_width, cache_height) = glyph_brush.texture_dimensions();
|
||||
GlyphBrush {
|
||||
pipeline: Pipeline::new(gl, cache_width, cache_height),
|
||||
glyph_brush,
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Font + Sync, H: BuildHasher> GlyphBrush<F, H> {
|
||||
/// Draws all queued sections onto a render target.
|
||||
/// See [`queue`](struct.GlyphBrush.html#method.queue).
|
||||
///
|
||||
|
@ -276,6 +195,81 @@ impl<'font, H: BuildHasher> GlyphBrush<'font, H> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_queued(&mut self, context: &glow::Context) {
|
||||
let pipeline = &mut self.pipeline;
|
||||
|
||||
let mut brush_action;
|
||||
|
||||
loop {
|
||||
brush_action = self.glyph_brush.process_queued(
|
||||
|rect, tex_data| {
|
||||
let offset = [rect.min[0] as u16, rect.min[1] as u16];
|
||||
let size = [rect.width() as u16, rect.height() as u16];
|
||||
|
||||
pipeline.update_cache(context, offset, size, tex_data);
|
||||
},
|
||||
Instance::from_vertex,
|
||||
);
|
||||
|
||||
match brush_action {
|
||||
Ok(_) => break,
|
||||
Err(BrushError::TextureTooSmall { suggested }) => {
|
||||
// TODO: Obtain max texture dimensions
|
||||
let max_image_dimension = 2048;
|
||||
|
||||
let (new_width, new_height) = if (suggested.0
|
||||
> max_image_dimension
|
||||
|| suggested.1 > max_image_dimension)
|
||||
&& (self.glyph_brush.texture_dimensions().0
|
||||
< max_image_dimension
|
||||
|| self.glyph_brush.texture_dimensions().1
|
||||
< max_image_dimension)
|
||||
{
|
||||
(max_image_dimension, max_image_dimension)
|
||||
} else {
|
||||
suggested
|
||||
};
|
||||
|
||||
if log_enabled!(log::Level::Warn) {
|
||||
warn!(
|
||||
"Increasing glyph texture size {old:?} -> {new:?}. \
|
||||
Consider building with `.initial_cache_size({new:?})` to avoid \
|
||||
resizing",
|
||||
old = self.glyph_brush.texture_dimensions(),
|
||||
new = (new_width, new_height),
|
||||
);
|
||||
}
|
||||
|
||||
pipeline
|
||||
.increase_cache_size(context, new_width, new_height);
|
||||
self.glyph_brush.resize_texture(new_width, new_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match brush_action.unwrap() {
|
||||
BrushAction::Draw(verts) => {
|
||||
self.pipeline.upload(context, &verts);
|
||||
}
|
||||
BrushAction::ReDraw => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Font, H: BuildHasher> GlyphBrush<F, H> {
|
||||
fn new(
|
||||
gl: &glow::Context,
|
||||
raw_builder: glyph_brush::GlyphBrushBuilder<F, H>,
|
||||
) -> Self {
|
||||
let glyph_brush = raw_builder.build();
|
||||
let (cache_width, cache_height) = glyph_brush.texture_dimensions();
|
||||
|
||||
GlyphBrush {
|
||||
pipeline: Pipeline::new(gl, cache_width, cache_height),
|
||||
glyph_brush,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to generate a generate a transform matrix.
|
||||
|
@ -289,42 +283,42 @@ pub fn orthographic_projection(width: u32, height: u32) -> [f32; 16] {
|
|||
]
|
||||
}
|
||||
|
||||
impl<'font, H: BuildHasher> GlyphCruncher<'font> for GlyphBrush<'font, H> {
|
||||
#[inline]
|
||||
fn pixel_bounds_custom_layout<'a, S, L>(
|
||||
&mut self,
|
||||
section: S,
|
||||
custom_layout: &L,
|
||||
) -> Option<Rect<i32>>
|
||||
where
|
||||
L: GlyphPositioner + std::hash::Hash,
|
||||
S: Into<Cow<'a, VariedSection<'a>>>,
|
||||
{
|
||||
self.glyph_brush
|
||||
.pixel_bounds_custom_layout(section, custom_layout)
|
||||
}
|
||||
|
||||
impl<F: Font, H: BuildHasher> GlyphCruncher<F> for GlyphBrush<F, H> {
|
||||
#[inline]
|
||||
fn glyphs_custom_layout<'a, 'b, S, L>(
|
||||
&'b mut self,
|
||||
section: S,
|
||||
custom_layout: &L,
|
||||
) -> PositionedGlyphIter<'b, 'font>
|
||||
) -> SectionGlyphIter<'b>
|
||||
where
|
||||
L: GlyphPositioner + std::hash::Hash,
|
||||
S: Into<Cow<'a, VariedSection<'a>>>,
|
||||
S: Into<Cow<'a, Section<'a>>>,
|
||||
{
|
||||
self.glyph_brush
|
||||
.glyphs_custom_layout(section, custom_layout)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fonts(&self) -> &[Font<'font>] {
|
||||
fn glyph_bounds_custom_layout<'a, S, L>(
|
||||
&mut self,
|
||||
section: S,
|
||||
custom_layout: &L,
|
||||
) -> Option<Rect>
|
||||
where
|
||||
L: GlyphPositioner + std::hash::Hash,
|
||||
S: Into<Cow<'a, Section<'a>>>,
|
||||
{
|
||||
self.glyph_brush
|
||||
.glyph_bounds_custom_layout(section, custom_layout)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fonts(&self) -> &[F] {
|
||||
self.glyph_brush.fonts()
|
||||
}
|
||||
}
|
||||
|
||||
impl<H> std::fmt::Debug for GlyphBrush<'_, H> {
|
||||
impl<F, H> std::fmt::Debug for GlyphBrush<F, H> {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "GlyphBrush")
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
mod cache;
|
||||
|
||||
use crate::ab_glyph::{point, Rect};
|
||||
use crate::Region;
|
||||
use cache::Cache;
|
||||
|
||||
use glow::HasContext;
|
||||
use glyph_brush::rusttype::{point, Rect};
|
||||
|
||||
pub struct Pipeline {
|
||||
program: <glow::Context as HasContext>::Program,
|
||||
|
@ -212,19 +212,15 @@ unsafe impl bytemuck::Pod for Instance {}
|
|||
|
||||
impl Instance {
|
||||
const INITIAL_AMOUNT: usize = 50_000;
|
||||
}
|
||||
|
||||
impl From<glyph_brush::GlyphVertex> for Instance {
|
||||
#[inline]
|
||||
fn from(vertex: glyph_brush::GlyphVertex) -> Instance {
|
||||
let glyph_brush::GlyphVertex {
|
||||
pub fn from_vertex(
|
||||
glyph_brush::GlyphVertex {
|
||||
mut tex_coords,
|
||||
pixel_coords,
|
||||
bounds,
|
||||
color,
|
||||
z,
|
||||
} = vertex;
|
||||
|
||||
extra,
|
||||
}: glyph_brush::GlyphVertex,
|
||||
) -> Instance {
|
||||
let gl_bounds = bounds;
|
||||
|
||||
let mut gl_rect = Rect {
|
||||
|
@ -262,11 +258,11 @@ impl From<glyph_brush::GlyphVertex> for Instance {
|
|||
}
|
||||
|
||||
Instance {
|
||||
left_top: [gl_rect.min.x, gl_rect.max.y, z],
|
||||
left_top: [gl_rect.min.x, gl_rect.max.y, extra.z],
|
||||
right_bottom: [gl_rect.max.x, gl_rect.min.y],
|
||||
tex_left_top: [tex_coords.min.x, tex_coords.max.y],
|
||||
tex_right_bottom: [tex_coords.max.x, tex_coords.min.y],
|
||||
color,
|
||||
color: extra.color,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue