Commit 2b31e7ec authored by Federico Mena Quintero's avatar Federico Mena Quintero Committed by Federico Mena Quintero

(#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 #363
parent 571f06a8
......@@ -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());
......
......@@ -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);
......
......@@ -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">
......
<?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>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment