diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index eb4f5cdade..18b2e25bc6 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -699,17 +699,17 @@ (if (< index total) (let [paragraph (nth paragraphs index) - leaves (get paragraph :children)] - (if (empty? (seq leaves)) + spans (get paragraph :children)] + (if (empty? (seq spans)) (recur (inc index) emoji? langs) - (let [text (apply str (map :text leaves)) + (let [text (apply str (map :text spans)) emoji? (if emoji? emoji? (t/contains-emoji? text)) langs (t/collect-used-languages langs text)] - (t/write-shape-text leaves paragraph text) + (t/write-shape-text spans paragraph text) (recur (inc index) emoji? langs)))) diff --git a/frontend/src/app/render_wasm/api/texts.cljs b/frontend/src/app/render_wasm/api/texts.cljs index 9713fa0633..44d36a8823 100644 --- a/frontend/src/app/render_wasm/api/texts.cljs +++ b/frontend/src/app/render_wasm/api/texts.cljs @@ -16,7 +16,7 @@ [app.render-wasm.wasm :as wasm])) (def ^:const PARAGRAPH-ATTR-U8-SIZE 44) -(def ^:const SPAN-ATTR-U8-SIZE 60) +(def ^:const SPAN-ATTR-U8-SIZE 64) (def ^:const MAX-TEXT-FILLS types.fills.impl/MAX-FILLS) (defn- encode-text @@ -74,68 +74,73 @@ (mem/write-uuid dview (d/nilv typography-ref-id uuid/zero)) (mem/assert-written offset PARAGRAPH-ATTR-U8-SIZE)))) -(defn- write-leaves - [offset dview leaves paragraph] - (reduce (fn [offset span] - (let [font-style (sr/translate-font-style (get span :font-style)) - font-size (get span :font-size) - letter-spacing (get span :letter-spacing) - font-weight (get span :font-weight) - font-id (f/normalize-font-id (get span :font-id)) - font-family (hash (get span :font-family)) +(defn- write-spans + [offset dview spans paragraph] + (let [paragraph-font-size (get paragraph :font-size) + paragraph-font-weight (get paragraph :font-weight) + paragraph-line-height (get paragraph :line-height)] + (reduce (fn [offset span] + (let [font-style (sr/translate-font-style (get span :font-style)) + font-size (get span :font-size paragraph-font-size) + line-height (get span :line-height paragraph-line-height) + letter-spacing (get span :letter-spacing) + font-weight (get span :font-weight paragraph-font-weight) + font-id (f/normalize-font-id (get span :font-id)) + font-family (hash (get span :font-family)) - text-buffer (encode-text (get span :text)) - text-length (mem/size text-buffer) - fills (take MAX-TEXT-FILLS (get span :fills)) + text-buffer (encode-text (get span :text)) + text-length (mem/size text-buffer) + fills (take MAX-TEXT-FILLS (get span :fills)) - font-variant-id - (get span :font-variant-id) - - font-variant-id - (if (uuid? font-variant-id) font-variant-id - uuid/zero) + (get span :font-variant-id) - text-decoration - (or (sr/translate-text-decoration (:text-decoration span)) - (sr/translate-text-decoration (:text-decoration paragraph)) - (sr/translate-text-decoration "none")) + font-variant-id + (if (uuid? font-variant-id) + font-variant-id + uuid/zero) - text-transform - (or (sr/translate-text-transform (:text-transform span)) - (sr/translate-text-transform (:text-transform paragraph)) - (sr/translate-text-transform "none")) + text-decoration + (or (sr/translate-text-decoration (:text-decoration span)) + (sr/translate-text-decoration (:text-decoration paragraph)) + (sr/translate-text-decoration "none")) - text-direction - (or (sr/translate-text-direction (:text-direction span)) - (sr/translate-text-direction (:text-direction paragraph)) - (sr/translate-text-direction "ltr"))] + text-transform + (or (sr/translate-text-transform (:text-transform span)) + (sr/translate-text-transform (:text-transform paragraph)) + (sr/translate-text-transform "none")) - (-> offset - (mem/write-u8 dview font-style) - (mem/write-u8 dview text-decoration) - (mem/write-u8 dview text-transform) - (mem/write-u8 dview text-direction) + text-direction + (or (sr/translate-text-direction (:text-direction span)) + (sr/translate-text-direction (:text-direction paragraph)) + (sr/translate-text-direction "ltr"))] - (mem/write-f32 dview font-size) - (mem/write-f32 dview letter-spacing) - (mem/write-u32 dview font-weight) + (-> offset + (mem/write-u8 dview font-style) + (mem/write-u8 dview text-decoration) + (mem/write-u8 dview text-transform) + (mem/write-u8 dview text-direction) - (mem/write-uuid dview font-id) - (mem/write-i32 dview font-family) - (mem/write-uuid dview (d/nilv font-variant-id uuid/zero)) + (mem/write-f32 dview font-size) + (mem/write-f32 dview line-height) + (mem/write-f32 dview letter-spacing) + (mem/write-u32 dview font-weight) - (mem/write-i32 dview text-length) - (mem/write-i32 dview (count fills)) - (mem/assert-written offset SPAN-ATTR-U8-SIZE) + (mem/write-uuid dview font-id) + (mem/write-i32 dview font-family) + (mem/write-uuid dview (d/nilv font-variant-id uuid/zero)) - (write-span-fills dview fills)))) - offset - leaves)) + (mem/write-i32 dview text-length) + (mem/write-i32 dview (count fills)) + (mem/assert-written offset SPAN-ATTR-U8-SIZE) + + (write-span-fills dview fills)))) + offset + spans))) (defn write-shape-text ;; buffer has the following format: - ;; [ ] + ;; [ ] [spans paragraph text] (let [num-spans (count spans) fills-size (* types.fills.impl/FILL-U8-SIZE MAX-TEXT-FILLS) @@ -153,7 +158,7 @@ (-> offset (mem/write-u32 dview num-spans) (write-paragraph dview paragraph) - (write-leaves dview spans paragraph) + (write-spans dview spans paragraph) (mem/write-buffer heapu8 text-buffer)) (h/call wasm/internal-module "_set_shape_text_content"))) diff --git a/render-wasm/src/render/text.rs b/render-wasm/src/render/text.rs index 0560225e31..5828a55643 100644 --- a/render-wasm/src/render/text.rs +++ b/render-wasm/src/render/text.rs @@ -221,21 +221,16 @@ fn draw_text( for paragraph_builder_group in paragraph_builder_groups { let mut group_offset_y = global_offset_y; - let total_paragraphs = paragraph_builder_group.len(); + let group_len = paragraph_builder_group.len(); for (paragraph_index, paragraph_builder) in paragraph_builder_group.iter_mut().enumerate() { let mut paragraph = paragraph_builder.build(); paragraph.layout(text_width); - let _paragraph_height = paragraph.height(); - // FIXME: I've kept the _paragraph_height variable to have - // a reminder in the future to keep digging why the ideographic_baseline - // works so well and not the paragraph_height. I think we should test - // this more. let xy = (shape.selrect().x(), shape.selrect().y() + group_offset_y); paragraph.paint(canvas, xy); - if paragraph_index == total_paragraphs - 1 { - group_offset_y += paragraph.ideographic_baseline(); + if paragraph_index == group_len - 1 { + group_offset_y += paragraph.height(); } for line_metrics in paragraph.get_line_metrics().iter() { diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index 8da1c65cbb..7fa0ea3f59 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -630,6 +630,7 @@ pub struct TextSpan { text: String, font_family: FontFamily, font_size: f32, + line_height: f32, letter_spacing: f32, font_weight: i32, font_variant_id: Uuid, @@ -645,6 +646,7 @@ impl TextSpan { text: String, font_family: FontFamily, font_size: f32, + line_height: f32, letter_spacing: f32, text_decoration: Option, text_transform: Option, @@ -657,6 +659,7 @@ impl TextSpan { text, font_family, font_size, + line_height, letter_spacing, text_decoration, text_transform, @@ -680,10 +683,9 @@ impl TextSpan { content_bounds: &Rect, fallback_fonts: &HashSet, remove_alpha: bool, - paragraph_line_height: f32, // Add this parameter + paragraph_line_height: f32, ) -> skia::textlayout::TextStyle { let mut style = skia::textlayout::TextStyle::default(); - let mut paint = paint::Paint::default(); if remove_alpha { @@ -693,9 +695,14 @@ impl TextSpan { paint = merge_fills(&self.fills, *content_bounds); } - style.set_height(paragraph_line_height); - style.set_height_override(true); + // FIXME + if self.line_height <= 0.0 { + style.set_height(paragraph_line_height); + } else { + style.set_height(self.line_height); + } + style.set_height_override(true); style.set_foreground_paint(&paint); style.set_decoration_type(match self.text_decoration { Some(text_decoration) => text_decoration, diff --git a/render-wasm/src/wasm/fills.rs b/render-wasm/src/wasm/fills.rs index 46901816e4..86f0e57e8e 100644 --- a/render-wasm/src/wasm/fills.rs +++ b/render-wasm/src/wasm/fills.rs @@ -75,6 +75,7 @@ pub extern "C" fn set_shape_fills() { // Skip the first 4 bytes (header with fill count) and parse only the actual fills let fills = parse_fills_from_bytes(&bytes[4..], num_fills); shape.set_fills(fills); + mem::free_bytes(); }); } diff --git a/render-wasm/src/wasm/text.rs b/render-wasm/src/wasm/text.rs index 910135097b..77c6612856 100644 --- a/render-wasm/src/wasm/text.rs +++ b/render-wasm/src/wasm/text.rs @@ -130,6 +130,7 @@ pub struct RawTextSpan { text_transform: RawTextTransform, text_direction: RawTextDirection, font_size: f32, + line_height: f32, letter_spacing: f32, font_weight: i32, font_id: [u32; 4], @@ -178,6 +179,7 @@ impl From for shapes::TextSpan { text, font_family, value.font_size, + value.line_height, value.letter_spacing, value.text_decoration.into(), value.text_transform.into(), @@ -193,7 +195,7 @@ impl From for shapes::TextSpan { #[derive(Debug, Clone)] pub struct RawParagraph { attrs: RawParagraphData, - leaves: Vec, + spans: Vec, text_buffer: Vec, } @@ -204,19 +206,19 @@ impl TryFrom<&Vec> for RawParagraph { fn try_from(bytes: &Vec) -> Result { let attrs = RawParagraphData::try_from(&bytes[..RAW_PARAGRAPH_DATA_SIZE])?; let mut offset = RAW_PARAGRAPH_DATA_SIZE; - let mut raw_text_leaves: Vec = Vec::new(); + let mut raw_text_spans: Vec = Vec::new(); for _ in 0..attrs.span_count { let text_span = RawTextSpan::try_from(&bytes[offset..(offset + RAW_SPAN_DATA_SIZE)])?; offset += RAW_SPAN_DATA_SIZE; - raw_text_leaves.push(text_span); + raw_text_spans.push(text_span); } let text_buffer = &bytes[offset..]; Ok(Self { attrs, - leaves: raw_text_leaves, + spans: raw_text_spans, text_buffer: text_buffer.to_vec(), }) } @@ -227,10 +229,10 @@ impl From for shapes::Paragraph { let typography_ref_file = uuid_from_u32(value.attrs.typography_ref_file); let typography_ref_id = uuid_from_u32(value.attrs.typography_ref_id); - let mut leaves = vec![]; + let mut spans = vec![]; let mut offset = 0; - for raw_span in value.leaves.into_iter() { + for raw_span in value.spans.into_iter() { let delta = raw_span.text_length as usize; let text_buffer = &value.text_buffer[offset..offset + delta]; @@ -239,7 +241,7 @@ impl From for shapes::Paragraph { span.set_text(String::from_utf8_lossy(text_buffer).to_string()); } - leaves.push(span); + spans.push(span); offset += delta; } @@ -252,7 +254,7 @@ impl From for shapes::Paragraph { value.attrs.letter_spacing, typography_ref_file, typography_ref_id, - leaves, + spans, ) } }