Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions crates/office2pdf/src/ir/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,39 @@ pub struct ParagraphStyle {
pub heading_level: Option<u8>,
/// Text direction for bidirectional rendering (RTL for Arabic/Hebrew).
pub direction: Option<TextDirection>,
/// Custom tab stop positions for this paragraph.
pub tab_stops: Option<Vec<TabStop>>,
}

/// A custom tab stop definition.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct TabStop {
/// Position in points from the left margin.
pub position: f64,
/// Alignment of text at this tab stop.
pub alignment: TabAlignment,
/// Leader character filling the space before this tab stop.
pub leader: TabLeader,
}

/// Tab stop alignment type.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TabAlignment {
#[default]
Left,
Center,
Right,
Decimal,
}

/// Leader character for a tab stop.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TabLeader {
#[default]
None,
Dot,
Hyphen,
Underscore,
}

/// Text direction for bidirectional (BiDi) rendering.
Expand Down
35 changes: 35 additions & 0 deletions crates/office2pdf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,41 @@ mod tests {
assert!(pdf.starts_with(b"%PDF"));
}

#[test]
fn test_render_document_with_tab_leader() {
let doc = Document {
metadata: Metadata::default(),
pages: vec![Page::Flow(FlowPage {
size: PageSize::default(),
margins: Margins::default(),
content: vec![Block::Paragraph(Paragraph {
style: ParagraphStyle {
tab_stops: Some(vec![TabStop {
position: 144.0,
alignment: TabAlignment::Left,
leader: TabLeader::Dot,
}]),
..ParagraphStyle::default()
},
runs: vec![Run {
text: "Heading\t12".to_string(),
style: TextStyle::default(),
href: None,
footnote: None,
}],
})],
header: None,
footer: None,
columns: None,
})],
styles: StyleSheet::default(),
};

let pdf = render_document(&doc).unwrap();
assert!(!pdf.is_empty());
assert!(pdf.starts_with(b"%PDF"));
}

#[test]
fn test_render_document_styled_text() {
let doc = Document {
Expand Down
Loading