[librsvg: 13/27] (#687) - text.rs - Don't clone the ComputedValues during text rendering
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 13/27] (#687) - text.rs - Don't clone the ComputedValues during text rendering
- Date: Mon, 10 May 2021 16:06:43 +0000 (UTC)
commit 81d1d4950f005e0dd7226754e202b9198a68b262
Author: Federico Mena Quintero <federico gnome org>
Date: Fri May 7 20:53:42 2021 -0500
(#687) - text.rs - Don't clone the ComputedValues during text rendering
All the chunk/span stages share a few immutable ComputedValues; there
is no need to clone the whole struct. Instead, Rc it at strategic
spots (basically when we extract a new one from a CascadedValues).
Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/687
src/text.rs | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
---
diff --git a/src/text.rs b/src/text.rs
index 533d1d05..30757a07 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -2,6 +2,7 @@
use markup5ever::{expanded_name, local_name, namespace_url, ns};
use std::cell::RefCell;
+use std::rc::Rc;
use crate::bbox::BoundingBox;
use crate::document::{AcquiredNodes, NodeId};
@@ -34,14 +35,14 @@ use crate::xml::Attributes;
///
/// [text chunk]: https://www.w3.org/TR/SVG11/text.html#TextLayoutIntroduction
struct Chunk {
- values: ComputedValues,
+ values: Rc<ComputedValues>,
x: Option<f64>,
y: Option<f64>,
spans: Vec<Span>,
}
struct MeasuredChunk {
- values: ComputedValues,
+ values: Rc<ComputedValues>,
x: Option<f64>,
y: Option<f64>,
advance: (f64, f64),
@@ -55,7 +56,7 @@ struct PositionedChunk {
}
struct Span {
- values: ComputedValues,
+ values: Rc<ComputedValues>,
text: String,
dx: f64,
dy: f64,
@@ -63,7 +64,7 @@ struct Span {
}
struct MeasuredSpan {
- values: ComputedValues,
+ values: Rc<ComputedValues>,
layout: pango::Layout,
_layout_size: (f64, f64),
advance: (f64, f64),
@@ -73,7 +74,7 @@ struct MeasuredSpan {
struct PositionedSpan {
layout: pango::Layout,
- values: ComputedValues,
+ values: Rc<ComputedValues>,
_position: (f64, f64),
rendered_position: (f64, f64),
next_span_x: f64,
@@ -83,7 +84,7 @@ struct PositionedSpan {
impl Chunk {
fn new(values: &ComputedValues, x: Option<f64>, y: Option<f64>) -> Chunk {
Chunk {
- values: values.clone(),
+ values: Rc::new(values.clone()),
x,
y,
spans: Vec::new(),
@@ -173,7 +174,7 @@ fn text_anchor_advance(
}
impl Span {
- fn new(text: &str, values: ComputedValues, dx: f64, dy: f64, depth: usize) -> Span {
+ fn new(text: &str, values: Rc<ComputedValues>, dx: f64, dy: f64, depth: usize) -> Span {
Span {
values,
text: text.to_string(),
@@ -188,7 +189,7 @@ impl MeasuredSpan {
fn from_span(span: &Span, draw_ctx: &DrawingCtx) -> MeasuredSpan {
let values = span.values.clone();
- let layout = create_pango_layout(draw_ctx, &values, &span.text);
+ let layout = create_pango_layout(draw_ctx, &*values, &span.text);
let (w, h) = layout.get_size();
let w = f64::from(w) / f64::from(pango::SCALE);
@@ -280,7 +281,7 @@ fn children_to_chunks(
let values = cascaded.get();
child
.borrow_chars()
- .to_chunks(&child, values, chunks, dx, dy, depth);
+ .to_chunks(&child, Rc::new(values.clone()), chunks, dx, dy, depth);
} else {
assert!(child.is_element());
@@ -376,19 +377,19 @@ impl Chars {
fn make_span(
&self,
node: &Node,
- values: &ComputedValues,
+ values: Rc<ComputedValues>,
dx: f64,
dy: f64,
depth: usize,
) -> Option<Span> {
- self.ensure_normalized_string(node, values);
+ self.ensure_normalized_string(node, &*values);
if self.space_normalized.borrow().as_ref().unwrap() == "" {
None
} else {
Some(Span::new(
self.space_normalized.borrow().as_ref().unwrap(),
- values.clone(),
+ values,
dx,
dy,
depth,
@@ -399,7 +400,7 @@ impl Chars {
fn to_chunks(
&self,
node: &Node,
- values: &ComputedValues,
+ values: Rc<ComputedValues>,
chunks: &mut Vec<Chunk>,
dx: f64,
dy: f64,
@@ -555,7 +556,12 @@ impl TRef {
if let Ok(acquired) = acquired_nodes.acquire(link) {
let c = acquired.get();
- extract_chars_children_to_chunks_recursively(chunks, &c, values, depth);
+ extract_chars_children_to_chunks_recursively(
+ chunks,
+ &c,
+ Rc::new(values.clone()),
+ depth,
+ );
} else {
rsvg_log!(
"element {} references a nonexistent text source \"{}\"",
@@ -569,10 +575,12 @@ impl TRef {
fn extract_chars_children_to_chunks_recursively(
chunks: &mut Vec<Chunk>,
node: &Node,
- values: &ComputedValues,
+ values: Rc<ComputedValues>,
depth: usize,
) {
for child in node.children() {
+ let values = values.clone();
+
if child.is_chars() {
child
.borrow_chars()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]