Introduce PhysicalGlyph for offsetting and scaling
This commit is contained in:
parent
e8b10fd675
commit
eb09cf0259
5 changed files with 79 additions and 38 deletions
|
|
@ -749,16 +749,27 @@ impl Buffer {
|
||||||
{
|
{
|
||||||
for run in self.layout_runs() {
|
for run in self.layout_runs() {
|
||||||
for glyph in run.glyphs.iter() {
|
for glyph in run.glyphs.iter() {
|
||||||
let (cache_key, x_int, y_int) = (glyph.cache_key, glyph.x_int, glyph.y_int);
|
let physical_glyph = glyph.physical((0., 0.), 1.0);
|
||||||
|
|
||||||
let glyph_color = match glyph.color_opt {
|
let glyph_color = match glyph.color_opt {
|
||||||
Some(some) => some,
|
Some(some) => some,
|
||||||
None => color,
|
None => color,
|
||||||
};
|
};
|
||||||
|
|
||||||
cache.with_pixels(font_system, cache_key, glyph_color, |x, y, color| {
|
cache.with_pixels(
|
||||||
f(x_int + x, run.line_y as i32 + y_int + y, 1, 1, color);
|
font_system,
|
||||||
});
|
physical_glyph.cache_key,
|
||||||
|
glyph_color,
|
||||||
|
|x, y, color| {
|
||||||
|
f(
|
||||||
|
physical_glyph.x + x,
|
||||||
|
run.line_y as i32 + physical_glyph.y + y,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ impl CacheKey {
|
||||||
pos: (f32, f32),
|
pos: (f32, f32),
|
||||||
) -> (Self, i32, i32) {
|
) -> (Self, i32, i32) {
|
||||||
let (x, x_bin) = SubpixelBin::new(pos.0);
|
let (x, x_bin) = SubpixelBin::new(pos.0);
|
||||||
let (y, y_bin) = SubpixelBin::new(pos.1);
|
let (y, y_bin) = SubpixelBin::new(pos.1.trunc());
|
||||||
(
|
(
|
||||||
Self {
|
Self {
|
||||||
font_id,
|
font_id,
|
||||||
|
|
|
||||||
|
|
@ -696,7 +696,6 @@ impl Edit for Editor {
|
||||||
) where
|
) where
|
||||||
F: FnMut(i32, i32, u32, u32, Color),
|
F: FnMut(i32, i32, u32, u32, Color),
|
||||||
{
|
{
|
||||||
let font_size = self.buffer.metrics().font_size;
|
|
||||||
let line_height = self.buffer.metrics().line_height;
|
let line_height = self.buffer.metrics().line_height;
|
||||||
|
|
||||||
for run in self.buffer.layout_runs() {
|
for run in self.buffer.layout_runs() {
|
||||||
|
|
@ -852,16 +851,27 @@ impl Edit for Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
for glyph in run.glyphs.iter() {
|
for glyph in run.glyphs.iter() {
|
||||||
let (cache_key, x_int, y_int) = (glyph.cache_key, glyph.x_int, glyph.y_int);
|
let physical_glyph = glyph.physical((0., 0.), 1.0);
|
||||||
|
|
||||||
let glyph_color = match glyph.color_opt {
|
let glyph_color = match glyph.color_opt {
|
||||||
Some(some) => some,
|
Some(some) => some,
|
||||||
None => color,
|
None => color,
|
||||||
};
|
};
|
||||||
|
|
||||||
cache.with_pixels(font_system, cache_key, glyph_color, |x, y, color| {
|
cache.with_pixels(
|
||||||
f(x_int + x, line_y as i32 + y_int + y, 1, 1, color);
|
font_system,
|
||||||
});
|
physical_glyph.cache_key,
|
||||||
|
glyph_color,
|
||||||
|
|x, y, color| {
|
||||||
|
f(
|
||||||
|
physical_glyph.x + x,
|
||||||
|
line_y as i32 + physical_glyph.y + y,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,24 @@ pub struct LayoutGlyph {
|
||||||
pub start: usize,
|
pub start: usize,
|
||||||
/// End index of cluster in original line
|
/// End index of cluster in original line
|
||||||
pub end: usize,
|
pub end: usize,
|
||||||
|
/// Font size of the glyph
|
||||||
|
pub font_size: f32,
|
||||||
|
/// Font id of the glyph
|
||||||
|
pub font_id: fontdb::ID,
|
||||||
|
/// Font id of the glyph
|
||||||
|
pub glyph_id: u16,
|
||||||
/// X offset of hitbox
|
/// X offset of hitbox
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
/// width of hitbox
|
/// Y offset of hitbox
|
||||||
|
pub y: f32,
|
||||||
|
/// Width of hitbox
|
||||||
pub w: f32,
|
pub w: f32,
|
||||||
/// Unicode BiDi embedding level, character is left-to-right if `level` is divisible by 2
|
/// Unicode BiDi embedding level, character is left-to-right if `level` is divisible by 2
|
||||||
pub level: unicode_bidi::Level,
|
pub level: unicode_bidi::Level,
|
||||||
/// Cache key, see [CacheKey]
|
|
||||||
pub cache_key: CacheKey,
|
|
||||||
/// X offset in line
|
/// X offset in line
|
||||||
///
|
///
|
||||||
/// If you are dealing with physical coordinates, you will want to use [`Self::x_int`]
|
/// If you are dealing with physical coordinates, use [`Self::physical`] to obtain a
|
||||||
/// together with [`CacheKey::x_bin`] instead. This will ensure the best alignment of the
|
/// [`PhysicalGlyph`] for rendering.
|
||||||
/// rasterized glyphs with the pixel grid.
|
|
||||||
///
|
///
|
||||||
/// This offset is useful when you are dealing with logical units and you do not care or
|
/// This offset is useful when you are dealing with logical units and you do not care or
|
||||||
/// cannot guarantee pixel grid alignment. For instance, when you want to use the glyphs
|
/// cannot guarantee pixel grid alignment. For instance, when you want to use the glyphs
|
||||||
|
|
@ -34,24 +39,47 @@ pub struct LayoutGlyph {
|
||||||
pub x_offset: f32,
|
pub x_offset: f32,
|
||||||
/// Y offset in line
|
/// Y offset in line
|
||||||
///
|
///
|
||||||
/// If you are dealing with physical coordinates, you will want to use [`Self::y_int`]
|
/// If you are dealing with physical coordinates, use [`Self::physical`] to obtain a
|
||||||
/// together with [`CacheKey::y_bin`] instead. This will ensure the best alignment of the
|
/// [`PhysicalGlyph`] for rendering.
|
||||||
/// rasterized glyphs with the pixel grid.
|
|
||||||
///
|
///
|
||||||
/// This offset is useful when you are dealing with logical units and you do not care or
|
/// This offset is useful when you are dealing with logical units and you do not care or
|
||||||
/// cannot guarantee pixel grid alignment. For instance, when you want to use the glyphs
|
/// cannot guarantee pixel grid alignment. For instance, when you want to use the glyphs
|
||||||
/// for vectorial text, apply linear transformations to the layout, etc.
|
/// for vectorial text, apply linear transformations to the layout, etc.
|
||||||
pub y_offset: f32,
|
pub y_offset: f32,
|
||||||
/// Integer component of X offset in line
|
|
||||||
pub x_int: i32,
|
|
||||||
/// Integer component of Y offset in line
|
|
||||||
pub y_int: i32,
|
|
||||||
/// Optional color override
|
/// Optional color override
|
||||||
pub color_opt: Option<Color>,
|
pub color_opt: Option<Color>,
|
||||||
/// Metadata from `Attrs`
|
/// Metadata from `Attrs`
|
||||||
pub metadata: usize,
|
pub metadata: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PhysicalGlyph {
|
||||||
|
/// Cache key, see [CacheKey]
|
||||||
|
pub cache_key: CacheKey,
|
||||||
|
/// Integer component of X offset in line
|
||||||
|
pub x: i32,
|
||||||
|
/// Integer component of Y offset in line
|
||||||
|
pub y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutGlyph {
|
||||||
|
pub fn physical(&self, offset: (f32, f32), scale: f32) -> PhysicalGlyph {
|
||||||
|
let x_offset = self.font_size * self.x_offset;
|
||||||
|
let y_offset = self.font_size * self.y_offset;
|
||||||
|
|
||||||
|
let (cache_key, x, y) = CacheKey::new(
|
||||||
|
self.font_id,
|
||||||
|
self.glyph_id,
|
||||||
|
self.font_size * scale,
|
||||||
|
(
|
||||||
|
(self.x + x_offset) * scale + offset.0,
|
||||||
|
(self.y - y_offset) * scale + offset.1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
PhysicalGlyph { cache_key, x, y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A line of laid out glyphs
|
/// A line of laid out glyphs
|
||||||
pub struct LayoutLine {
|
pub struct LayoutLine {
|
||||||
/// Width of the line
|
/// Width of the line
|
||||||
|
|
|
||||||
22
src/shape.rs
22
src/shape.rs
|
|
@ -9,7 +9,7 @@ use unicode_script::{Script, UnicodeScript};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
use crate::fallback::FontFallbackIter;
|
use crate::fallback::FontFallbackIter;
|
||||||
use crate::{Align, AttrsList, CacheKey, Color, Font, FontSystem, LayoutGlyph, LayoutLine, Wrap};
|
use crate::{Align, AttrsList, Color, Font, FontSystem, LayoutGlyph, LayoutLine, Wrap};
|
||||||
|
|
||||||
/// The shaping strategy of some text.
|
/// The shaping strategy of some text.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
|
@ -332,26 +332,18 @@ impl ShapeGlyph {
|
||||||
w: f32,
|
w: f32,
|
||||||
level: unicode_bidi::Level,
|
level: unicode_bidi::Level,
|
||||||
) -> LayoutGlyph {
|
) -> LayoutGlyph {
|
||||||
let x_offset = font_size * self.x_offset;
|
|
||||||
let y_offset = font_size * self.y_offset;
|
|
||||||
|
|
||||||
let (cache_key, x_int, y_int) = CacheKey::new(
|
|
||||||
self.font_id,
|
|
||||||
self.glyph_id,
|
|
||||||
font_size,
|
|
||||||
(x + x_offset, y - y_offset),
|
|
||||||
);
|
|
||||||
LayoutGlyph {
|
LayoutGlyph {
|
||||||
start: self.start,
|
start: self.start,
|
||||||
end: self.end,
|
end: self.end,
|
||||||
|
font_size,
|
||||||
|
font_id: self.font_id,
|
||||||
|
glyph_id: self.glyph_id,
|
||||||
x,
|
x,
|
||||||
|
y,
|
||||||
w,
|
w,
|
||||||
level,
|
level,
|
||||||
cache_key,
|
x_offset: self.x_offset,
|
||||||
x_offset,
|
y_offset: self.y_offset,
|
||||||
y_offset,
|
|
||||||
x_int,
|
|
||||||
y_int,
|
|
||||||
color_opt: self.color_opt,
|
color_opt: self.color_opt,
|
||||||
metadata: self.metadata,
|
metadata: self.metadata,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue