From a07a6190548c8e40a55f6b7761387047ff1bf6ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Nov 2025 23:18:30 +0100 Subject: [PATCH] Add `set_hinting` method to `Buffer` --- benches/layout.rs | 2 +- benches/text_shaping_benchmarks.rs | 10 ++++---- examples/editor-test/src/main.rs | 8 ++----- examples/editor/src/main.rs | 5 ++-- examples/multiview/src/main.rs | 4 ++-- examples/rich-text/src/main.rs | 7 ++---- examples/terminal/src/main.rs | 4 ++-- src/buffer.rs | 38 ++++++++++++++++++++---------- src/buffer_line.rs | 4 ++-- src/lib.rs | 4 ++-- tests/common/mod.rs | 6 ++--- tests/editor_modified_state.rs | 4 ++-- tests/wrap_stability.rs | 2 +- tests/wrap_word_fallback.rs | 4 ++-- 14 files changed, 54 insertions(+), 48 deletions(-) diff --git a/benches/layout.rs b/benches/layout.rs index 3600d69..d41dc46 100644 --- a/benches/layout.rs +++ b/benches/layout.rs @@ -9,7 +9,7 @@ fn load_font_system(c: &mut Criterion) { fn layout(c: &mut Criterion) { let mut fs = ct::FontSystem::new(); - let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(10.0, 10.0), ct::Hinting::Disabled); + let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(10.0, 10.0)); buffer.set_size(&mut fs, Some(80.0), None); for (wrap_name, wrap) in &[ diff --git a/benches/text_shaping_benchmarks.rs b/benches/text_shaping_benchmarks.rs index 6f06192..097b552 100644 --- a/benches/text_shaping_benchmarks.rs +++ b/benches/text_shaping_benchmarks.rs @@ -4,7 +4,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn bench_ascii_fast_path(c: &mut Criterion) { let mut fs = ct::FontSystem::new(); - let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0), ct::Hinting::Disabled); + let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0)); buffer.set_size(&mut fs, Some(500.0), None); let ascii_text = "Pure ASCII text for BidiParagraphs optimization testing.\n".repeat(50); @@ -25,7 +25,7 @@ fn bench_ascii_fast_path(c: &mut Criterion) { fn bench_bidi_processing(c: &mut Criterion) { let mut fs = ct::FontSystem::new(); - let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0), ct::Hinting::Disabled); + let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0)); buffer.set_size(&mut fs, Some(500.0), None); let bidi_text = "Mixed English and العربية النص العربي text for BiDi testing.\nThis tests adjust_levels and combined BiDi optimizations.\n".repeat(30); @@ -46,7 +46,7 @@ fn bench_bidi_processing(c: &mut Criterion) { fn bench_lang_mixed(c: &mut Criterion) { let mut fs = ct::FontSystem::new(); - let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0), ct::Hinting::Disabled); + let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0)); buffer.set_size(&mut fs, Some(500.0), None); let bidi_text = include_str!("../sample/hello.txt"); @@ -69,7 +69,7 @@ fn bench_lang_mixed(c: &mut Criterion) { fn bench_layout_heavy(c: &mut Criterion) { let mut fs = ct::FontSystem::new(); - let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0), ct::Hinting::Disabled); + let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0)); buffer.set_size(&mut fs, Some(500.0), None); let layout_text = "This is a very long line that will wrap multiple times and stress the reorder optimization through intensive layout processing with comprehensive buffer reuse testing. ".repeat(30); @@ -90,7 +90,7 @@ fn bench_layout_heavy(c: &mut Criterion) { fn bench_combined_stress(c: &mut Criterion) { let mut fs = ct::FontSystem::new(); - let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0), ct::Hinting::Disabled); + let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0)); buffer.set_size(&mut fs, Some(500.0), None); let stress_text = format!("{}\n{}\n{}\n{}\n", diff --git a/examples/editor-test/src/main.rs b/examples/editor-test/src/main.rs index 45f78ee..85bae2b 100644 --- a/examples/editor-test/src/main.rs +++ b/examples/editor-test/src/main.rs @@ -2,7 +2,7 @@ use cosmic_text::{ Action, BidiParagraphs, BorrowedWithFontSystem, Buffer, Color, Edit, Editor, FontSystem, - Hinting, Metrics, Motion, SwashCache, + Metrics, Motion, SwashCache, }; use orbclient::{EventOption, Renderer, Window, WindowFlag}; use std::{env, fs, process, time::Instant}; @@ -71,11 +71,7 @@ fn main() { ]; let font_size_default = 1; // Body - let mut buffer = Buffer::new( - &mut font_system, - font_sizes[font_size_default], - Hinting::Disabled, - ); + let mut buffer = Buffer::new(&mut font_system, font_sizes[font_size_default]); buffer .borrow_with(&mut font_system) .set_size(Some(window.width() as f32), Some(window.height() as f32)); diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 193b085..d0e5ff0 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use cosmic_text::{ - Action, Attrs, Buffer, Edit, Family, FontSystem, Hinting, Metrics, Motion, SwashCache, - SyntaxEditor, SyntaxSystem, + Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Motion, SwashCache, SyntaxEditor, + SyntaxSystem, }; use std::{env, fs, num::NonZeroU32, rc::Rc, slice}; use tiny_skia::{Paint, PixmapMut, Rect, Transform}; @@ -45,7 +45,6 @@ fn main() { Buffer::new( &mut font_system, font_sizes[font_size_i].scale(display_scale), - Hinting::Disabled, ), &syntax_system, "base16-eighties.dark", diff --git a/examples/multiview/src/main.rs b/examples/multiview/src/main.rs index 677bb56..e292fe9 100644 --- a/examples/multiview/src/main.rs +++ b/examples/multiview/src/main.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use cosmic_text::{ - Action, Attrs, Buffer, Edit, Family, FontSystem, Hinting, Metrics, Scroll, Shaping, SwashCache, + Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Scroll, Shaping, SwashCache, }; use std::{collections::HashMap, env, fs, num::NonZeroU32, rc::Rc, slice}; use tiny_skia::{Color, Paint, PixmapMut, Rect, Transform}; @@ -25,7 +25,7 @@ fn main() { let mut swash_cache = SwashCache::new(); - let mut buffer = Buffer::new_empty(Metrics::new(14.0, 20.0), Hinting::Disabled); + let mut buffer = Buffer::new_empty(Metrics::new(14.0, 20.0)); let mut buffer = buffer.borrow_with(&mut font_system); diff --git a/examples/rich-text/src/main.rs b/examples/rich-text/src/main.rs index 83181d5..9d51bc0 100644 --- a/examples/rich-text/src/main.rs +++ b/examples/rich-text/src/main.rs @@ -7,7 +7,7 @@ use cosmic_text::Editor; use cosmic_text::Shaping; use cosmic_text::Style; use cosmic_text::{ - Action, Attrs, Buffer, Edit, Family, FontSystem, Hinting, Metrics, Motion, SwashCache, Weight, + Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Motion, SwashCache, Weight, }; use std::{num::NonZeroU32, rc::Rc, slice}; use tiny_skia::{Paint, PixmapMut, Rect, Transform}; @@ -172,10 +172,7 @@ fn main() { let mut display_scale = window.scale_factor() as f32; let metrics = Metrics::new(32.0, 44.0); - let mut editor = Editor::new(Buffer::new_empty( - metrics.scale(display_scale), - Hinting::Disabled, - )); + let mut editor = Editor::new(Buffer::new_empty(metrics.scale(display_scale))); let mut editor = editor.borrow_with(&mut font_system); editor.with_buffer_mut(|buffer| { buffer.set_size( diff --git a/examples/terminal/src/main.rs b/examples/terminal/src/main.rs index 0bb7d2c..08596e7 100644 --- a/examples/terminal/src/main.rs +++ b/examples/terminal/src/main.rs @@ -4,7 +4,7 @@ //! or `cargo run --package terminal -- "my own text"` use colored::Colorize; -use cosmic_text::{Attrs, Buffer, Color, FontSystem, Hinting, Metrics, Shaping, SwashCache}; +use cosmic_text::{Attrs, Buffer, Color, FontSystem, Metrics, Shaping, SwashCache}; use std::fmt::Write; fn main() { @@ -20,7 +20,7 @@ fn main() { let metrics = Metrics::new(FONT_SIZE, LINE_HEIGHT); // A Buffer provides shaping and layout for a UTF-8 string, create one per text widget - let mut buffer = Buffer::new(&mut font_system, metrics, Hinting::Disabled); + let mut buffer = Buffer::new(&mut font_system, metrics); let mut buffer = buffer.borrow_with(&mut font_system); diff --git a/src/buffer.rs b/src/buffer.rs index 031eec0..282989b 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -216,7 +216,7 @@ pub struct Buffer { wrap: Wrap, monospace_width: Option, tab_width: u16, - hint: Hinting, + hinting: Hinting, } impl Clone for Buffer { @@ -231,7 +231,7 @@ impl Clone for Buffer { wrap: self.wrap, monospace_width: self.monospace_width, tab_width: self.tab_width, - hint: self.hint, + hinting: self.hinting, } } } @@ -248,7 +248,7 @@ impl Buffer { /// # Panics /// /// Will panic if `metrics.line_height` is zero. - pub fn new_empty(metrics: Metrics, hint: Hinting) -> Self { + pub fn new_empty(metrics: Metrics) -> Self { assert_ne!(metrics.line_height, 0.0, "line height cannot be 0"); Self { lines: Vec::new(), @@ -260,7 +260,7 @@ impl Buffer { wrap: Wrap::WordOrGlyph, monospace_width: None, tab_width: 8, - hint, + hinting: Hinting::default(), } } @@ -269,8 +269,8 @@ impl Buffer { /// # Panics /// /// Will panic if `metrics.line_height` is zero. - pub fn new(font_system: &mut FontSystem, metrics: Metrics, hint: Hinting) -> Self { - let mut buffer = Self::new_empty(metrics, hint); + pub fn new(font_system: &mut FontSystem, metrics: Metrics) -> Self { + let mut buffer = Self::new_empty(metrics); buffer.set_text(font_system, "", &Attrs::new(), Shaping::Advanced, None); buffer } @@ -300,7 +300,7 @@ impl Buffer { self.wrap, self.monospace_width, self.tab_width, - self.hint, + self.hinting, ); } } @@ -544,7 +544,7 @@ impl Buffer { self.wrap, self.monospace_width, self.tab_width, - self.hint, + self.hinting, )) } @@ -562,6 +562,20 @@ impl Buffer { self.set_metrics_and_size(font_system, metrics, self.width_opt, self.height_opt); } + /// Get the current [`Hinting`] strategy. + pub const fn hinting(&self) -> Hinting { + self.hinting + } + + /// Set the current [`Hinting`] strategy. + pub fn set_hinting(&mut self, font_system: &mut FontSystem, hinting: Hinting) { + if hinting != self.hinting { + self.hinting = hinting; + self.relayout(font_system); + self.shape_until_scroll(font_system, false); + } + } + /// Get the current [`Wrap`] pub const fn wrap(&self) -> Wrap { self.wrap @@ -722,9 +736,9 @@ impl Buffer { /// Set text of buffer, using an iterator of styled spans (pairs of text and attributes) /// /// ``` - /// # use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Hinting, Shaping}; + /// # use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Shaping}; /// # let mut font_system = FontSystem::new(); - /// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0), Hinting::Disabled); + /// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0)); /// let attrs = Attrs::new().family(Family::Serif); /// buffer.set_rich_text( /// &mut font_system, @@ -1451,9 +1465,9 @@ impl BorrowedWithFontSystem<'_, Buffer> { /// Set text of buffer, using an iterator of styled spans (pairs of text and attributes) /// /// ``` - /// # use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Hinting, Shaping}; + /// # use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Shaping}; /// # let mut font_system = FontSystem::new(); - /// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0), Hinting::Disabled); + /// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0)); /// let attrs = Attrs::new().family(Family::Serif); /// buffer.set_rich_text( /// &mut font_system, diff --git a/src/buffer_line.rs b/src/buffer_line.rs index c6ed194..73077ca 100644 --- a/src/buffer_line.rs +++ b/src/buffer_line.rs @@ -244,7 +244,7 @@ impl BufferLine { wrap: Wrap, match_mono_width: Option, tab_width: u16, - hint: Hinting, + hinting: Hinting, ) -> &[LayoutLine] { if self.layout_opt.is_unused() { let align = self.align; @@ -261,7 +261,7 @@ impl BufferLine { align, &mut layout, match_mono_width, - hint, + hinting, ); self.layout_opt.set_used(layout); } diff --git a/src/lib.rs b/src/lib.rs index f539e64..0cad691 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,7 @@ //! point, you can use the `SwashCache` to rasterize glyphs into either images or pixels. //! //! ``` -//! use cosmic_text::{Attrs, Color, FontSystem, SwashCache, Buffer, Metrics, Hinting, Shaping}; +//! use cosmic_text::{Attrs, Color, FontSystem, SwashCache, Buffer, Metrics, Shaping}; //! //! // A FontSystem provides access to detected system fonts, create one per application //! let mut font_system = FontSystem::new(); @@ -24,7 +24,7 @@ //! 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(&mut font_system, metrics, Hinting::Disabled); +//! let mut buffer = Buffer::new(&mut font_system, metrics); //! //! // Borrow buffer together with the font system for more convenient method calls //! let mut buffer = buffer.borrow_with(&mut font_system); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index e5fcf71..6dae78b 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; use cosmic_text::{ - fontdb::Database, Attrs, AttrsOwned, Buffer, Color, Family, FontSystem, Hinting, Metrics, - Shaping, SwashCache, + fontdb::Database, Attrs, AttrsOwned, Buffer, Color, Family, FontSystem, Metrics, Shaping, + SwashCache, }; use tiny_skia::{Paint, Pixmap, Rect, Transform}; @@ -85,7 +85,7 @@ impl DrawTestCfg { let mut font_system = FontSystem::new_with_locale_and_db("En-US".into(), font_db); let mut swash_cache = SwashCache::new(); let metrics = Metrics::new(self.font_size, self.line_height); - let mut buffer = Buffer::new(&mut font_system, metrics, Hinting::Disabled); + let mut buffer = Buffer::new(&mut font_system, metrics); let mut buffer = buffer.borrow_with(&mut font_system); let margins = 5; buffer.set_size( diff --git a/tests/editor_modified_state.rs b/tests/editor_modified_state.rs index a45bc78..b3f9e07 100644 --- a/tests/editor_modified_state.rs +++ b/tests/editor_modified_state.rs @@ -2,7 +2,7 @@ use std::sync::OnceLock; -use cosmic_text::{Buffer, Cursor, Edit, Hinting, Metrics, SyntaxEditor, SyntaxSystem, ViEditor}; +use cosmic_text::{Buffer, Cursor, Edit, Metrics, SyntaxEditor, SyntaxSystem, ViEditor}; static SYNTAX_SYSTEM: OnceLock = OnceLock::new(); @@ -13,7 +13,7 @@ fn editor() -> ViEditor<'static, 'static> { let line_height = (font_size * 1.4).ceil(); let metrics = Metrics::new(font_size, line_height); - let buffer = Buffer::new_empty(metrics, Hinting::Disabled); + let buffer = Buffer::new_empty(metrics); let editor = SyntaxEditor::new( buffer, SYNTAX_SYSTEM.get_or_init(SyntaxSystem::new), diff --git a/tests/wrap_stability.rs b/tests/wrap_stability.rs index f785805..56a51a2 100644 --- a/tests/wrap_stability.rs +++ b/tests/wrap_stability.rs @@ -113,7 +113,7 @@ fn wrap_extra_line() { let mut font_system = FontSystem::new(); let metrics = Metrics::new(14.0, 20.0); - let mut buffer = Buffer::new(&mut font_system, metrics, Hinting::Disabled); + let mut buffer = Buffer::new(&mut font_system, metrics); let mut buffer = buffer.borrow_with(&mut font_system); diff --git a/tests/wrap_word_fallback.rs b/tests/wrap_word_fallback.rs index f560025..db7f80a 100644 --- a/tests/wrap_word_fallback.rs +++ b/tests/wrap_word_fallback.rs @@ -1,4 +1,4 @@ -use cosmic_text::{Attrs, Buffer, FontSystem, Hinting, Metrics, Shaping, Wrap}; +use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, Wrap}; // Tests the ability to fallback to glyph wrapping when a word can't fit on a line by itself. // No line should ever overflow the buffer size. @@ -10,7 +10,7 @@ fn wrap_word_fallback() { font_system.db_mut().load_font_data(font); let metrics = Metrics::new(14.0, 20.0); - let mut buffer = Buffer::new(&mut font_system, metrics, Hinting::Disabled); + let mut buffer = Buffer::new(&mut font_system, metrics); let mut buffer = buffer.borrow_with(&mut font_system);