[librsvg: 4/5] (#363): Fix whitespace removal around <tspan> elements



commit 2b31e7ec52bd0be4f4ca426bef083c8c3c1e5ff1
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Oct 23 17:58:18 2018 -0500

    (#363): Fix whitespace removal around <tspan> elements
    
    When there is something like
    
      <text>hello <tspan>world</tspan></text>
    
    librsvg would trim away the space after "hello", so the rendered text
    looked like "helloworld".
    
    Now we only trim the ends of NodeChars elements if they don't have an
    adjacent sibling; in the example above, the tspan is the sibling to
    the right, and so the rightmost space in the "hello " NodeChars
    doesn't get trimmed.
    
    This makes the rendering in 340047.svg match Firefox; regenerated the
    test reference file for that, and made it always use a sans-serif
    font.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/363

 rsvg_internals/src/node.rs                         |   8 +++++++
 rsvg_internals/src/text.rs                         |  23 +++++++++++++--------
 tests/fixtures/reftests/bugs/340047-ref.png        | Bin 4752 -> 4761 bytes
 tests/fixtures/reftests/bugs/340047.svg            |   2 +-
 .../reftests/bugs/363-missing-space-ref.png        | Bin 0 -> 6558 bytes
 tests/fixtures/reftests/bugs/363-missing-space.svg |   6 ++++++
 6 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 0381dfa5..36e3df03 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -322,6 +322,14 @@ impl Node {
         false
     }
 
+    pub fn has_previous_sibling(&self) -> bool {
+        !self.prev_sib.borrow().is_none()
+    }
+
+    pub fn has_next_sibling(&self) -> bool {
+        !self.next_sib.borrow().is_none()
+    }
+
     pub fn add_child(&self, child: &Rc<Node>) {
         assert!(child.next_sib.borrow().is_none());
         assert!(child.prev_sib.borrow().is_none());
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 6bf9f0d7..7017dbdb 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -67,14 +67,14 @@ impl NodeChars {
         *self.space_normalized.borrow_mut() = None;
     }
 
-    fn ensure_normalized_string(&self, values: &ComputedValues) {
+    fn ensure_normalized_string(&self, node: &RsvgNode, values: &ComputedValues) {
         let mut normalized = self.space_normalized.borrow_mut();
 
         if (*normalized).is_none() {
             let mode = match values.xml_space {
                 XmlSpace::Default => XmlSpaceNormalize::Default(NormalizeDefault {
-                    has_element_before: false,
-                    has_element_after: false,
+                    has_element_before: node.has_previous_sibling(),
+                    has_element_after: node.has_next_sibling(),
                 }),
 
                 XmlSpace::Preserve => XmlSpaceNormalize::Preserve,
@@ -84,8 +84,13 @@ impl NodeChars {
         }
     }
 
-    fn create_layout(&self, values: &ComputedValues, draw_ctx: &DrawingCtx<'_>) -> pango::Layout {
-        self.ensure_normalized_string(values);
+    fn create_layout(
+        &self,
+        node: &RsvgNode,
+        values: &ComputedValues,
+        draw_ctx: &DrawingCtx<'_>,
+    ) -> pango::Layout {
+        self.ensure_normalized_string(node, values);
         let norm = self.space_normalized.borrow();
         let s = norm.as_ref().unwrap();
         create_pango_layout(draw_ctx, values, &s)
@@ -93,12 +98,12 @@ impl NodeChars {
 
     fn measure(
         &self,
-        _node: &RsvgNode,
+        node: &RsvgNode,
         values: &ComputedValues,
         draw_ctx: &DrawingCtx<'_>,
         length: &mut f64,
     ) {
-        let layout = self.create_layout(values, draw_ctx);
+        let layout = self.create_layout(node, values, draw_ctx);
         let (width, _) = layout.get_size();
 
         *length = f64::from(width) / f64::from(pango::SCALE);
@@ -106,14 +111,14 @@ impl NodeChars {
 
     fn render(
         &self,
-        _node: &RsvgNode,
+        node: &RsvgNode,
         values: &ComputedValues,
         draw_ctx: &mut DrawingCtx<'_>,
         x: &mut f64,
         y: &mut f64,
         clipping: bool,
     ) -> Result<(), RenderingError> {
-        let layout = self.create_layout(values, draw_ctx);
+        let layout = self.create_layout(node, values, draw_ctx);
         let (width, _) = layout.get_size();
 
         let baseline = f64::from(layout.get_baseline()) / f64::from(pango::SCALE);
diff --git a/tests/fixtures/reftests/bugs/340047-ref.png b/tests/fixtures/reftests/bugs/340047-ref.png
index 95283a8e..3babc639 100644
Binary files a/tests/fixtures/reftests/bugs/340047-ref.png and b/tests/fixtures/reftests/bugs/340047-ref.png 
differ
diff --git a/tests/fixtures/reftests/bugs/340047.svg b/tests/fixtures/reftests/bugs/340047.svg
index 4e0ee31a..954bc7a7 100644
--- a/tests/fixtures/reftests/bugs/340047.svg
+++ b/tests/fixtures/reftests/bugs/340047.svg
@@ -17,7 +17,7 @@
    sodipodi:docname="New document 1">
 
     <g fill = "navy">
-        <text x = "10" y = "25" font-size = "20">
+        <text x = "10" y = "25" font-size = "20" font-family="sans">
             <tspan>
                 e = mc
                 <tspan baseline-shift = "super">
diff --git a/tests/fixtures/reftests/bugs/363-missing-space-ref.png 
b/tests/fixtures/reftests/bugs/363-missing-space-ref.png
new file mode 100644
index 00000000..1e10aa6a
Binary files /dev/null and b/tests/fixtures/reftests/bugs/363-missing-space-ref.png differ
diff --git a/tests/fixtures/reftests/bugs/363-missing-space.svg 
b/tests/fixtures/reftests/bugs/363-missing-space.svg
new file mode 100644
index 00000000..8203f802
--- /dev/null
+++ b/tests/fixtures/reftests/bugs/363-missing-space.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 600 450" font-family="sans-serif" font-size="50">
+  <text x="20" y="100">hello <tspan>world</tspan></text>
+  <!-- <text x="20" y="150">hello<tspan> world</tspan></text> -->
+  <text x="20" y="200">hello <tspan> world</tspan></text>
+</svg>


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