[librsvg: 2/4] (#565): Apply writing-mode to text elements, not individual tspan elements




commit 3cf258ca663251843496e23662f23fb3d007bc0a
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Sep 24 17:02:47 2021 -0500

    (#565): Apply writing-mode to text elements, not individual tspan elements
    
    SVG1.1 explicitly says that writing-mode only applies to <text>
    elements.  SVG2 doesn't, but implies it in the text layout algorithm.
    We were using the writing-mode from the computed values of individual
    <tspan> elements.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/565
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/597>

 src/layout.rs | 12 ++++++++++--
 src/text.rs   | 22 +++++++++++++++-------
 2 files changed, 25 insertions(+), 9 deletions(-)
---
diff --git a/src/layout.rs b/src/layout.rs
index 91fd8cb5..7eaccab1 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -238,10 +238,18 @@ impl Stroke {
 }
 
 impl FontProperties {
-    pub fn new(values: &ComputedValues, params: &NormalizeParams) -> FontProperties {
+    /// Collects font properties from a `ComputedValues`.
+    ///
+    /// The `writing-mode` property is passed separately, as it must come from the `<text>` element,
+    /// not the `<tspan>` whose computed values are being passed.
+    pub fn new(
+        values: &ComputedValues,
+        writing_mode: WritingMode,
+        params: &NormalizeParams,
+    ) -> FontProperties {
         FontProperties {
             xml_lang: values.xml_lang(),
-            writing_mode: values.writing_mode(),
+            writing_mode,
             unicode_bidi: values.unicode_bidi(),
             direction: values.direction(),
             font_family: values.font_family(),
diff --git a/src/text.rs b/src/text.rs
index d5be2a56..ee612ed4 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -89,11 +89,15 @@ impl Chunk {
 }
 
 impl MeasuredChunk {
-    fn from_chunk(chunk: &Chunk, draw_ctx: &DrawingCtx) -> MeasuredChunk {
+    fn from_chunk(
+        chunk: &Chunk,
+        text_writing_mode: WritingMode,
+        draw_ctx: &DrawingCtx,
+    ) -> MeasuredChunk {
         let measured_spans: Vec<MeasuredSpan> = chunk
             .spans
             .iter()
-            .map(|span| MeasuredSpan::from_span(span, draw_ctx))
+            .map(|span| MeasuredSpan::from_span(span, text_writing_mode, draw_ctx))
             .collect();
 
         let advance = measured_spans.iter().fold((0.0, 0.0), |acc, measured| {
@@ -157,7 +161,7 @@ impl PositionedChunk {
                 Direction::Rtl => (-mspan.advance.0, mspan.advance.1),
             };
 
-            let rendered_position = if values.writing_mode().is_horizontal() {
+            let rendered_position = if text_writing_mode.is_horizontal() {
                 (start_pos.0 + dx, start_pos.1 - baseline_offset + dy)
             } else {
                 (start_pos.0 + baseline_offset + dx, start_pos.1 + dy)
@@ -227,13 +231,17 @@ impl Span {
 }
 
 impl MeasuredSpan {
-    fn from_span(span: &Span, draw_ctx: &DrawingCtx) -> MeasuredSpan {
+    fn from_span(
+        span: &Span,
+        text_writing_mode: WritingMode,
+        draw_ctx: &DrawingCtx,
+    ) -> MeasuredSpan {
         let values = span.values.clone();
 
         let view_params = draw_ctx.get_view_params();
         let params = NormalizeParams::new(&values, &view_params);
 
-        let properties = FontProperties::new(&values, &params);
+        let properties = FontProperties::new(&values, text_writing_mode, &params);
         let layout = create_pango_layout(draw_ctx, &properties, &span.text);
         let (w, h) = layout.size();
 
@@ -244,7 +252,7 @@ impl MeasuredSpan {
         assert!(w >= 0.0);
         assert!(h >= 0.0);
 
-        let advance = if values.writing_mode().is_horizontal() {
+        let advance = if text_writing_mode.is_horizontal() {
             (w, 0.0)
         } else {
             (0.0, w)
@@ -558,7 +566,7 @@ impl Draw for Text {
 
                 let mut measured_chunks = Vec::new();
                 for chunk in &chunks {
-                    measured_chunks.push(MeasuredChunk::from_chunk(chunk, dc));
+                    measured_chunks.push(MeasuredChunk::from_chunk(chunk, text_writing_mode, dc));
                 }
 
                 let mut positioned_chunks = Vec::new();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]