[librsvg: 13/27] (#687) - text.rs - Don't clone the ComputedValues during text rendering




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]