[librsvg/librsvg-2.48] (#129): Fix baseline-shift for simple subscripts/superscripts and absolute offsets



commit fb86e8b0c7115d985c36efeba6a27732b714dd93
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Mar 27 18:27:55 2020 -0600

    (#129): Fix baseline-shift for simple subscripts/superscripts and absolute offsets
    
    This has two parts:
    
    1. Start a new chunk for a tspan even if it does not have absolute
    positions.  This is so that
    
      <text>
        Foo bar<tspan baseline-shift="sub">subscript</tspan>
      </text>
    
    will actually pick up the span's ComputedValues - note how the tspan
    does not have x/y position properties.
    
    2. If the baseline-shift is a length with an absolute unit, add it to
    the parent's instead of ignoring it.  As a limitation, we still use
    only the parent's baseline-shift if the units are different.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/129

 rsvg_internals/src/property_defs.rs                |  29 ++++++---
 rsvg_internals/src/text.rs                         |   7 +-
 .../reftests/svg1.1/text-align-02-b-ref.png        | Bin 0 -> 19831 bytes
 tests/fixtures/reftests/svg1.1/text-align-02-b.svg |  71 +++++++++++++++++++++
 4 files changed, 94 insertions(+), 13 deletions(-)
---
diff --git a/rsvg_internals/src/property_defs.rs b/rsvg_internals/src/property_defs.rs
index 3df0ba8b..a1794ad3 100644
--- a/rsvg_internals/src/property_defs.rs
+++ b/rsvg_internals/src/property_defs.rs
@@ -27,16 +27,29 @@ make_property!(
 
             fn compute(&self, v: &ComputedValues) -> Self {
                 let font_size = v.font_size.0.value();
+                let parent = v.baseline_shift.clone();
 
-                // FIXME: this implementation has limitations:
-                // 1) we only handle 'percent' shifts, but it could also be an absolute offset
-                // 2) we should be able to normalize the lengths and add even if they have
-                //    different units, but at the moment that requires access to the draw_ctx
-                if self.0.unit != LengthUnit::Percent || v.baseline_shift.0.unit != font_size.unit {
-                    return BaselineShift(Length::<Both>::new(v.baseline_shift.0.length, 
v.baseline_shift.0.unit));
-                }
+                match (self.0.unit, parent.0.unit) {
+                    (LengthUnit::Percent, _) => {
+                        BaselineShift(Length::<Both>::new(self.0.length * font_size.length + 
parent.0.length, font_size.unit))
+                    }
+
+                    (x, y) if x == y || parent.0.length == 0.0 => {
+                        BaselineShift(Length::<Both>::new(self.0.length + parent.0.length, self.0.unit))
+                    }
 
-                BaselineShift(Length::<Both>::new(self.0.length * font_size.length + 
v.baseline_shift.0.length, font_size.unit))
+                    _ => {
+                        // FIXME: the limitation here is that the parent's baseline_shift
+                        // and ours have different units.  We should be able to normalize
+                        // the lengths and add them even if they have different units, but
+                        // at the moment that requires access to the draw_ctx, which we
+                        // don't have here.
+                        //
+                        // So for now we won't add to the parent's baseline_shift.
+
+                        parent
+                    }
+                }
             }
         }
     },
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index df22b764..688c5158 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -758,11 +758,8 @@ impl TSpan {
         chunks: &mut Vec<Chunk>,
         depth: usize,
     ) {
-        if self.x.is_some() || self.y.is_some() {
-            // Any absolute position creates a new chunk
-            let values = cascaded.get();
-            chunks.push(Chunk::new(values, self.x, self.y));
-        }
+        let values = cascaded.get();
+        chunks.push(Chunk::new(values, self.x, self.y));
 
         children_to_chunks(
             chunks,
diff --git a/tests/fixtures/reftests/svg1.1/text-align-02-b-ref.png 
b/tests/fixtures/reftests/svg1.1/text-align-02-b-ref.png
new file mode 100644
index 00000000..b9e67243
Binary files /dev/null and b/tests/fixtures/reftests/svg1.1/text-align-02-b-ref.png differ
diff --git a/tests/fixtures/reftests/svg1.1/text-align-02-b.svg 
b/tests/fixtures/reftests/svg1.1/text-align-02-b.svg
new file mode 100644
index 00000000..d172d84c
--- /dev/null
+++ b/tests/fixtures/reftests/svg1.1/text-align-02-b.svg
@@ -0,0 +1,71 @@
+<svg version="1.1" baseProfile="basic" id="svg-root"
+  width="100%" height="100%" viewBox="0 0 480 360"
+  xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink";>
+  <!--======================================================================-->
+  <!--=  SVG 1.1 2nd Edition Test Case                                     =-->
+  <!--======================================================================-->
+  <!--=  Copyright 2009 World Wide Web Consortium, (Massachusetts          =-->
+  <!--=  Institute of Technology, European Research Consortium for         =-->
+  <!--=  Informatics and Mathematics (ERCIM), Keio University).            =-->
+  <!--=  All Rights Reserved.                                              =-->
+  <!--=  See http://www.w3.org/Consortium/Legal/.                          =-->
+  <!--======================================================================-->
+  <d:SVGTestCase xmlns:d="http://www.w3.org/2000/02/svg/testsuite/description/";
+    template-version="1.4" reviewer="SVGWG" author="Jon Ferraiolo" status="accepted"
+    version="$Revision: 1.8 $" testname="$RCSfile: text-align-02-b.svg,v $">
+    <d:testDescription xmlns="http://www.w3.org/1999/xhtml"; 
href="http://www.w3.org/TR/SVG11/text.html#AlignmentProperties";>
+      <p>
+        Test the 'baseline-shift' property (horizontal).
+      </p>
+    </d:testDescription>
+    <d:operatorScript xmlns="http://www.w3.org/1999/xhtml";>
+      <p>
+        Run the test. No interaction required.
+      </p>
+    </d:operatorScript>
+    <d:passCriteria xmlns="http://www.w3.org/1999/xhtml";>
+      <p>
+        This three lines test property 'baseline-shift'.
+        The first line tests 'baseline-shift:7' (i.e., a length for 'baseline-shift').
+        The pink text should be shifted upwards by an amount approximately half of the height of the text.
+        The second line tests 'baseline-shift:-70%' (i.e., a percentage for 'baseline-shift').
+        The pink text should shift downward by about the height of the text.
+        The third line tests the three keywords 'sub', 'super' and 'normal'.
+        The string "sub" should be shifted downwards, the string "super" shifted upwards,
+        and the string "te" (in blue) aligned with the remainder of the text in the line.
+      </p>
+    </d:passCriteria>
+  </d:SVGTestCase>
+  <title id="test-title">$RCSfile: text-align-02-b.svg,v $</title>
+  <defs>
+    <font-face font-family="SVGFreeSansASCII" unicode-range="U+0-7F">
+      <font-face-src>
+        <font-face-uri xlink:href="../resources/SVGFreeSans.svg#ascii"/>
+      </font-face-src>
+    </font-face>
+  </defs>
+  <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+    <text font-size="34" x="5" y="40">Test 'baseline-shift' (horizontal)</text>
+    <g id="baseline-shift" font-size="30" transform="translate(15,120)">
+      <text y="0">
+        Normal<tspan baseline-shift="7" fill="fuchsia">baseline-shift:7</tspan>text
+      </text>
+      <text y="70">
+        Normal<tspan baseline-shift="-70%" fill="fuchsia">baseline-shift:-70%</tspan>text
+      </text>
+      <text y="140">
+        Normal<tspan baseline-shift="sub" fill="fuchsia">sub</tspan><tspan baseline-shift="super" 
fill="green">super</tspan><tspan baseline-shift="baseline" fill="blue">te</tspan>xt
+      </text>
+    </g>
+  </g>
+  <g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
+    <text id="revision" x="10" y="340" stroke="none" fill="black">$Revision: 1.8 $</text>
+  </g>
+  <rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
+  <!-- comment out this watermark once the test is approved -->
+  <!--<g id="draft-watermark">
+    <rect x="1" y="1" width="478" height="20" fill="red" stroke="black" stroke-width="1"/>
+    <text font-family="SVGFreeSansASCII,sans-serif" font-weight="bold" font-size="20" x="240"
+      text-anchor="middle" y="18" stroke-width="0.5" stroke="black" fill="white">DRAFT</text>
+  </g>-->
+</svg>


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