summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc.rs2
-rw-r--r--src/export/pdf.rs30
-rw-r--r--src/layout/boxed.rs2
-rw-r--r--src/layout/size.rs6
-rw-r--r--src/layout/text.rs32
5 files changed, 39 insertions, 33 deletions
diff --git a/src/doc.rs b/src/doc.rs
index a7d44897..304b4936 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -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.
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index 87b9d52c..b521079e 100644
--- a/src/export/pdf.rs
+++ b/src/export/pdf.rs
@@ -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;
diff --git a/src/layout/boxed.rs b/src/layout/boxed.rs
index cfdf51f2..c240db0b 100644
--- a/src/layout/boxed.rs
+++ b/src/layout/boxed.rs
@@ -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);
}
}
diff --git a/src/layout/size.rs b/src/layout/size.rs
index c4686966..92a4c113 100644
--- a/src/layout/size.rs
+++ b/src/layout/size.rs
@@ -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 {
diff --git a/src/layout/text.rs b/src/layout/text.rs
index 0f105531..11a1e38c 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -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.