fn new(table: Arc<Table>, device: &dyn Device, min_width: usize, look: &Look) -> Self {
use Axis2::*;
- let n = table.n.clone();
+ let n = table.n;
// Figure out rule widths.
//
// `rules[Y]` is horizontal rules.
let rules = EnumMap::from_fn(|axis| {
(0..=n[axis])
- .map(|z| measure_rule(device, &*table, axis, z))
+ .map(|z| measure_rule(device, &table, axis, z))
.collect::<Vec<_>>()
});
// multiple columns.
let mut unspanned_columns = [vec![0; n.x()], vec![0; n.x()]];
for cell in table.cells().filter(|cell| cell.col_span() == 1) {
- let mut w = device.measure_cell_width(&DrawCell::new(cell.inner(), &*table));
+ let mut w = device.measure_cell_width(&DrawCell::new(cell.inner(), &table));
if device.params().px_size.is_some() {
if let Some(region) = table.heading_region(cell.coord) {
let wr = &heading_widths[region];
.and_then(|x_break| {
x_break.next(
device,
- (device.params().size[Axis2::X] as f64 / self.scale as f64) as usize,
+ (device.params().size[Axis2::X] as f64 / self.scale) as usize,
)
})
.map(|page| Break::new(page, Axis2::Y));
}
}
-#[cfg(test)]
-mod test {
- use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
-
- use crate::output::text::new_line_breaks;
-
- #[test]
- fn unicode_width() {
- // `\n` is a control character, so [UnicodeWidthChar] considers it to
- // have no width.
- assert_eq!('\n'.width(), None);
-
- // But [UnicodeWidthStr] has a different idea.
- assert_eq!("\n".width(), 1);
- assert_eq!("\r\n".width(), 1);
- }
-
- #[track_caller]
- fn test_line_breaks(input: &str, width: usize, expected: Vec<&str>) {
- let actual = new_line_breaks(input, width).collect::<Vec<_>>();
- if expected != actual {
- panic!("filling {input:?} to {width} columns:\nexpected: {expected:?}\nactual: {actual:?}");
- }
- }
- #[test]
- fn line_breaks() {
- for width in 0..=6 {
- test_line_breaks("abc def ghi", width, vec!["abc", "def", "ghi"]);
- }
- for width in 7..=10 {
- test_line_breaks("abc def ghi", width, vec!["abc def", "ghi"]);
- }
- test_line_breaks("abc def ghi", 11, vec!["abc def ghi"]);
-
- for width in 0..=6 {
- test_line_breaks("abc def ghi", width, vec!["abc", "def", "ghi"]);
- }
- test_line_breaks("abc def ghi", 7, vec!["abc", "def ghi"]);
- for width in 8..=11 {
- test_line_breaks("abc def ghi", width, vec!["abc def", "ghi"]);
- }
- test_line_breaks("abc def ghi", 12, vec!["abc def ghi"]);
-
- test_line_breaks("abc\ndef\nghi", 2, vec!["abc", "def", "ghi"]);
- }
-}
-
impl Driver for TextDriver {
fn name(&self) -> Cow<'static, str> {
Cow::from("text")
HorzAlign::Left => bb[X].start,
HorzAlign::Center => (bb[X].start + bb[X].end - width + 1) / 2,
};
- let Some((x, text)) = clip_text(&text, &(x..x + width), &clip[X]) else {
+ let Some((x, text)) = clip_text(text, &(x..x + width), &clip[X]) else {
continue;
};
unimplemented!()
}
}
+
+#[cfg(test)]
+mod test {
+ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
+
+ use crate::output::text::new_line_breaks;
+
+ #[test]
+ fn unicode_width() {
+ // `\n` is a control character, so [UnicodeWidthChar] considers it to
+ // have no width.
+ assert_eq!('\n'.width(), None);
+
+ // But [UnicodeWidthStr] has a different idea.
+ assert_eq!("\n".width(), 1);
+ assert_eq!("\r\n".width(), 1);
+ }
+
+ #[track_caller]
+ fn test_line_breaks(input: &str, width: usize, expected: Vec<&str>) {
+ let actual = new_line_breaks(input, width).collect::<Vec<_>>();
+ if expected != actual {
+ panic!("filling {input:?} to {width} columns:\nexpected: {expected:?}\nactual: {actual:?}");
+ }
+ }
+ #[test]
+ fn line_breaks() {
+ for width in 0..=6 {
+ test_line_breaks("abc def ghi", width, vec!["abc", "def", "ghi"]);
+ }
+ for width in 7..=10 {
+ test_line_breaks("abc def ghi", width, vec!["abc def", "ghi"]);
+ }
+ test_line_breaks("abc def ghi", 11, vec!["abc def ghi"]);
+
+ for width in 0..=6 {
+ test_line_breaks("abc def ghi", width, vec!["abc", "def", "ghi"]);
+ }
+ test_line_breaks("abc def ghi", 7, vec!["abc", "def ghi"]);
+ for width in 8..=11 {
+ test_line_breaks("abc def ghi", width, vec!["abc def", "ghi"]);
+ }
+ test_line_breaks("abc def ghi", 12, vec!["abc def ghi"]);
+
+ test_line_breaks("abc\ndef\nghi", 2, vec!["abc", "def", "ghi"]);
+ }
+}
}
}
+pub fn clip_text<'a>(
+ text: &'a str,
+ bb: &Range<usize>,
+ clip: &Range<usize>,
+) -> Option<(usize, &'a str)> {
+ let mut x = bb.start;
+ let mut width = bb.len();
+
+ let mut iter = text.chars();
+ while x < clip.start {
+ let c = iter.next()?;
+ if let Some(w) = c.width() {
+ x += w;
+ width = width.checked_sub(w)?;
+ }
+ }
+ if x + width > clip.end {
+ if x >= clip.end {
+ return None;
+ }
+
+ while x + width > clip.end {
+ let c = iter.next_back()?;
+ if let Some(w) = c.width() {
+ width = width.checked_sub(w)?;
+ }
+ }
+ }
+ Some((x, iter.as_str()))
+}
+
#[cfg(test)]
mod test {
use super::{Emphasis, TextLine};
}
}
}
-
-pub fn clip_text<'a>(
- text: &'a str,
- bb: &Range<usize>,
- clip: &Range<usize>,
-) -> Option<(usize, &'a str)> {
- let mut x = bb.start;
- let mut width = bb.len();
-
- let mut iter = text.chars();
- while x < clip.start {
- let c = iter.next()?;
- if let Some(w) = c.width() {
- x += w;
- width = width.checked_sub(w)?;
- }
- }
- if x + width > clip.end {
- if x >= clip.end {
- return None;
- }
-
- while x + width > clip.end {
- let c = iter.next_back()?;
- if let Some(w) = c.width() {
- width = width.checked_sub(w)?;
- }
- }
- }
- Some((x, iter.as_str()))
-}