use rdocx_oxml::borders::CT_PBdr;
use rdocx_oxml::shared::ST_Jc;
use crate::line::LayoutLine;
use crate::output::Color;
use crate::table::TableBlock;
#[derive(Debug, Clone)]
pub enum LayoutBlock {
Paragraph(ParagraphBlock),
Table(TableBlock),
}
impl LayoutBlock {
pub fn total_height(&self) -> f64 {
match self {
LayoutBlock::Paragraph(p) => p.total_height(),
LayoutBlock::Table(t) => t.total_height(),
}
}
pub fn content_height(&self) -> f64 {
match self {
LayoutBlock::Paragraph(p) => p.content_height(),
LayoutBlock::Table(t) => t.content_height(),
}
}
pub fn space_before(&self) -> f64 {
match self {
LayoutBlock::Paragraph(p) => p.space_before,
LayoutBlock::Table(_) => 0.0,
}
}
pub fn space_after(&self) -> f64 {
match self {
LayoutBlock::Paragraph(p) => p.space_after,
LayoutBlock::Table(_) => 0.0,
}
}
pub fn keep_next(&self) -> bool {
match self {
LayoutBlock::Paragraph(p) => p.keep_next,
LayoutBlock::Table(_) => false,
}
}
pub fn keep_lines(&self) -> bool {
match self {
LayoutBlock::Paragraph(p) => p.keep_lines,
LayoutBlock::Table(_) => false,
}
}
pub fn page_break_before(&self) -> bool {
match self {
LayoutBlock::Paragraph(p) => p.page_break_before,
LayoutBlock::Table(_) => false,
}
}
pub fn widow_control(&self) -> bool {
match self {
LayoutBlock::Paragraph(p) => p.widow_control,
LayoutBlock::Table(_) => false,
}
}
}
#[derive(Debug, Clone)]
pub struct ParagraphBlock {
pub lines: Vec<LayoutLine>,
pub space_before: f64,
pub space_after: f64,
pub borders: Option<CT_PBdr>,
pub shading: Option<Color>,
pub indent_left: f64,
pub indent_right: f64,
pub jc: Option<ST_Jc>,
pub keep_next: bool,
pub keep_lines: bool,
pub page_break_before: bool,
pub widow_control: bool,
pub heading_level: Option<u32>,
pub heading_text: Option<String>,
}
impl ParagraphBlock {
pub fn content_height(&self) -> f64 {
self.lines.iter().map(|l| l.height).sum()
}
pub fn total_height(&self) -> f64 {
self.space_before + self.content_height() + self.space_after
}
pub fn line_count(&self) -> usize {
self.lines.len()
}
}
pub fn build_paragraph_block(
lines: Vec<LayoutLine>,
space_before: f64,
space_after: f64,
borders: Option<CT_PBdr>,
shading: Option<Color>,
indent_left: f64,
indent_right: f64,
jc: Option<ST_Jc>,
keep_next: bool,
keep_lines: bool,
page_break_before: bool,
widow_control: bool,
) -> ParagraphBlock {
ParagraphBlock {
lines,
space_before,
space_after,
borders,
shading,
indent_left,
indent_right,
jc,
keep_next,
keep_lines,
page_break_before,
widow_control,
heading_level: None,
heading_text: None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn paragraph_block_height() {
let block = ParagraphBlock {
lines: vec![
LayoutLine {
items: vec![],
width: 0.0,
ascent: 10.0,
descent: 3.0,
height: 13.0,
indent_left: 0.0,
available_width: 468.0,
is_last: false,
},
LayoutLine {
items: vec![],
width: 0.0,
ascent: 10.0,
descent: 3.0,
height: 13.0,
indent_left: 0.0,
available_width: 468.0,
is_last: true,
},
],
space_before: 6.0,
space_after: 8.0,
borders: None,
shading: None,
indent_left: 0.0,
indent_right: 0.0,
jc: None,
keep_next: false,
keep_lines: false,
page_break_before: false,
widow_control: true,
heading_level: None,
heading_text: None,
};
assert!((block.content_height() - 26.0).abs() < 0.01);
assert!((block.total_height() - 40.0).abs() < 0.01);
}
}