diff --git a/examples/text.rs b/examples/text.rs index 1d688dd..beb0798 100644 --- a/examples/text.rs +++ b/examples/text.rs @@ -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); + // } + // } // } } diff --git a/src/text.rs b/src/text.rs index 7359f9a..fef537b 100644 --- a/src/text.rs +++ b/src/text.rs @@ -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> + Clone) -> Vec { let mut words: Vec = vec![]; - // dbg!(items.clone().map(|s| s).collect::>()); - // 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)) @@ -26,6 +29,7 @@ pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator(out: &mut String, items: impl Iterator 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(), @@ -80,6 +87,7 @@ pub fn concat_text<'a, E: Encoder + 'a>(out: &mut String, items: impl Iterator(out: &mut String, items: impl Iterator = 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" + } } \ No newline at end of file