Skip to content

Commit

Permalink
Add test for concat_text method
Browse files Browse the repository at this point in the history
  • Loading branch information
vidy committed Dec 9, 2024
1 parent 51bd665 commit 9db0789
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
10 changes: 5 additions & 5 deletions examples/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ fn main() {
}
}
}
for line in flow.lines {
for w in line.words {
println!("{}", w.text);
}
}
// for line in flow.lines {
// for w in line.words {
// println!("{}", w.text);
// }
// }
// }
}
61 changes: 58 additions & 3 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ use crate::{util::avg, flow::{Word, Rect}};

pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator<Item=&'a TextSpan<E>> + Clone) -> Vec<Word> {
let mut words: Vec<Word> = vec![];
// dbg!(items.clone().map(|s| s).collect::<Vec<_>>());
// gaps between each char

// Calculate gaps between each char, the unit is em, relative to the font size.
let gaps = items.clone()
.flat_map(|s| {
// the transform matrix is from em space to device space
// so we need to invert it
let tr_inv = s.transform.matrix.inverse();
let pos = (tr_inv * s.transform.vector).x();

s.chars.iter()
.filter(|c| !s.text[c.offset..].chars().next().unwrap().is_whitespace())
.map(move |c| (c.pos + pos, c.pos + pos + c.width, s.font_size))
Expand All @@ -26,6 +29,7 @@ pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator<I
let space_gap = (0.5 * font_size).min(2.0 * avg(gaps).unwrap_or(0.0)); //2.0 * gaps[gaps.len()/2];

let mut end = 0.; // trailing edge of the last char
// out中最后一个字符是否是空格
let mut trailing_space = out.chars().last().map(|c| c.is_whitespace()).unwrap_or(true);
let mut word_start_pos = 0.0;
let mut word_start_idx = out.len();
Expand All @@ -38,16 +42,19 @@ pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator<I
let mut pos = 0; // byte index of last char into span.text
let tr_inv = span.transform.matrix.inverse();
let x_off = (tr_inv * span.transform.vector).x();

for c in span.chars.iter() {

// current string of TextChar
let s = &span.text[pos..c.offset];
if c.offset > 0 {
let is_whitespace = s.chars().all(|c| c.is_whitespace());
// 在不为空格的时候, 将 s 写入 out.
if !trailing_space || !is_whitespace {
out.extend(s.nfkc());
}
trailing_space = is_whitespace;
}
// 在 s 不为空格,且有gap 的时候,记录一个 word.
if !trailing_space && c.pos + x_off > end + space_gap {
words.push(Word {
text: out[word_start_idx..].into(),
Expand Down Expand Up @@ -80,6 +87,7 @@ pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator<I
y_max = y_max.max(span.rect.max_y());
}
}

trailing_space = span.text[pos..].chars().all(|c| c.is_whitespace());

out.extend(span.text[pos..].nfkc());
Expand All @@ -95,4 +103,51 @@ pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator<I
});

words
}

#[cfg(test)]
mod tests {
use pathfinder_geometry::{rect::RectF, transform2d::Transform2F};
use pdf_render::{font::OutlineBuilder, Fill, TextChar};

use super::*;

#[test]
fn test_concat_text() {
let text_span: TextSpan<OutlineBuilder> = TextSpan {
rect: RectF::from_points(Vector2F::new(56.8, 55.85077), Vector2F::new(136.26399, 67.85077)),
width: 79.464,
bbox: None,
font_size: 12.0,
font: None,
text: "hello world".to_string(),
chars: vec![
TextChar { offset: 0, pos: 0.0, width: 7.224001 },
TextChar { offset: 1, pos: 7.224001, width: 7.224001 },
TextChar { offset: 2, pos: 14.448002, width: 7.224001 },
TextChar { offset: 3, pos: 21.672003, width: 7.224001 },
TextChar { offset: 4, pos: 28.896004, width: 7.224001 },
TextChar { offset: 5, pos: 36.120003, width: 7.224001 },
TextChar { offset: 6, pos: 43.344, width: 7.224001 },
TextChar { offset: 7, pos: 50.568, width: 7.224001 },
TextChar { offset: 8, pos: 57.792, width: 7.224001 },
TextChar { offset: 9, pos: 65.016, width: 7.224001 },
TextChar { offset: 10, pos: 72.24, width: 7.224001 },
],
color: Fill::Solid(0.0, 0.5019608, 0.0),
alpha: 1.0,
transform: Transform2F::row_major(1.0, 0.0, 56.8, 0.0, 1.0, 67.85077),
mode: pdf::content::TextMode::Fill,
op_nr: 18,
};

let mut output = String::new();
let words = concat_text(&mut output, vec![&text_span].into_iter());

// Assert the concatenated text
assert_eq!(output, "hello world");

// Assert the words
assert_eq!(words.len(), 2); // Expect two words: "hello" and "world"
}
}

0 comments on commit 9db0789

Please sign in to comment.