[librsvg: 12/37] text.rs: Start logic to turn a NodeText and its children to Chunks
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 12/37] text.rs: Start logic to turn a NodeText and its children to Chunks
- Date: Fri, 28 Dec 2018 03:24:58 +0000 (UTC)
commit e97cbefd025a8b0e0a1955f2d78fc54c089eb1fe
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Oct 30 18:16:30 2018 -0600
text.rs: Start logic to turn a NodeText and its children to Chunks
rsvg_internals/src/text.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
---
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index c5a45640..74a8228f 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -38,11 +38,21 @@ use state::{
///
/// [text chunk]: https://www.w3.org/TR/SVG11/text.html#TextLayoutIntroduction
struct Chunk {
- x: Option<f64>,
- y: Option<f64>,
+ x: Option<Length>,
+ y: Option<Length>,
spans: Vec<Span>,
}
+impl Chunk {
+ fn new(x: Option<Length>, y: Option<Length>) -> Chunk {
+ Chunk {
+ x,
+ y,
+ spans: Vec::new(),
+ }
+ }
+}
+
struct Span {
values: ComputedValues,
text: String,
@@ -138,6 +148,52 @@ impl PositionedSpan {
}
}
+/// Walks the children of a `<text>`, `<tspan>`, or `<tref>` element
+/// and appends chunks/spans from them into the specified `chunks`
+/// array.
+///
+/// `x` and `y` are the absolute position for the first chunk. If the
+/// first child is a `<tspan>` with a specified absolute position, it
+/// will be used instead of the given arguments.
+fn children_to_chunks(
+ chunks: &mut Vec<Chunk>,
+ node: &RsvgNode,
+ cascaded: &CascadedValues<'_>,
+ x: Option<Length>,
+ y: Option<Length>,
+) {
+ let values = cascaded.get();
+
+ for child in node.children() {
+ match child.get_type() {
+ NodeType::Chars => node.with_impl(|chars: &NodeChars| {
+ let span = chars.make_span(&child, &values);
+
+ let num_chunks = chunks.len();
+ if num_chunks > 0 {
+ chunks[num_chunks - 1].spans.push(span);
+ } else {
+ let mut chunk = Chunk::new(x, y);
+ chunk.spans.push(span);
+ chunks.push(chunk);
+ }
+ }),
+
+ NodeType::TSpan => node.with_impl(|tspan: &NodeTSpan| {
+ let cascaded = CascadedValues::new(cascaded, &child);
+ tspan.to_chunks(&child, &cascaded, chunks, x, y);
+ }),
+
+ NodeType::TRef => node.with_impl(|tref: &NodeTRef| {
+ let cascaded = CascadedValues::new(cascaded, &child);
+ tref.to_chunks(&child, &cascaded, chunks, x, y);
+ }),
+
+ _ => (),
+ }
+ }
+}
+
/// In SVG text elements, we use `NodeChars` to store character data. For example,
/// an element like `<text>Foo Bar</text>` will be a `NodeText` with a single child,
/// and the child will be a `NodeChars` with "Foo Bar" for its contents.
@@ -257,6 +313,16 @@ impl NodeText {
dy: Cell::new(Length::default()),
}
}
+
+ fn make_chunks(&self, node: &RsvgNode, cascaded: &CascadedValues<'_>) -> Vec<Chunk> {
+ let mut chunks = Vec::new();
+
+ let x = self.x.get();
+ let y = self.y.get();
+
+ children_to_chunks(&mut chunks, node, cascaded, Some(x), Some(y));
+ chunks
+ }
}
impl NodeTrait for NodeText {
@@ -332,6 +398,19 @@ impl NodeTRef {
}
}
+ fn to_chunks(
+ &self,
+ _node: &RsvgNode,
+ _cascaded: &CascadedValues<'_>,
+ _chunks: &mut Vec<Chunk>,
+ _x: Option<Length>,
+ _y: Option<Length>,
+ ) {
+ // let x = self.x.get().or(x);
+ // let y = self.y.get().or(y);
+ // unimplemented!();
+ }
+
fn measure(
&self,
node: &RsvgNode,
@@ -423,6 +502,20 @@ impl NodeTSpan {
}
}
+ fn to_chunks(
+ &self,
+ node: &RsvgNode,
+ cascaded: &CascadedValues<'_>,
+ chunks: &mut Vec<Chunk>,
+ x: Option<Length>,
+ y: Option<Length>,
+ ) {
+ let x = self.x.get().or(x);
+ let y = self.y.get().or(y);
+
+ children_to_chunks(chunks, node, cascaded, x, y);
+ }
+
fn measure(
&self,
node: &RsvgNode,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]