From 3053c3bfe81332aa2a3375bacbdbf3788bc05d4f Mon Sep 17 00:00:00 2001 From: yuyaprgrm Date: Sat, 11 Apr 2026 09:47:13 +0900 Subject: [PATCH 1/2] feat: use text-based memory allocation --- src/graphics/util.rs | 77 ++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/src/graphics/util.rs b/src/graphics/util.rs index 635a813..efc3132 100644 --- a/src/graphics/util.rs +++ b/src/graphics/util.rs @@ -2,8 +2,10 @@ use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, SwashCache, Swash use std::borrow::Cow; use std::sync::{Arc, Mutex}; use tiny_skia::{ - Color, IntSize, Mask, Paint, Pixmap, PixmapPaint, PixmapRef, Point, Rect, Transform, + Color, FilterQuality, IntSize, Paint, Pattern, Pixmap, PixmapPaint, PixmapRef, Point, Rect, + SpreadMode, Transform, }; +use tracing::warn; #[derive(Clone)] pub struct Calligraphy { @@ -44,23 +46,26 @@ impl Calligraphy { ); buffer.shape_until_scroll(font_system, true); - let size = IntSize::from_wh(pixmap.width(), pixmap.height()).unwrap(); - let mut text_mask_data = vec![0; size.width() as usize * size.height() as usize]; - - let x = text.pos.x as i32; - let y = text.pos.y as i32; - + let color_u8 = text.color.to_color_u8(); for run in buffer.layout_runs() { - let half_line_width = run.line_w / 2.0; + let height = metrics.font_size; + let Some(text_area_size) = + IntSize::from_wh(run.line_w.ceil() as u32, height.ceil() as u32) + else { + warn!(text=%run.text, "Failed to determine size"); + continue; + }; + let mut text_alpha_data = + vec![0; text_area_size.width() as usize * text_area_size.height() as usize]; for glyph in run.glyphs { - let physical_glyph = glyph.physical((-half_line_width, 0.0), 1.0); + let physical_glyph = glyph.physical((0.0, 0.0), 1.0); if let Some(image) = swash_cache.get_image(font_system, physical_glyph.cache_key) { - let left = x + image.placement.left + physical_glyph.x; - let top = y - image.placement.top + physical_glyph.y; + let left = image.placement.left + physical_glyph.x; + let top = height as i32 - image.placement.top + physical_glyph.y; let width = image.placement.width; let height = image.placement.height; @@ -74,14 +79,14 @@ impl Calligraphy { for (i, &a) in image.data.iter().enumerate() { let x = i as i32 % width as i32 + left; let y = i as i32 / width as i32 + top; - if x < 0 || size.width() as i32 <= x { + if x < 0 || text_area_size.width() as i32 <= x { continue; } - if y < 0 || size.height() as i32 <= y { + if y < 0 || text_area_size.height() as i32 <= y { continue; } - let idx = (x + y * size.width() as i32) as usize; - text_mask_data[idx] = a; + let idx = (x + y * text_area_size.width() as i32) as usize; + text_alpha_data[idx] = a; } } @@ -107,19 +112,43 @@ impl Calligraphy { } } } - } - let mut paint = Paint::default(); - paint.set_color(text.color); + let mut text_pixmap_data = Vec::with_capacity(text_alpha_data.len() * 4); + for a in text_alpha_data { + text_pixmap_data.extend_from_slice(&[ + color_u8.red(), + color_u8.green(), + color_u8.blue(), + a, + ]); + } + + let Some(text_pixmap) = Pixmap::from_vec(text_pixmap_data, text_area_size) else { + warn!("failed to construct pixmap from vec"); + continue; + }; - if let Some(mask) = Mask::from_vec(text_mask_data, size) { - pixmap.fill_rect( - Rect::from_xywh(0.0, 0.0, size.width() as f32, size.height() as f32) - .unwrap_or(Rect::from_xywh(0.0, 0.0, 0.0, 0.0).unwrap()), - &paint, + let shader = Pattern::new( + text_pixmap.as_ref(), + SpreadMode::Pad, + FilterQuality::Bicubic, + 1.0, Transform::identity(), - Some(&mask), ); + + pixmap.fill_rect( + Rect::from_xywh(0.0, 0.0, run.line_w, height).unwrap(), + &Paint { + shader, + anti_alias: true, + ..Paint::default() + }, + Transform::from_translate( + text.pos.x - run.line_w / 2.0, + text.pos.y - metrics.font_size, + ), + None, + ) } } From 7e80a7c2aaab28948675a922e376f85264eab5eb Mon Sep 17 00:00:00 2001 From: yuyaprgrm Date: Sat, 11 Apr 2026 19:44:56 +0900 Subject: [PATCH 2/2] chore: bump up calver --- src/reporting/reporter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reporting/reporter.rs b/src/reporting/reporter.rs index 429cf4b..7c89379 100644 --- a/src/reporting/reporter.rs +++ b/src/reporting/reporter.rs @@ -127,7 +127,7 @@ impl Reporter { )]) .accent_color(accent_color), footer: CreateTextDisplay::new(format!( - "-# ringring-rs v26.4.7 {}\n-# rendering {}ms", + "-# ringring-rs v26.4.11 {}\n-# rendering {}ms", FormattedTimestamp::new(timestamp, Some(FormattedTimestampStyle::RelativeTime)), rendering_elapsed.as_millis(), )),