use crate::text_block::TextBlock;
use crate::text_frame::TextFrame;
use crate::text_table::TextTable;
use crate::{Alignment, BlockFormat, FrameFormat, ListStyle, TextFormat};
#[derive(Clone)]
pub enum FlowElement {
Block(TextBlock),
Table(TextTable),
Frame(TextFrame),
}
impl FlowElement {
pub fn snapshot(&self) -> FlowElementSnapshot {
match self {
FlowElement::Block(b) => FlowElementSnapshot::Block(b.snapshot()),
FlowElement::Table(t) => FlowElementSnapshot::Table(t.snapshot()),
FlowElement::Frame(f) => FlowElementSnapshot::Frame(f.snapshot()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FragmentContent {
Text {
text: String,
format: TextFormat,
offset: usize,
length: usize,
element_id: u64,
word_starts: Vec<u8>,
},
Image {
name: String,
width: u32,
height: u32,
quality: u32,
format: TextFormat,
offset: usize,
element_id: u64,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct BlockSnapshot {
pub block_id: usize,
pub position: usize,
pub length: usize,
pub text: String,
pub fragments: Vec<FragmentContent>,
pub block_format: BlockFormat,
pub list_info: Option<ListInfo>,
pub parent_frame_id: Option<usize>,
pub table_cell: Option<TableCellContext>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TableCellContext {
pub table_id: usize,
pub row: usize,
pub column: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ListInfo {
pub list_id: usize,
pub style: ListStyle,
pub indent: u8,
pub marker: String,
pub item_index: usize,
}
#[derive(Clone)]
pub struct TableCellRef {
pub table: TextTable,
pub row: usize,
pub column: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CellRange {
pub table_id: usize,
pub start_row: usize,
pub start_col: usize,
pub end_row: usize,
pub end_col: usize,
}
impl CellRange {
pub fn expand_for_spans(mut self, cells: &[(usize, usize, usize, usize)]) -> Self {
loop {
let mut expanded = false;
for &(row, col, rs, cs) in cells {
let cell_bottom = row + rs - 1;
let cell_right = col + cs - 1;
if row <= self.end_row
&& cell_bottom >= self.start_row
&& col <= self.end_col
&& cell_right >= self.start_col
{
if row < self.start_row {
self.start_row = row;
expanded = true;
}
if cell_bottom > self.end_row {
self.end_row = cell_bottom;
expanded = true;
}
if col < self.start_col {
self.start_col = col;
expanded = true;
}
if cell_right > self.end_col {
self.end_col = cell_right;
expanded = true;
}
}
}
if !expanded {
break;
}
}
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SelectionKind {
None,
Text,
Cells(CellRange),
Mixed {
cell_range: CellRange,
text_before: bool,
text_after: bool,
},
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct TableFormat {
pub border: Option<i32>,
pub cell_spacing: Option<i32>,
pub cell_padding: Option<i32>,
pub width: Option<i32>,
pub alignment: Option<Alignment>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CellFormat {
pub padding: Option<i32>,
pub border: Option<i32>,
pub vertical_alignment: Option<CellVerticalAlignment>,
pub background_color: Option<String>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum CellVerticalAlignment {
#[default]
Top,
Middle,
Bottom,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TableSnapshot {
pub table_id: usize,
pub rows: usize,
pub columns: usize,
pub column_widths: Vec<i32>,
pub format: TableFormat,
pub cells: Vec<CellSnapshot>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CellSnapshot {
pub row: usize,
pub column: usize,
pub row_span: usize,
pub column_span: usize,
pub format: CellFormat,
pub blocks: Vec<BlockSnapshot>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct FlowSnapshot {
pub elements: Vec<FlowElementSnapshot>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FlowElementSnapshot {
Block(BlockSnapshot),
Table(TableSnapshot),
Frame(FrameSnapshot),
}
#[derive(Debug, Clone, PartialEq)]
pub struct FrameSnapshot {
pub frame_id: usize,
pub format: FrameFormat,
pub elements: Vec<FlowElementSnapshot>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FormatChangeKind {
Block,
Character,
List,
}