From 88e77e3218243ef6ccd1dfb1793db43a0058fb9d Mon Sep 17 00:00:00 2001 From: Elena Torro Date: Tue, 27 May 2025 14:04:27 +0200 Subject: [PATCH 1/2] :wrench: Fix text parsing and transformation --- render-wasm/src/render.rs | 14 +++++++++++--- render-wasm/src/shapes/text.rs | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index 5d9709e9d9..f681d29fba 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -416,9 +416,17 @@ impl RenderState { } Type::Text(text_content) => { - self.surfaces.apply_mut(&[SurfaceId::Fills], |s| { - s.canvas().concat(&matrix); - }); + self.surfaces.apply_mut( + &[ + SurfaceId::Fills, + SurfaceId::Strokes, + SurfaceId::DropShadows, + SurfaceId::InnerShadows, + ], + |s| { + s.canvas().concat(&matrix); + }, + ); let text_content = text_content.new_bounds(shape.selrect()); let paragraphs = text_content.get_skia_paragraphs(self.fonts.font_collection()); diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index e63b1df29a..fe4ea78499 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -197,8 +197,8 @@ impl Default for TextContent { pub struct Paragraph { num_leaves: u32, text_align: u8, - text_decoration: u8, text_direction: u8, + text_decoration: u8, text_transform: u8, line_height: f32, letter_spacing: f32, @@ -212,8 +212,8 @@ impl Default for Paragraph { Self { num_leaves: 0, text_align: 0, - text_decoration: 0, text_direction: 0, + text_decoration: 0, text_transform: 0, line_height: 1.0, letter_spacing: 0.0, @@ -229,8 +229,8 @@ impl Paragraph { pub fn new( num_leaves: u32, text_align: u8, - text_decoration: u8, text_direction: u8, + text_decoration: u8, text_transform: u8, line_height: f32, letter_spacing: f32, @@ -241,8 +241,8 @@ impl Paragraph { Self { num_leaves, text_align, - text_decoration, text_direction, + text_decoration, text_transform, line_height, letter_spacing, @@ -345,6 +345,8 @@ impl TextLeaf { 3 => skia::textlayout::TextDecoration::OVERLINE, _ => skia::textlayout::TextDecoration::NO_DECORATION, }); + // FIXME + style.set_decoration_color(paint.color()); style.set_font_families(&[ self.serialized_font_family(), @@ -362,6 +364,15 @@ impl TextLeaf { ) -> skia::textlayout::TextStyle { let mut style = self.to_style(paragraph, &Rect::default()); style.set_foreground_paint(stroke_paint); + style.set_font_size(self.font_size); + style.set_letter_spacing(paragraph.letter_spacing); + style.set_decoration_type(match paragraph.text_decoration { + 0 => skia::textlayout::TextDecoration::NO_DECORATION, + 1 => skia::textlayout::TextDecoration::UNDERLINE, + 2 => skia::textlayout::TextDecoration::LINE_THROUGH, + 3 => skia::textlayout::TextDecoration::OVERLINE, + _ => skia::textlayout::TextDecoration::NO_DECORATION, + }); style } From 5c58a04fc2de458be3a965be1fd5aeb2724e306f Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 28 May 2025 08:04:19 +0200 Subject: [PATCH 2/2] :bug: Fix inner strokes black background effect --- render-wasm/src/render.rs | 24 ++++++++++++++++-------- render-wasm/src/render/text.rs | 12 ++++++++++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index f681d29fba..423d41f17a 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -19,7 +19,7 @@ use options::RenderOptions; use surfaces::{SurfaceId, Surfaces}; use crate::performance; -use crate::shapes::{modified_children_ids, Corners, Shape, StructureEntry, Type}; +use crate::shapes::{modified_children_ids, Corners, Shape, StrokeKind, StructureEntry, Type}; use crate::tiles::{self, TileRect, TileViewbox, TileWithDistance}; use crate::uuid::Uuid; use crate::view::Viewbox; @@ -441,13 +441,21 @@ impl RenderState { self.fonts.font_collection(), ); shadows::render_text_drop_shadows(self, &shape, &stroke_paragraphs, antialias); - text::render( - self, - &shape, - &stroke_paragraphs, - Some(SurfaceId::Strokes), - None, - ); + if stroke.kind == StrokeKind::Inner { + // Inner strokes must be rendered on the Fills surface because their blend modes + // (e.g., SrcATop, DstOver) rely on the text fill already being present underneath. + // Rendering them on a separate surface would break this blending and result in incorrect visuals as + // black color background. + text::render(self, &shape, &stroke_paragraphs, None, None); + } else { + text::render( + self, + &shape, + &stroke_paragraphs, + Some(SurfaceId::Strokes), + None, + ); + } shadows::render_text_inner_shadows(self, &shape, &stroke_paragraphs, antialias); } diff --git a/render-wasm/src/render/text.rs b/render-wasm/src/render/text.rs index 0bec6887d2..d6346b29a0 100644 --- a/render-wasm/src/render/text.rs +++ b/render-wasm/src/render/text.rs @@ -8,13 +8,19 @@ pub fn render( surface_id: Option, paint: Option, ) { + let use_save_layer = paint.is_some(); let mask_paint = paint.unwrap_or_default(); let mask = SaveLayerRec::default().paint(&mask_paint); let canvas = render_state .surfaces .canvas(surface_id.unwrap_or(SurfaceId::Fills)); - canvas.save_layer(&mask); + // Skip save_layer when no custom paint is provided to avoid isolating content unnecessarily. + // This ensures inner strokes and fills can blend correctly on the same surface. + if use_save_layer { + canvas.save_layer(&mask); + } + for group in paragraphs { let mut offset_y = 0.0; for skia_paragraph in group { @@ -23,5 +29,7 @@ pub fn render( offset_y += skia_paragraph.height(); } } - canvas.restore(); + if use_save_layer { + canvas.restore(); + } }