Move to top-left default positioning 📐
This commit is contained in:
parent
221934df4b
commit
3e9f42661e
@ -27,6 +27,8 @@ pub struct Page {
|
||||
/// A text layouting action.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TextAction {
|
||||
/// Move to an absolute position.
|
||||
MoveAbsolute(Position),
|
||||
/// Move from the _start_ of the current line by an (x, y) offset.
|
||||
MoveNewline(Position),
|
||||
/// Write text starting at the current position.
|
||||
|
@ -8,9 +8,9 @@ use pdf::doc::{Catalog, PageTree, Page, Resource, Text};
|
||||
use pdf::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags};
|
||||
use pdf::font::{GlyphUnit, CMap, CMapEncoding, WidthRecord, FontStream};
|
||||
|
||||
use crate::doc::{Document, TextAction};
|
||||
use crate::doc::{Document, Page as DocPage, TextAction};
|
||||
use crate::font::{Font, FontError};
|
||||
use crate::layout::Size;
|
||||
use crate::layout::{Size, Position};
|
||||
|
||||
|
||||
/// Exports documents into _PDFs_.
|
||||
@ -96,8 +96,8 @@ impl<'d, W: Write> PdfEngine<'d, W> {
|
||||
/// Write the complete document.
|
||||
fn write(&mut self) -> PdfResult<usize> {
|
||||
self.writer.write_header(&Version::new(1, 7))?;
|
||||
self.write_page_tree()?;
|
||||
self.write_pages()?;
|
||||
self.write_contents()?;
|
||||
self.write_fonts()?;
|
||||
self.writer.write_xref_table()?;
|
||||
self.writer.write_trailer(&Trailer::new(self.offsets.catalog))?;
|
||||
@ -105,13 +105,14 @@ impl<'d, W: Write> PdfEngine<'d, W> {
|
||||
}
|
||||
|
||||
/// Write the document catalog and page tree.
|
||||
fn write_pages(&mut self) -> PdfResult<()> {
|
||||
fn write_page_tree(&mut self) -> PdfResult<()> {
|
||||
// The document catalog
|
||||
self.writer.write_obj(self.offsets.catalog, &Catalog::new(self.offsets.page_tree))?;
|
||||
|
||||
// The font resources
|
||||
let offset = self.offsets.fonts.0;
|
||||
let fonts = (0 .. self.fonts.len())
|
||||
.map(|i| Resource::Font((i + 1) as u32, self.offsets.fonts.0 + 5 * i as u32));
|
||||
.map(|i| Resource::Font((i + 1) as u32, offset + 5 * i as u32));
|
||||
|
||||
// The root page tree
|
||||
self.writer.write_obj(self.offsets.page_tree, PageTree::new()
|
||||
@ -131,21 +132,28 @@ impl<'d, W: Write> PdfEngine<'d, W> {
|
||||
}
|
||||
|
||||
/// Write the contents of all pages.
|
||||
fn write_contents(&mut self) -> PdfResult<()> {
|
||||
fn write_pages(&mut self) -> PdfResult<()> {
|
||||
for (id, page) in ids(self.offsets.contents).zip(&self.doc.pages) {
|
||||
self.write_text_actions(id, &page.actions)?;
|
||||
self.write_page(id, &page)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write a series of text actions.
|
||||
fn write_text_actions(&mut self, id: u32, actions: &[TextAction]) -> PdfResult<()> {
|
||||
/// Write the content of a page.
|
||||
fn write_page(&mut self, id: u32, page: &DocPage) -> PdfResult<()> {
|
||||
let mut font = 0;
|
||||
let mut text = Text::new();
|
||||
|
||||
for action in actions {
|
||||
text.tm(1.0, 0.0, 0.0, 1.0, 0.0, page.height.to_points());
|
||||
|
||||
for action in &page.actions {
|
||||
match action {
|
||||
TextAction::MoveNewline(x, y) => { text.td(x.to_points(), y.to_points()); },
|
||||
TextAction::MoveAbsolute(pos) => {
|
||||
let x = pos.x.to_points();
|
||||
let y = (page.height - pos.y).to_points();
|
||||
text.tm(1.0, 0.0, 0.0, 1.0, x, y);
|
||||
},
|
||||
TextAction::MoveNewline(pos) => { text.td(pos.x.to_points(), -pos.y.to_points()); },
|
||||
TextAction::WriteText(string) => { text.tj(self.fonts[font].encode(&string)); },
|
||||
TextAction::SetFont(id, size) => {
|
||||
font = *id;
|
||||
|
@ -22,7 +22,7 @@ impl<'a, 'p> BoxLayouter<'a, 'p> {
|
||||
|
||||
/// Add a sublayout.
|
||||
pub fn add_layout_absolute(&mut self, position: Position, layout: Layout) {
|
||||
self.actions.push(TextAction::MoveNewline(position));
|
||||
self.actions.push(TextAction::MoveAbsolute(position));
|
||||
self.actions.extend(layout.actions);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,12 @@ pub struct Position {
|
||||
pub y: Size,
|
||||
}
|
||||
|
||||
impl Position {
|
||||
/// Create a zeroed position.
|
||||
#[inline]
|
||||
pub fn zero() -> Position { Position { x: Size::zero(), y: Size::zero() } }
|
||||
}
|
||||
|
||||
/// Size of a box in 2-dimensional space.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Default)]
|
||||
pub struct Extent {
|
||||
|
@ -145,8 +145,9 @@ impl<'a, 'p> TextFinisher<'a, 'p> {
|
||||
let mut units = Vec::new();
|
||||
mem::swap(&mut self.layouter.units, &mut units);
|
||||
|
||||
// Move to the top-left corner of the layout space.
|
||||
self.move_start();
|
||||
// Move from the origin one line below because the y-component of the origin is the
|
||||
// baseline.
|
||||
self.move_newline(1.0);
|
||||
|
||||
for unit in units {
|
||||
match unit {
|
||||
@ -206,29 +207,18 @@ impl<'a, 'p> TextFinisher<'a, 'p> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Move to the top-left corner of the layout space.
|
||||
fn move_start(&mut self) {
|
||||
self.actions.push(TextAction::MoveNewline(Position {
|
||||
x: Size::zero(),
|
||||
y: self.layouter.ctx.max_extent.height
|
||||
- Size::from_points(self.layouter.ctx.text_style.font_size)
|
||||
}));
|
||||
}
|
||||
|
||||
/// Move to the next line. A factor of 1.0 uses the default line spacing.
|
||||
fn move_newline(&mut self, factor: f32) {
|
||||
if self.active_font != std::usize::MAX {
|
||||
let vertical = Size::from_points(self.layouter.ctx.text_style.font_size)
|
||||
* self.layouter.ctx.text_style.line_spacing
|
||||
* factor;
|
||||
let vertical = Size::from_points(self.layouter.ctx.text_style.font_size)
|
||||
* self.layouter.ctx.text_style.line_spacing
|
||||
* factor;
|
||||
|
||||
self.actions.push(TextAction::MoveNewline(Position {
|
||||
x: Size::zero(),
|
||||
y: -vertical
|
||||
}));
|
||||
self.actions.push(TextAction::MoveNewline(Position {
|
||||
x: Size::zero(),
|
||||
y: vertical
|
||||
}));
|
||||
|
||||
self.current_width = Size::zero();
|
||||
}
|
||||
self.current_width = Size::zero();
|
||||
}
|
||||
|
||||
/// Output a text action containing the buffered text and reset the buffer.
|
||||
|
Loading…
x
Reference in New Issue
Block a user