summaryrefslogtreecommitdiff
path: root/src/export/pdf.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-06-22 12:51:06 +0200
committerLaurenz <laurmaedje@gmail.com>2019-06-22 12:51:06 +0200
commitc7ee2b393a369325b3578557e045f2ff94ceab8f (patch)
tree063e371b764b119e378644817cc556c397ebd9dd /src/export/pdf.rs
parentf6fe3b5cdd2805f3975985752f9cb0e04e3daf49 (diff)
Fix top-left text alignment 📐
Diffstat (limited to 'src/export/pdf.rs')
-rw-r--r--src/export/pdf.rs55
1 files changed, 36 insertions, 19 deletions
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index 1c0d52b0..a09f3b0c 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, Page as DocPage, TextAction};
+use crate::doc::{Document, Page as DocPage, LayoutAction};
use crate::font::{Font, FontError};
-use crate::size::Size;
+use crate::size::{Size, Size2D};
/// Exports documents into _PDFs_.
@@ -72,8 +72,8 @@ impl<'d, W: Write> PdfEngine<'d, W> {
for page in &doc.pages {
for action in &page.actions {
match action {
- TextAction::WriteText(string) => chars[font].extend(string.chars()),
- TextAction::SetFont(id, _) => font = *id,
+ LayoutAction::WriteText(string) => chars[font].extend(string.chars()),
+ LayoutAction::SetFont(id, _) => font = *id,
_ => {},
}
}
@@ -123,7 +123,7 @@ impl<'d, W: Write> PdfEngine<'d, W> {
// The page objects
for (id, page) in ids(self.offsets.pages).zip(&self.doc.pages) {
self.writer.write_obj(id, Page::new(self.offsets.page_tree)
- .media_box(Rect::new(0.0, 0.0, page.width.to_points(), page.height.to_points()))
+ .media_box(Rect::new(0.0, 0.0, page.width.to_pt(), page.height.to_pt()))
.contents(ids(self.offsets.contents))
)?;
}
@@ -141,23 +141,40 @@ impl<'d, W: Write> PdfEngine<'d, W> {
/// 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();
+ // The currently used font.
+ let mut active_font = (std::usize::MAX, 0.0);
+
+ // The last set position and font, these get flushed when content is written.
+ let mut next_pos = Some(Size2D::zero());
+ let mut next_font = None;
- text.tm(1.0, 0.0, 0.0, 1.0, 0.0, page.height.to_points());
+ // The output text.
+ let mut text = Text::new();
for action in &page.actions {
match action {
- 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;
- text.tf(*id as u32 + 1, *size);
+ LayoutAction::MoveAbsolute(pos) => next_pos = Some(*pos),
+ LayoutAction::SetFont(id, size) => next_font = Some((*id, *size)),
+ LayoutAction::WriteText(string) => {
+ // Flush the font if it is different from the current.
+ if let Some((id, size)) = next_font {
+ if (id, size) != active_font {
+ text.tf(id as u32 + 1, size);
+ active_font = (id, size);
+ next_font = None;
+ }
+ }
+
+ // Flush the position.
+ if let Some(pos) = next_pos {
+ let x = pos.x.to_pt();
+ let y = (page.height - pos.y - Size::pt(active_font.1)).to_pt();
+ text.tm(1.0, 0.0, 0.0, 1.0, x, y);
+ next_pos = None;
+ }
+
+ // Write the text.
+ text.tj(self.fonts[active_font.0].encode(&string));
},
}
}
@@ -249,7 +266,7 @@ impl PdfFont {
fn new(font: &Font, chars: &HashSet<char>) -> PdfResult<PdfFont> {
/// Convert a size into a _PDF_ glyph unit.
fn size_to_glyph_unit(size: Size) -> GlyphUnit {
- (1000.0 * size.to_points()).round() as GlyphUnit
+ (1000.0 * size.to_pt()).round() as GlyphUnit
}
// Subset the font using the selected characters.