[librsvg: 16/20] Extract the dx/dy from the first span of a chunk and make it the chunk's own dx/dy
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 16/20] Extract the dx/dy from the first span of a chunk and make it the chunk's own dx/dy
- Date: Thu, 21 Oct 2021 00:26:08 +0000 (UTC)
commit 4d617708aacfb4fc76ed97a6aa7c883a4fdbd0e0
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Oct 20 18:17:18 2021 -0500
Extract the dx/dy from the first span of a chunk and make it the chunk's own dx/dy
Librsvg does not yet support arrays of dx/dy values in those
attributes. So, the single value they support acts as if it overwrote
the one from the parent element. That is, in
<text dx="-1">
<tspan dx="2">
...
</tspan>
</tspan>
The only dx ever used will be dx=2, since it would override the -1.
Here, dx=2 becomes part of the first and only chunk.
At the end, we add the chunk's dx/dy to each positioned span,
independend of the chunk's internal layout.
This finally makes
https://upload.wikimedia.org/wikipedia/commons/f/f7/S-Bahn_RheinNeckar2020.svg
render correctly. Yay!!!
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/616>
src/text.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 58 insertions(+), 12 deletions(-)
---
diff --git a/src/text.rs b/src/text.rs
index 6ff4220d..bbd2d539 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -48,6 +48,8 @@ struct MeasuredChunk {
values: Rc<ComputedValues>,
x: Option<f64>,
y: Option<f64>,
+ dx: f64,
+ dy: f64,
spans: Vec<MeasuredSpan>,
link: Option<String>,
}
@@ -122,16 +124,32 @@ impl MeasuredChunk {
text_writing_mode: WritingMode,
draw_ctx: &DrawingCtx,
) -> MeasuredChunk {
- let measured_spans: Vec<MeasuredSpan> = chunk
+ let mut measured_spans: Vec<MeasuredSpan> = chunk
.spans
.iter()
.map(|span| MeasuredSpan::from_span(span, text_writing_mode, draw_ctx))
.collect();
+ // The first span contains the (dx, dy) that will be applied to the whole chunk.
+ // Make them 0 in the span, and extract the values to set them on the chunk.
+ // This is a hack until librsvg adds support for multiple dx/dy values per text/tspan.
+
+ let (chunk_dx, chunk_dy) = if let Some(first) = measured_spans.first_mut() {
+ let dx = first.dx;
+ let dy = first.dy;
+ first.dx = 0.0;
+ first.dy = 0.0;
+ (dx, dy)
+ } else {
+ (0.0, 0.0)
+ };
+
MeasuredChunk {
values: chunk.values.clone(),
x: chunk.x,
y: chunk.y,
+ dx: chunk_dx,
+ dy: chunk_dy,
spans: measured_spans,
link: chunk.link.clone(),
}
@@ -219,17 +237,20 @@ impl PositionedChunk {
);
// Apply the text-anchor offset to each individually-positioned span, and compute the
- // start position of the next chunk.
+ // start position of the next chunk. Also add in the chunk's dx/dy.
let mut next_chunk_x = chunk_x;
let mut next_chunk_y = chunk_y;
for pspan in &mut positioned {
- pspan.rendered_position.0 += chunk_x + anchor_offset.0;
- pspan.rendered_position.1 += chunk_y + anchor_offset.1;
-
- next_chunk_x = chunk_x + pspan.next_span_position.0 + anchor_offset.0;
- next_chunk_y = chunk_y + pspan.next_span_position.1 + anchor_offset.1;
+ // Add the chunk's position, plus the text-anchor offset, plus the chunk's dx/dy.
+ // This last term is a hack until librsvg adds support for multiple dx/dy values per text/tspan;
+ // see the corresponding part in MeasuredChunk::from_chunk().
+ pspan.rendered_position.0 += chunk_x + anchor_offset.0 + measured.dx;
+ pspan.rendered_position.1 += chunk_y + anchor_offset.1 + measured.dy;
+
+ next_chunk_x = chunk_x + pspan.next_span_position.0 + anchor_offset.0 + measured.dx;
+ next_chunk_y = chunk_y + pspan.next_span_position.1 + anchor_offset.1 + measured.dy;
}
PositionedChunk {
@@ -1124,17 +1145,32 @@ mod tests {
use TextAnchor::*;
assert_eq!(
- text_anchor_offset(Start, Ltr, WritingMode::Lr, Rect::from_size(1.0, 2.0).translate((5.0, 6.0))),
+ text_anchor_offset(
+ Start,
+ Ltr,
+ WritingMode::Lr,
+ Rect::from_size(1.0, 2.0).translate((5.0, 6.0))
+ ),
(-5.0, 0.0)
);
assert_eq!(
- text_anchor_offset(Middle, Ltr, WritingMode::Lr, Rect::from_size(1.0, 2.0).translate((5.0,
6.0))),
+ text_anchor_offset(
+ Middle,
+ Ltr,
+ WritingMode::Lr,
+ Rect::from_size(1.0, 2.0).translate((5.0, 6.0))
+ ),
(-5.5, 0.0)
);
assert_eq!(
- text_anchor_offset(End, Ltr, WritingMode::Lr, Rect::from_size(1.0, 2.0).translate((5.0, 6.0))),
+ text_anchor_offset(
+ End,
+ Ltr,
+ WritingMode::Lr,
+ Rect::from_size(1.0, 2.0).translate((5.0, 6.0))
+ ),
(-6.0, 0.0)
);
}
@@ -1145,11 +1181,21 @@ mod tests {
use TextAnchor::*;
assert_eq!(
- text_anchor_offset(Start, Rtl, WritingMode::Rl, Rect::from_size(1.0, 2.0).translate((5.0, 6.0))),
+ text_anchor_offset(
+ Start,
+ Rtl,
+ WritingMode::Rl,
+ Rect::from_size(1.0, 2.0).translate((5.0, 6.0))
+ ),
(-6.0, 0.0)
);
assert_eq!(
- text_anchor_offset(Middle, Rtl, WritingMode::Rl, Rect::from_size(1.0, 2.0).translate((5.0,
6.0))),
+ text_anchor_offset(
+ Middle,
+ Rtl,
+ WritingMode::Rl,
+ Rect::from_size(1.0, 2.0).translate((5.0, 6.0))
+ ),
(-5.5, 0.0)
);
assert_eq!(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]