Merge pull request #72 from hecrj/logical-units
Use `f32` instead of `i32` for lengths
This commit is contained in:
commit
3135122f6b
15 changed files with 207 additions and 155 deletions
|
|
@ -14,7 +14,7 @@ use cosmic::{
|
|||
use cosmic_text::{
|
||||
Align, Attrs, AttrsList, Buffer, Edit, FontSystem, Metrics, SyntaxEditor, SyntaxSystem, Wrap,
|
||||
};
|
||||
use std::{env, fs, path::PathBuf, sync::Mutex};
|
||||
use std::{env, fmt, fs, path::PathBuf, sync::Mutex};
|
||||
|
||||
use self::text::text;
|
||||
mod text;
|
||||
|
|
@ -27,14 +27,52 @@ lazy_static::lazy_static! {
|
|||
static ref SYNTAX_SYSTEM: SyntaxSystem = SyntaxSystem::new();
|
||||
}
|
||||
|
||||
static FONT_SIZES: &'static [Metrics] = &[
|
||||
Metrics::new(10, 14), // Caption
|
||||
Metrics::new(14, 20), // Body
|
||||
Metrics::new(20, 28), // Title 4
|
||||
Metrics::new(24, 32), // Title 3
|
||||
Metrics::new(28, 36), // Title 2
|
||||
Metrics::new(32, 44), // Title 1
|
||||
];
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FontSize {
|
||||
Caption,
|
||||
Body,
|
||||
Title4,
|
||||
Title3,
|
||||
Title2,
|
||||
Title1,
|
||||
}
|
||||
|
||||
impl FontSize {
|
||||
pub fn all() -> &'static [Self] {
|
||||
&[
|
||||
Self::Caption,
|
||||
Self::Body,
|
||||
Self::Title4,
|
||||
Self::Title3,
|
||||
Self::Title2,
|
||||
Self::Title1,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn to_metrics(self) -> Metrics {
|
||||
match self {
|
||||
Self::Caption => Metrics::new(10.0, 14.0), // Caption
|
||||
Self::Body => Metrics::new(14.0, 20.0), // Body
|
||||
Self::Title4 => Metrics::new(20.0, 28.0), // Title 4
|
||||
Self::Title3 => Metrics::new(24.0, 32.0), // Title 3
|
||||
Self::Title2 => Metrics::new(28.0, 36.0), // Title 2
|
||||
Self::Title1 => Metrics::new(32.0, 44.0), // Title 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FontSize {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Caption => write!(f, "Caption"),
|
||||
Self::Body => write!(f, "Body"),
|
||||
Self::Title4 => write!(f, "Title 4"),
|
||||
Self::Title3 => write!(f, "Title 3"),
|
||||
Self::Title2 => write!(f, "Title 2"),
|
||||
Self::Title1 => write!(f, "Title 1"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static WRAP_MODE: &'static [Wrap] = &[Wrap::None, Wrap::Glyph, Wrap::Word];
|
||||
|
||||
|
|
@ -50,6 +88,7 @@ pub struct Window {
|
|||
theme: Theme,
|
||||
path_opt: Option<PathBuf>,
|
||||
attrs: Attrs<'static>,
|
||||
font_size: FontSize,
|
||||
#[cfg(not(feature = "vi"))]
|
||||
editor: Mutex<SyntaxEditor<'static>>,
|
||||
#[cfg(feature = "vi")]
|
||||
|
|
@ -64,7 +103,7 @@ pub enum Message {
|
|||
Bold(bool),
|
||||
Italic(bool),
|
||||
Monospaced(bool),
|
||||
MetricsChanged(Metrics),
|
||||
FontSizeChanged(FontSize),
|
||||
WrapChanged(Wrap),
|
||||
AlignmentChanged(Align),
|
||||
ThemeChanged(&'static str),
|
||||
|
|
@ -98,7 +137,7 @@ impl Application for Window {
|
|||
.family(cosmic_text::Family::Monospace);
|
||||
|
||||
let mut editor = SyntaxEditor::new(
|
||||
Buffer::new(&FONT_SYSTEM, FONT_SIZES[1 /* Body */]),
|
||||
Buffer::new(&FONT_SYSTEM, FontSize::Body.to_metrics()),
|
||||
&SYNTAX_SYSTEM,
|
||||
"base16-eighties.dark",
|
||||
)
|
||||
|
|
@ -111,6 +150,7 @@ impl Application for Window {
|
|||
|
||||
let mut window = Window {
|
||||
theme: Theme::Dark,
|
||||
font_size: FontSize::Body,
|
||||
path_opt: None,
|
||||
attrs,
|
||||
editor: Mutex::new(editor),
|
||||
|
|
@ -195,9 +235,11 @@ impl Application for Window {
|
|||
let mut editor = self.editor.lock().unwrap();
|
||||
update_attrs(&mut *editor, self.attrs);
|
||||
}
|
||||
Message::MetricsChanged(metrics) => {
|
||||
Message::FontSizeChanged(font_size) => {
|
||||
self.font_size = font_size;
|
||||
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
editor.buffer_mut().set_metrics(metrics);
|
||||
editor.buffer_mut().set_metrics(font_size.to_metrics());
|
||||
}
|
||||
Message::WrapChanged(wrap) => {
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
|
|
@ -245,9 +287,9 @@ impl Application for Window {
|
|||
let font_size_picker = {
|
||||
let editor = self.editor.lock().unwrap();
|
||||
pick_list(
|
||||
FONT_SIZES,
|
||||
Some(editor.buffer().metrics()),
|
||||
Message::MetricsChanged,
|
||||
FontSize::all(),
|
||||
Some(self.font_size),
|
||||
Message::FontSizeChanged,
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl Text {
|
|||
|
||||
let text = Self {
|
||||
line,
|
||||
metrics: Metrics::new(14, 20),
|
||||
metrics: Metrics::new(14.0, 20.0),
|
||||
};
|
||||
|
||||
log::debug!("Text::new in {:?}", instant.elapsed());
|
||||
|
|
@ -99,17 +99,17 @@ where
|
|||
//TODO: can we cache this?
|
||||
let layout_lines = shape.layout(
|
||||
self.metrics.font_size,
|
||||
limits.max().width as i32,
|
||||
limits.max().width,
|
||||
self.line.wrap(),
|
||||
self.line.align(),
|
||||
);
|
||||
|
||||
let mut width = 0;
|
||||
let mut height = 0;
|
||||
let mut width = 0.0f32;
|
||||
let mut height = 0.0f32;
|
||||
|
||||
for layout_line in layout_lines {
|
||||
for glyph in layout_line.glyphs.iter() {
|
||||
width = cmp::max(width, (glyph.x + glyph.w) as i32 + 1);
|
||||
width = width.max((glyph.x + glyph.w) + 1.0);
|
||||
}
|
||||
height += self.metrics.line_height;
|
||||
}
|
||||
|
|
@ -156,8 +156,8 @@ where
|
|||
cmp::max(0, cmp::min(255, (appearance.text_color.a * 255.0) as i32)) as u8,
|
||||
);
|
||||
|
||||
let layout_w = layout.bounds().width as i32;
|
||||
let layout_h = layout.bounds().height as i32;
|
||||
let layout_w = layout.bounds().width;
|
||||
let layout_h = layout.bounds().height;
|
||||
|
||||
let shape = self.line.shape_opt().as_ref().unwrap();
|
||||
|
||||
|
|
@ -185,8 +185,8 @@ where
|
|||
|
||||
cache.with_pixels(cache_key, glyph_color, |pixel_x, pixel_y, color| {
|
||||
let x = x_int + pixel_x;
|
||||
let y = line_y + y_int + pixel_y;
|
||||
draw_pixel(&mut pixels, layout_w, layout_h, x, y, color);
|
||||
let y = line_y as i32 + y_int + pixel_y;
|
||||
draw_pixel(&mut pixels, layout_w as i32, layout_h as i32, x, y, color);
|
||||
});
|
||||
}
|
||||
line_y += self.metrics.line_height;
|
||||
|
|
|
|||
|
|
@ -160,10 +160,8 @@ where
|
|||
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
|
||||
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32)
|
||||
- self.padding.horizontal() as i32;
|
||||
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32)
|
||||
- self.padding.vertical() as i32;
|
||||
let view_w = viewport.width.min(layout.bounds().width) - self.padding.horizontal() as f32;
|
||||
let view_h = viewport.height.min(layout.bounds().height) - self.padding.vertical() as f32;
|
||||
editor.buffer_mut().set_size(view_w, view_h);
|
||||
|
||||
editor.shape_as_needed();
|
||||
|
|
@ -203,7 +201,7 @@ where
|
|||
),
|
||||
);
|
||||
} else {
|
||||
text::draw_pixel(&mut pixels, view_w, view_h, x, y, color);
|
||||
text::draw_pixel(&mut pixels, view_w as i32, view_h as i32, x, y, color);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ fn main() {
|
|||
let display_scale = match orbclient::get_display_size() {
|
||||
Ok((w, h)) => {
|
||||
log::info!("Display size: {}, {}", w, h);
|
||||
(h as i32 / 1600) + 1
|
||||
(h as f32 / 1600.0) + 1.0
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("Failed to get display size: {}", err);
|
||||
1
|
||||
1.0
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -45,17 +45,17 @@ fn main() {
|
|||
let syntax_system = SyntaxSystem::new();
|
||||
|
||||
let font_sizes = [
|
||||
Metrics::new(10, 14).scale(display_scale), // Caption
|
||||
Metrics::new(14, 20).scale(display_scale), // Body
|
||||
Metrics::new(20, 28).scale(display_scale), // Title 4
|
||||
Metrics::new(24, 32).scale(display_scale), // Title 3
|
||||
Metrics::new(28, 36).scale(display_scale), // Title 2
|
||||
Metrics::new(32, 44).scale(display_scale), // Title 1
|
||||
Metrics::new(10.0, 14.0).scale(display_scale), // Caption
|
||||
Metrics::new(14.0, 20.0).scale(display_scale), // Body
|
||||
Metrics::new(20.0, 28.0).scale(display_scale), // Title 4
|
||||
Metrics::new(24.0, 32.0).scale(display_scale), // Title 3
|
||||
Metrics::new(28.0, 36.0).scale(display_scale), // Title 2
|
||||
Metrics::new(32.0, 44.0).scale(display_scale), // Title 1
|
||||
];
|
||||
let font_size_default = 1; // Body
|
||||
let mut font_size_i = font_size_default;
|
||||
|
||||
let line_x = 8 * display_scale;
|
||||
let line_x = 8.0 * display_scale;
|
||||
|
||||
let mut editor = SyntaxEditor::new(
|
||||
Buffer::new(&font_system, font_sizes[font_size_i]),
|
||||
|
|
@ -69,7 +69,7 @@ fn main() {
|
|||
|
||||
editor
|
||||
.buffer_mut()
|
||||
.set_size(window.width() as i32 - line_x * 2, window.height() as i32);
|
||||
.set_size(window.width() as f32 - line_x * 2.0, window.height() as f32);
|
||||
|
||||
let attrs = Attrs::new().monospaced(true).family(Family::Monospace);
|
||||
match editor.load_text(&path, attrs) {
|
||||
|
|
@ -95,7 +95,13 @@ fn main() {
|
|||
|
||||
let fg = editor.foreground_color();
|
||||
editor.draw(&mut swash_cache, fg, |x, y, w, h, color| {
|
||||
window.rect(line_x + x, y, w, h, orbclient::Color { data: color.0 })
|
||||
window.rect(
|
||||
line_x as i32 + x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
orbclient::Color { data: color.0 },
|
||||
)
|
||||
});
|
||||
|
||||
// Draw scrollbar
|
||||
|
|
@ -177,7 +183,7 @@ fn main() {
|
|||
mouse_y = event.y;
|
||||
if mouse_left {
|
||||
editor.action(Action::Drag {
|
||||
x: mouse_x - line_x,
|
||||
x: mouse_x - line_x as i32,
|
||||
y: mouse_y,
|
||||
});
|
||||
|
||||
|
|
@ -197,7 +203,7 @@ fn main() {
|
|||
mouse_left = event.left;
|
||||
if mouse_left {
|
||||
editor.action(Action::Click {
|
||||
x: mouse_x - line_x,
|
||||
x: mouse_x - line_x as i32,
|
||||
y: mouse_y,
|
||||
});
|
||||
}
|
||||
|
|
@ -207,7 +213,7 @@ fn main() {
|
|||
EventOption::Resize(event) => {
|
||||
editor
|
||||
.buffer_mut()
|
||||
.set_size(event.width as i32 - line_x * 2, event.height as i32);
|
||||
.set_size(event.width as f32 - line_x * 2.0, event.height as f32);
|
||||
}
|
||||
EventOption::Scroll(event) => {
|
||||
editor.action(Action::Scroll {
|
||||
|
|
@ -221,7 +227,7 @@ fn main() {
|
|||
|
||||
if mouse_left && force_drag {
|
||||
editor.action(Action::Drag {
|
||||
x: mouse_x - line_x,
|
||||
x: mouse_x - line_x as i32,
|
||||
y: mouse_y,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ fn redraw(window: &mut Window, editor: &mut Editor<'_>, swash_cache: &mut SwashC
|
|||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let display_scale = 1;
|
||||
let display_scale = 1.0;
|
||||
let font_system = FontSystem::new();
|
||||
|
||||
let mut window = Window::new_flags(
|
||||
|
|
@ -45,17 +45,17 @@ fn main() {
|
|||
.unwrap();
|
||||
|
||||
let font_sizes = [
|
||||
Metrics::new(10, 14).scale(display_scale), // Caption
|
||||
Metrics::new(14, 20).scale(display_scale), // Body
|
||||
Metrics::new(20, 28).scale(display_scale), // Title 4
|
||||
Metrics::new(24, 32).scale(display_scale), // Title 3
|
||||
Metrics::new(28, 36).scale(display_scale), // Title 2
|
||||
Metrics::new(32, 44).scale(display_scale), // Title 1
|
||||
Metrics::new(10.0, 14.0).scale(display_scale), // Caption
|
||||
Metrics::new(14.0, 20.0).scale(display_scale), // Body
|
||||
Metrics::new(20.0, 28.0).scale(display_scale), // Title 4
|
||||
Metrics::new(24.0, 32.0).scale(display_scale), // Title 3
|
||||
Metrics::new(28.0, 36.0).scale(display_scale), // Title 2
|
||||
Metrics::new(32.0, 44.0).scale(display_scale), // Title 1
|
||||
];
|
||||
let font_size_default = 1; // Body
|
||||
|
||||
let mut buffer = Buffer::new(&font_system, font_sizes[font_size_default]);
|
||||
buffer.set_size(window.width() as i32, window.height() as i32);
|
||||
buffer.set_size(window.width() as f32, window.height() as f32);
|
||||
|
||||
let mut editor = Editor::new(buffer);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ fn main() {
|
|||
let display_scale = match orbclient::get_display_size() {
|
||||
Ok((w, h)) => {
|
||||
log::info!("Display size: {}, {}", w, h);
|
||||
(h as i32 / 1600) + 1
|
||||
(h as f32 / 1600.0) + 1.0
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("Failed to get display size: {}", err);
|
||||
1
|
||||
1.0
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -38,12 +38,12 @@ fn main() {
|
|||
|
||||
let mut editor = Editor::new(Buffer::new(
|
||||
&font_system,
|
||||
Metrics::new(32, 44).scale(display_scale),
|
||||
Metrics::new(32.0, 44.0).scale(display_scale),
|
||||
));
|
||||
|
||||
editor
|
||||
.buffer_mut()
|
||||
.set_size(window.width() as i32, window.height() as i32);
|
||||
.set_size(window.width() as f32, window.height() as f32);
|
||||
|
||||
let attrs = Attrs::new();
|
||||
let serif_attrs = attrs.family(Family::Serif);
|
||||
|
|
@ -211,7 +211,7 @@ fn main() {
|
|||
EventOption::Resize(resize) => {
|
||||
editor
|
||||
.buffer_mut()
|
||||
.set_size(resize.width as i32, resize.height as i32);
|
||||
.set_size(resize.width as f32, resize.height as f32);
|
||||
}
|
||||
EventOption::Quit(_) => process::exit(0),
|
||||
_ => (),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ fn main() {
|
|||
let mut swash_cache = SwashCache::new(&font_system);
|
||||
|
||||
// Text metrics indicate the font size and line height of a buffer
|
||||
let metrics = Metrics::new(14, 20);
|
||||
let metrics = Metrics::new(14.0, 20.0);
|
||||
|
||||
// A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
|
||||
let mut buffer = Buffer::new(&font_system, metrics);
|
||||
|
|
@ -20,7 +20,7 @@ fn main() {
|
|||
// Set a size for the text buffer, in pixels
|
||||
let width = 80u16;
|
||||
let height = 25u16;
|
||||
buffer.set_size(width as i32, height as i32);
|
||||
buffer.set_size(width as f32, height as f32);
|
||||
|
||||
// Attributes indicate what font to choose
|
||||
let attrs = Attrs::new();
|
||||
|
|
@ -39,7 +39,7 @@ fn main() {
|
|||
|
||||
// Clear buffer with black background
|
||||
for _y in 0..height {
|
||||
for _x in 0..buffer.size().0 {
|
||||
for _x in 0..(buffer.size().0 as i32) {
|
||||
print!(
|
||||
"{} {}",
|
||||
color::Bg(color::Rgb(0, 0, 0)),
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ pub struct LayoutRun<'a> {
|
|||
/// The array of layout glyphs to draw
|
||||
pub glyphs: &'a [LayoutGlyph],
|
||||
/// Y offset of line
|
||||
pub line_y: i32,
|
||||
pub line_y: f32,
|
||||
/// width of line
|
||||
pub line_w: f32,
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ pub struct LayoutRunIter<'a, 'b> {
|
|||
line_i: usize,
|
||||
layout_i: usize,
|
||||
remaining_len: usize,
|
||||
line_y: i32,
|
||||
line_y: f32,
|
||||
total_layout: i32,
|
||||
}
|
||||
|
||||
|
|
@ -192,16 +192,18 @@ impl<'a, 'b> LayoutRunIter<'a, 'b> {
|
|||
.sum();
|
||||
let top_cropped_layout_lines =
|
||||
total_layout_lines.saturating_sub(buffer.scroll.try_into().unwrap_or_default());
|
||||
let maximum_lines = buffer
|
||||
.height
|
||||
.checked_div(buffer.metrics.line_height)
|
||||
.unwrap_or_default();
|
||||
let maximum_lines = if buffer.metrics.line_height == 0.0 {
|
||||
0
|
||||
} else {
|
||||
(buffer.height / buffer.metrics.line_height) as i32
|
||||
};
|
||||
let bottom_cropped_layout_lines =
|
||||
if top_cropped_layout_lines > maximum_lines.try_into().unwrap_or_default() {
|
||||
maximum_lines.try_into().unwrap_or_default()
|
||||
} else {
|
||||
top_cropped_layout_lines
|
||||
};
|
||||
|
||||
Self {
|
||||
buffer,
|
||||
line_i: 0,
|
||||
|
|
@ -259,30 +261,30 @@ impl<'a, 'b> Iterator for LayoutRunIter<'a, 'b> {
|
|||
impl<'a, 'b> ExactSizeIterator for LayoutRunIter<'a, 'b> {}
|
||||
|
||||
/// Metrics of text
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
pub struct Metrics {
|
||||
/// Font size in pixels
|
||||
pub font_size: i32,
|
||||
pub font_size: f32,
|
||||
/// Line height in pixels
|
||||
pub line_height: i32,
|
||||
pub line_height: f32,
|
||||
}
|
||||
|
||||
impl Metrics {
|
||||
pub const fn new(font_size: i32, line_height: i32) -> Self {
|
||||
pub const fn new(font_size: f32, line_height: f32) -> Self {
|
||||
Self {
|
||||
font_size,
|
||||
line_height,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn scale(self, scale: i32) -> Self {
|
||||
pub fn scale(self, scale: f32) -> Self {
|
||||
Self {
|
||||
font_size: self.font_size * scale,
|
||||
line_height: self.line_height * scale,
|
||||
}
|
||||
}
|
||||
|
||||
fn y_offset(&self) -> i32 {
|
||||
fn y_offset(&self) -> f32 {
|
||||
self.font_size - self.line_height
|
||||
}
|
||||
}
|
||||
|
|
@ -299,8 +301,8 @@ pub struct Buffer<'a> {
|
|||
/// [BufferLine]s (or paragraphs) of text in the buffer
|
||||
pub lines: Vec<BufferLine>,
|
||||
metrics: Metrics,
|
||||
width: i32,
|
||||
height: i32,
|
||||
width: f32,
|
||||
height: f32,
|
||||
scroll: i32,
|
||||
/// True if a redraw is requires. Set to false after processing
|
||||
redraw: bool,
|
||||
|
|
@ -310,14 +312,14 @@ pub struct Buffer<'a> {
|
|||
impl<'a> Buffer<'a> {
|
||||
/// Create a new [`Buffer`] with the provided [`FontSystem`] and [`Metrics`]
|
||||
pub fn new(font_system: &'a FontSystem, metrics: Metrics) -> Self {
|
||||
assert_ne!(metrics.line_height, 0, "line height cannot be 0");
|
||||
assert_ne!(metrics.line_height, 0.0, "line height cannot be 0");
|
||||
|
||||
let mut buffer = Self {
|
||||
font_system,
|
||||
lines: Vec::new(),
|
||||
metrics,
|
||||
width: 0,
|
||||
height: 0,
|
||||
width: 0.0,
|
||||
height: 0.0,
|
||||
scroll: 0,
|
||||
redraw: false,
|
||||
wrap: Wrap::Word,
|
||||
|
|
@ -497,7 +499,7 @@ impl<'a> Buffer<'a> {
|
|||
/// Set the current [`Metrics`]
|
||||
pub fn set_metrics(&mut self, metrics: Metrics) {
|
||||
if metrics != self.metrics {
|
||||
assert_ne!(metrics.font_size, 0, "font size cannot be 0");
|
||||
assert_ne!(metrics.font_size, 0.0, "font size cannot be 0");
|
||||
self.metrics = metrics;
|
||||
self.relayout();
|
||||
self.shape_until_scroll();
|
||||
|
|
@ -519,14 +521,14 @@ impl<'a> Buffer<'a> {
|
|||
}
|
||||
|
||||
/// Get the current buffer dimensions (width, height)
|
||||
pub fn size(&self) -> (i32, i32) {
|
||||
pub fn size(&self) -> (f32, f32) {
|
||||
(self.width, self.height)
|
||||
}
|
||||
|
||||
/// Set the current buffer dimensions
|
||||
pub fn set_size(&mut self, width: i32, height: i32) {
|
||||
let clamped_width = width.max(0);
|
||||
let clamped_height = height.max(0);
|
||||
pub fn set_size(&mut self, width: f32, height: f32) {
|
||||
let clamped_width = width.max(0.0);
|
||||
let clamped_height = height.max(0.0);
|
||||
|
||||
if clamped_width != self.width || clamped_height != self.height {
|
||||
self.width = clamped_width;
|
||||
|
|
@ -551,7 +553,7 @@ impl<'a> Buffer<'a> {
|
|||
|
||||
/// Get the number of lines that can be viewed in the buffer
|
||||
pub fn visible_lines(&self) -> i32 {
|
||||
self.height / self.metrics.line_height
|
||||
(self.height / self.metrics.line_height) as i32
|
||||
}
|
||||
|
||||
/// Set text of buffer, using provided attributes for each line by default
|
||||
|
|
@ -588,7 +590,7 @@ impl<'a> Buffer<'a> {
|
|||
}
|
||||
|
||||
/// Convert x, y position to Cursor (hit detection)
|
||||
pub fn hit(&self, x: i32, y: i32) -> Option<Cursor> {
|
||||
pub fn hit(&self, x: f32, y: f32) -> Option<Cursor> {
|
||||
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
||||
let instant = std::time::Instant::now();
|
||||
|
||||
|
|
@ -616,12 +618,12 @@ impl<'a> Buffer<'a> {
|
|||
'hit: for (glyph_i, glyph) in run.glyphs.iter().enumerate() {
|
||||
if first_glyph {
|
||||
first_glyph = false;
|
||||
if (run.rtl && x > glyph.x as i32) || (!run.rtl && x < 0) {
|
||||
if (run.rtl && x > glyph.x) || (!run.rtl && x < 0.0) {
|
||||
new_cursor_glyph = 0;
|
||||
new_cursor_char = 0;
|
||||
}
|
||||
}
|
||||
if x >= glyph.x as i32 && x <= (glyph.x + glyph.w) as i32 {
|
||||
if x >= glyph.x && x <= glyph.x + glyph.w {
|
||||
new_cursor_glyph = glyph_i;
|
||||
|
||||
let cluster = &run.text[glyph.start..glyph.end];
|
||||
|
|
@ -629,10 +631,10 @@ impl<'a> Buffer<'a> {
|
|||
let mut egc_x = glyph.x;
|
||||
let egc_w = glyph.w / (total as f32);
|
||||
for (egc_i, egc) in cluster.grapheme_indices(true) {
|
||||
if x >= egc_x as i32 && x <= (egc_x + egc_w) as i32 {
|
||||
if x >= egc_x && x <= egc_x + egc_w {
|
||||
new_cursor_char = egc_i;
|
||||
|
||||
let right_half = x >= (egc_x + egc_w / 2.0) as i32;
|
||||
let right_half = x >= egc_x + egc_w / 2.0;
|
||||
if right_half != glyph.level.is_rtl() {
|
||||
// If clicking on last half of glyph, move cursor past glyph
|
||||
new_cursor_char += egc.len();
|
||||
|
|
@ -643,7 +645,7 @@ impl<'a> Buffer<'a> {
|
|||
egc_x += egc_w;
|
||||
}
|
||||
|
||||
let right_half = x >= (glyph.x + glyph.w / 2.0) as i32;
|
||||
let right_half = x >= glyph.x + glyph.w / 2.0;
|
||||
if right_half != glyph.level.is_rtl() {
|
||||
// If clicking on last half of glyph, move cursor past glyph
|
||||
new_cursor_char = cluster.len();
|
||||
|
|
@ -704,7 +706,7 @@ impl<'a> Buffer<'a> {
|
|||
};
|
||||
|
||||
cache.with_pixels(cache_key, glyph_color, |x, y, color| {
|
||||
f(x_int + x, run.line_y + y_int + y, 1, 1, color);
|
||||
f(x_int + x, run.line_y as i32 + y_int + y, 1, 1, color);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,8 +184,8 @@ impl BufferLine {
|
|||
pub fn layout(
|
||||
&mut self,
|
||||
font_system: &FontSystem,
|
||||
font_size: i32,
|
||||
width: i32,
|
||||
font_size: f32,
|
||||
width: f32,
|
||||
wrap: Wrap,
|
||||
) -> &[LayoutLine] {
|
||||
if self.layout_opt.is_none() {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ pub struct CacheKey {
|
|||
pub font_id: fontdb::ID,
|
||||
/// Glyph ID
|
||||
pub glyph_id: u16,
|
||||
/// Font size in pixels
|
||||
pub font_size: i32,
|
||||
/// `f32` bits of font size
|
||||
pub font_size_bits: u32,
|
||||
/// Binning of fractional X offset
|
||||
pub x_bin: SubpixelBin,
|
||||
/// Binning of fractional Y offset
|
||||
|
|
@ -19,7 +19,7 @@ impl CacheKey {
|
|||
pub fn new(
|
||||
font_id: fontdb::ID,
|
||||
glyph_id: u16,
|
||||
font_size: i32,
|
||||
font_size: f32,
|
||||
pos: (f32, f32),
|
||||
) -> (Self, i32, i32) {
|
||||
let (x, x_bin) = SubpixelBin::new(pos.0);
|
||||
|
|
@ -28,7 +28,7 @@ impl CacheKey {
|
|||
Self {
|
||||
font_id,
|
||||
glyph_id,
|
||||
font_size,
|
||||
font_size_bits: font_size.to_bits(),
|
||||
x_bin,
|
||||
y_bin,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -424,14 +424,14 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
self.buffer.set_redraw(true);
|
||||
}
|
||||
Action::PageUp => {
|
||||
self.action(Action::Vertical(-self.buffer.size().1));
|
||||
self.action(Action::Vertical(-self.buffer.size().1 as i32));
|
||||
}
|
||||
Action::PageDown => {
|
||||
self.action(Action::Vertical(self.buffer.size().1));
|
||||
self.action(Action::Vertical(self.buffer.size().1 as i32));
|
||||
}
|
||||
Action::Vertical(px) => {
|
||||
// TODO more efficient
|
||||
let lines = px / self.buffer.metrics().line_height;
|
||||
let lines = px / self.buffer.metrics().line_height as i32;
|
||||
if lines < 0 {
|
||||
for _ in 0..-lines {
|
||||
self.action(Action::Up);
|
||||
|
|
@ -541,7 +541,7 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
Action::Click { x, y } => {
|
||||
self.select_opt = None;
|
||||
|
||||
if let Some(new_cursor) = self.buffer.hit(x, y) {
|
||||
if let Some(new_cursor) = self.buffer.hit(x as f32, y as f32) {
|
||||
if new_cursor != self.cursor {
|
||||
self.cursor = new_cursor;
|
||||
self.buffer.set_redraw(true);
|
||||
|
|
@ -554,7 +554,7 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
self.buffer.set_redraw(true);
|
||||
}
|
||||
|
||||
if let Some(new_cursor) = self.buffer.hit(x, y) {
|
||||
if let Some(new_cursor) = self.buffer.hit(x as f32, y as f32) {
|
||||
if new_cursor != self.cursor {
|
||||
self.cursor = new_cursor;
|
||||
self.buffer.set_redraw(true);
|
||||
|
|
@ -753,7 +753,7 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
} else if let Some((min, max)) = range_opt.take() {
|
||||
f(
|
||||
min,
|
||||
line_y - font_size,
|
||||
(line_y - font_size) as i32,
|
||||
cmp::max(0, max - min) as u32,
|
||||
line_height as u32,
|
||||
Color::rgba(color.r(), color.g(), color.b(), 0x33),
|
||||
|
|
@ -765,7 +765,7 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
|
||||
if run.glyphs.is_empty() && end.line > line_i {
|
||||
// Highlight all of internal empty lines
|
||||
range_opt = Some((0, self.buffer.size().0));
|
||||
range_opt = Some((0, self.buffer.size().0 as i32));
|
||||
}
|
||||
|
||||
if let Some((mut min, mut max)) = range_opt.take() {
|
||||
|
|
@ -774,12 +774,12 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
if run.rtl {
|
||||
min = 0;
|
||||
} else {
|
||||
max = self.buffer.size().0;
|
||||
max = self.buffer.size().0 as i32;
|
||||
}
|
||||
}
|
||||
f(
|
||||
min,
|
||||
line_y - font_size,
|
||||
(line_y - font_size) as i32,
|
||||
cmp::max(0, max - min) as u32,
|
||||
line_height as u32,
|
||||
Color::rgba(color.r(), color.g(), color.b(), 0x33),
|
||||
|
|
@ -815,7 +815,7 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
},
|
||||
};
|
||||
|
||||
f(x, line_y - font_size, 1, line_height as u32, color);
|
||||
f(x, (line_y - font_size) as i32, 1, line_height as u32, color);
|
||||
}
|
||||
|
||||
for glyph in run.glyphs.iter() {
|
||||
|
|
@ -827,7 +827,7 @@ impl<'a> Edit<'a> for Editor<'a> {
|
|||
};
|
||||
|
||||
cache.with_pixels(cache_key, glyph_color, |x, y, color| {
|
||||
f(x_int + x, line_y + y_int + y, 1, 1, color);
|
||||
f(x_int + x, line_y as i32 + y_int + y, 1, 1, color);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ impl<'a> Edit<'a> for ViEditor<'a> {
|
|||
|
||||
let cursor_glyph_opt = |cursor: &Cursor| -> Option<(usize, f32, f32)> {
|
||||
//TODO: better calculation of width
|
||||
let default_width = (font_size as f32) / 2.0;
|
||||
let default_width = font_size / 2.0;
|
||||
if cursor.line == line_i {
|
||||
for (glyph_i, glyph) in run.glyphs.iter().enumerate() {
|
||||
if cursor.index >= glyph.start && cursor.index < glyph.end {
|
||||
|
|
@ -312,7 +312,7 @@ impl<'a> Edit<'a> for ViEditor<'a> {
|
|||
} else if let Some((min, max)) = range_opt.take() {
|
||||
f(
|
||||
min,
|
||||
line_y - font_size,
|
||||
(line_y - font_size) as i32,
|
||||
cmp::max(0, max - min) as u32,
|
||||
line_height as u32,
|
||||
Color::rgba(color.r(), color.g(), color.b(), 0x33),
|
||||
|
|
@ -324,7 +324,7 @@ impl<'a> Edit<'a> for ViEditor<'a> {
|
|||
|
||||
if run.glyphs.is_empty() && end.line > line_i {
|
||||
// Highlight all of internal empty lines
|
||||
range_opt = Some((0, self.buffer().size().0));
|
||||
range_opt = Some((0, self.buffer().size().0 as i32));
|
||||
}
|
||||
|
||||
if let Some((mut min, mut max)) = range_opt.take() {
|
||||
|
|
@ -333,12 +333,12 @@ impl<'a> Edit<'a> for ViEditor<'a> {
|
|||
if run.rtl {
|
||||
min = 0;
|
||||
} else {
|
||||
max = self.buffer().size().0;
|
||||
max = self.buffer().size().0 as i32;
|
||||
}
|
||||
}
|
||||
f(
|
||||
min,
|
||||
line_y - font_size,
|
||||
(line_y - font_size) as i32,
|
||||
cmp::max(0, max - min) as u32,
|
||||
line_height as u32,
|
||||
Color::rgba(color.r(), color.g(), color.b(), 0x33),
|
||||
|
|
@ -397,13 +397,19 @@ impl<'a> Edit<'a> for ViEditor<'a> {
|
|||
let right_x = cmp::max(start_x, end_x);
|
||||
f(
|
||||
left_x,
|
||||
line_y - font_size,
|
||||
(line_y - font_size) as i32,
|
||||
(right_x - left_x) as u32,
|
||||
line_height as u32,
|
||||
Color::rgba(color.r(), color.g(), color.b(), 0x33),
|
||||
);
|
||||
} else {
|
||||
f(start_x, line_y - font_size, 1, line_height as u32, color);
|
||||
f(
|
||||
start_x,
|
||||
(line_y - font_size) as i32,
|
||||
1,
|
||||
line_height as u32,
|
||||
color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -416,7 +422,7 @@ impl<'a> Edit<'a> for ViEditor<'a> {
|
|||
};
|
||||
|
||||
cache.with_pixels(cache_key, glyph_color, |x, y, color| {
|
||||
f(x_int + x, line_y + y_int + y, 1, 1, color)
|
||||
f(x_int + x, line_y as i32 + y_int + y, 1, 1, color);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@
|
|||
//! let mut swash_cache = SwashCache::new(&font_system);
|
||||
//!
|
||||
//! // Text metrics indicate the font size and line height of a buffer
|
||||
//! let metrics = Metrics::new(14, 20);
|
||||
//! let metrics = Metrics::new(14.0, 20.0);
|
||||
//!
|
||||
//! // A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
|
||||
//! let mut buffer = Buffer::new(&font_system, metrics);
|
||||
//!
|
||||
//! // Set a size for the text buffer, in pixels
|
||||
//! buffer.set_size(80, 25);
|
||||
//! buffer.set_size(80.0, 25.0);
|
||||
//!
|
||||
//! // Attributes indicate what font to choose
|
||||
//! let attrs = Attrs::new();
|
||||
|
|
|
|||
68
src/shape.rs
68
src/shape.rs
|
|
@ -237,14 +237,14 @@ pub struct ShapeGlyph {
|
|||
impl ShapeGlyph {
|
||||
fn layout(
|
||||
&self,
|
||||
font_size: i32,
|
||||
font_size: f32,
|
||||
x: f32,
|
||||
y: f32,
|
||||
w: f32,
|
||||
level: unicode_bidi::Level,
|
||||
) -> LayoutGlyph {
|
||||
let x_offset = font_size as f32 * self.x_offset;
|
||||
let y_offset = font_size as f32 * self.y_offset;
|
||||
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,
|
||||
|
|
@ -608,8 +608,8 @@ impl ShapeLine {
|
|||
|
||||
pub fn layout(
|
||||
&self,
|
||||
font_size: i32,
|
||||
line_width: i32,
|
||||
font_size: f32,
|
||||
line_width: f32,
|
||||
wrap: Wrap,
|
||||
align: Option<Align>,
|
||||
) -> Vec<LayoutLine> {
|
||||
|
|
@ -637,8 +637,8 @@ impl ShapeLine {
|
|||
// let mut vl_range_of_spans = Vec::with_capacity(1);
|
||||
let mut vl_range_of_spans: Vec<VisualLine> = Vec::with_capacity(1);
|
||||
|
||||
let start_x = if self.rtl { line_width as f32 } else { 0.0 };
|
||||
let end_x = if self.rtl { 0.0 } else { line_width as f32 };
|
||||
let start_x = if self.rtl { line_width } else { 0.0 };
|
||||
let end_x = if self.rtl { 0.0 } else { line_width };
|
||||
let mut x = start_x;
|
||||
let mut y;
|
||||
|
||||
|
|
@ -655,7 +655,7 @@ impl ShapeLine {
|
|||
.push((span_index, (0, 0), (span.words.len(), 0)));
|
||||
}
|
||||
} else {
|
||||
let mut fit_x = line_width as f32;
|
||||
let mut fit_x = line_width;
|
||||
for (span_index, span) in self.spans.iter().enumerate() {
|
||||
let mut word_ranges = Vec::new();
|
||||
let mut word_range_width = 0.;
|
||||
|
|
@ -666,7 +666,7 @@ impl ShapeLine {
|
|||
// incongruent directions
|
||||
let mut fitting_start = (span.words.len(), 0);
|
||||
for (i, word) in span.words.iter().enumerate().rev() {
|
||||
let word_size = font_size as f32 * word.x_advance;
|
||||
let word_size = font_size * word.x_advance;
|
||||
if fit_x - word_size >= 0. {
|
||||
// fits
|
||||
fit_x -= word_size;
|
||||
|
|
@ -677,7 +677,7 @@ impl ShapeLine {
|
|||
continue;
|
||||
} else if wrap == Wrap::Glyph {
|
||||
for (glyph_i, glyph) in word.glyphs.iter().enumerate().rev() {
|
||||
let glyph_size = font_size as f32 * glyph.x_advance;
|
||||
let glyph_size = font_size * glyph.x_advance;
|
||||
if fit_x - glyph_size >= 0. {
|
||||
fit_x -= glyph_size;
|
||||
word_range_width += glyph_size;
|
||||
|
|
@ -690,7 +690,7 @@ impl ShapeLine {
|
|||
number_of_blanks,
|
||||
));
|
||||
number_of_blanks = 0;
|
||||
fit_x = line_width as f32 - glyph_size;
|
||||
fit_x = line_width - glyph_size;
|
||||
word_range_width = glyph_size;
|
||||
fitting_start = (i, glyph_i + 1);
|
||||
}
|
||||
|
|
@ -706,8 +706,7 @@ impl ShapeLine {
|
|||
// previous word if it's a whitespace
|
||||
if previous_word.blank {
|
||||
number_of_blanks -= 1;
|
||||
prev_word_width =
|
||||
Some(previous_word.x_advance * font_size as f32);
|
||||
prev_word_width = Some(previous_word.x_advance * font_size);
|
||||
}
|
||||
}
|
||||
if let Some(width) = prev_word_width {
|
||||
|
|
@ -727,11 +726,11 @@ impl ShapeLine {
|
|||
}
|
||||
number_of_blanks = 0;
|
||||
if word.blank {
|
||||
fit_x = line_width as f32;
|
||||
fit_x = line_width;
|
||||
word_range_width = 0.;
|
||||
fitting_start = (i + 1, 0);
|
||||
} else {
|
||||
fit_x = line_width as f32 - word_size;
|
||||
fit_x = line_width - word_size;
|
||||
word_range_width = word_size;
|
||||
fitting_start = (i + 1, 0);
|
||||
}
|
||||
|
|
@ -742,7 +741,7 @@ impl ShapeLine {
|
|||
// congruent direction
|
||||
let mut fitting_start = (0, 0);
|
||||
for (i, word) in span.words.iter().enumerate() {
|
||||
let word_size = font_size as f32 * word.x_advance;
|
||||
let word_size = font_size * word.x_advance;
|
||||
if fit_x - word_size >= 0. {
|
||||
// fits
|
||||
fit_x -= word_size;
|
||||
|
|
@ -753,7 +752,7 @@ impl ShapeLine {
|
|||
continue;
|
||||
} else if wrap == Wrap::Glyph {
|
||||
for (glyph_i, glyph) in word.glyphs.iter().enumerate() {
|
||||
let glyph_size = font_size as f32 * glyph.x_advance;
|
||||
let glyph_size = font_size * glyph.x_advance;
|
||||
if fit_x - glyph_size >= 0. {
|
||||
fit_x -= glyph_size;
|
||||
word_range_width += glyph_size;
|
||||
|
|
@ -766,7 +765,7 @@ impl ShapeLine {
|
|||
number_of_blanks,
|
||||
));
|
||||
number_of_blanks = 0;
|
||||
fit_x = line_width as f32 - glyph_size;
|
||||
fit_x = line_width - glyph_size;
|
||||
word_range_width = glyph_size;
|
||||
fitting_start = (i, glyph_i);
|
||||
}
|
||||
|
|
@ -782,8 +781,7 @@ impl ShapeLine {
|
|||
// previous word if it's a whitespace
|
||||
if previous_word.blank {
|
||||
number_of_blanks -= 1;
|
||||
prev_word_width =
|
||||
Some(previous_word.x_advance * font_size as f32);
|
||||
prev_word_width = Some(previous_word.x_advance * font_size);
|
||||
}
|
||||
}
|
||||
if let Some(width) = prev_word_width {
|
||||
|
|
@ -804,11 +802,11 @@ impl ShapeLine {
|
|||
number_of_blanks = 0;
|
||||
|
||||
if word.blank {
|
||||
fit_x = line_width as f32;
|
||||
fit_x = line_width;
|
||||
word_range_width = 0.;
|
||||
fitting_start = (i + 1, 0);
|
||||
} else {
|
||||
fit_x = line_width as f32 - word_size;
|
||||
fit_x = line_width - word_size;
|
||||
word_range_width = word_size;
|
||||
fitting_start = (i, 0);
|
||||
}
|
||||
|
|
@ -872,7 +870,7 @@ impl ShapeLine {
|
|||
} else {
|
||||
x += word_range_width;
|
||||
}
|
||||
if word_range_width > line_width as f32 {
|
||||
if word_range_width > line_width {
|
||||
// single word is bigger than line_width
|
||||
vl_range_of_spans.push(current_visual_line);
|
||||
current_visual_line = VisualLine::default();
|
||||
|
|
@ -895,15 +893,15 @@ impl ShapeLine {
|
|||
x = start_x;
|
||||
y = 0.;
|
||||
let alignment_correction = match (align, self.rtl) {
|
||||
(Align::Left, true) => line_width as f32 - visual_line.w,
|
||||
(Align::Left, true) => line_width - visual_line.w,
|
||||
(Align::Left, false) => 0.,
|
||||
(Align::Right, true) => 0.,
|
||||
(Align::Right, false) => line_width as f32 - visual_line.w,
|
||||
(Align::Center, _) => (line_width as f32 - visual_line.w) / 2.0,
|
||||
(Align::Right, false) => line_width - visual_line.w,
|
||||
(Align::Center, _) => (line_width - visual_line.w) / 2.0,
|
||||
(Align::Justified, _) => {
|
||||
// Don't justify the last line in a paragraph.
|
||||
if visual_line.spaces > 0 && index != number_of_visual_lines - 1 {
|
||||
(line_width as f32 - visual_line.w) / visual_line.spaces as f32
|
||||
(line_width - visual_line.w) / visual_line.spaces as f32
|
||||
} else {
|
||||
0.
|
||||
}
|
||||
|
|
@ -927,8 +925,8 @@ impl ShapeLine {
|
|||
[*starting_glyph..*ending_glyph]
|
||||
.iter()
|
||||
{
|
||||
let x_advance = font_size as f32 * glyph.x_advance;
|
||||
let y_advance = font_size as f32 * glyph.y_advance;
|
||||
let x_advance = font_size * glyph.x_advance;
|
||||
let y_advance = font_size * glyph.y_advance;
|
||||
x -= x_advance;
|
||||
if word_blank && align == Align::Justified {
|
||||
x -= alignment_correction;
|
||||
|
|
@ -958,8 +956,8 @@ impl ShapeLine {
|
|||
|
||||
let word_blank = word.blank;
|
||||
for glyph in &word.glyphs[g1..g2] {
|
||||
let x_advance = font_size as f32 * glyph.x_advance;
|
||||
let y_advance = font_size as f32 * glyph.y_advance;
|
||||
let x_advance = font_size * glyph.x_advance;
|
||||
let y_advance = font_size * glyph.y_advance;
|
||||
x -= x_advance;
|
||||
if word_blank && align == Align::Justified {
|
||||
x -= alignment_correction;
|
||||
|
|
@ -1002,8 +1000,8 @@ impl ShapeLine {
|
|||
[*starting_glyph..*ending_glyph]
|
||||
.iter()
|
||||
{
|
||||
let x_advance = font_size as f32 * glyph.x_advance;
|
||||
let y_advance = font_size as f32 * glyph.y_advance;
|
||||
let x_advance = font_size * glyph.x_advance;
|
||||
let y_advance = font_size * glyph.y_advance;
|
||||
if word_blank && align == Align::Justified {
|
||||
glyphs.push(glyph.layout(
|
||||
font_size,
|
||||
|
|
@ -1033,8 +1031,8 @@ impl ShapeLine {
|
|||
|
||||
let word_blank = word.blank;
|
||||
for glyph in &word.glyphs[g1..g2] {
|
||||
let x_advance = font_size as f32 * glyph.x_advance;
|
||||
let y_advance = font_size as f32 * glyph.y_advance;
|
||||
let x_advance = font_size * glyph.x_advance;
|
||||
let y_advance = font_size * glyph.y_advance;
|
||||
if word_blank && align == Align::Justified {
|
||||
glyphs.push(glyph.layout(
|
||||
font_size,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ fn swash_image(
|
|||
// Build the scaler
|
||||
let mut scaler = context
|
||||
.builder(font.as_swash())
|
||||
.size(cache_key.font_size as f32)
|
||||
.size(f32::from_bits(cache_key.font_size_bits))
|
||||
.hint(true)
|
||||
.build();
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ fn swash_outline_commands(
|
|||
// Build the scaler
|
||||
let mut scaler = context
|
||||
.builder(font.as_swash())
|
||||
.size(cache_key.font_size as f32)
|
||||
.size(f32::from_bits(cache_key.font_size_bits))
|
||||
.build();
|
||||
|
||||
// Scale the outline
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue