summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-03-30 16:58:45 +0100
committerLaurenz <laurmaedje@gmail.com>2019-03-30 16:58:45 +0100
commitdb96ecae94a7c06d04528e8d4461ebca86d2d249 (patch)
tree9f1bdbaa65b424ef522dadda02bfa4826acfc836 /src
parentf683bba4004cc07f9ac91d5d99a6bab76f335dba (diff)
Move some types into better places 🧱
Diffstat (limited to 'src')
-rw-r--r--src/doc.rs202
-rw-r--r--src/engine/mod.rs (renamed from src/engine.rs)54
-rw-r--r--src/engine/size.rs144
-rw-r--r--src/error.rs2
-rw-r--r--src/export/pdf.rs3
-rw-r--r--src/font.rs26
-rw-r--r--src/lib.rs13
-rw-r--r--src/parsing.rs3
-rw-r--r--src/syntax.rs2
9 files changed, 230 insertions, 219 deletions
diff --git a/src/doc.rs b/src/doc.rs
index 5d3c1e14..3ffc7f8c 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -1,9 +1,10 @@
-//! Abstract representation of a typesetted document.
+//! Representation of typesetted documents.
use crate::font::Font;
+use crate::engine::Size;
-/// A representation of a typesetted document.
+/// A complete typesetted document, which can be exported.
#[derive(Debug, Clone, PartialEq)]
pub struct Document {
/// The pages of the document.
@@ -12,62 +13,6 @@ pub struct Document {
pub fonts: Vec<Font>,
}
-/// Default styles for a document.
-#[derive(Debug, Clone, PartialEq)]
-pub struct Style {
- /// The width of the paper.
- pub width: Size,
- /// The height of the paper.
- pub height: Size,
-
- /// The left margin of the paper.
- pub margin_left: Size,
- /// The top margin of the paper.
- pub margin_top: Size,
- /// The right margin of the paper.
- pub margin_right: Size,
- /// The bottom margin of the paper.
- pub margin_bottom: Size,
-
- /// A fallback list of font families to use.
- pub font_families: Vec<FontFamily>,
- /// The font size.
- pub font_size: f32,
- /// The line spacing (as a multiple of the font size).
- pub line_spacing: f32,
-}
-
-/// A family of fonts (either generic or named).
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub enum FontFamily {
- SansSerif,
- Serif,
- Monospace,
- Named(String),
-}
-
-impl Default for Style {
- fn default() -> Style {
- use FontFamily::*;
- Style {
- // A4 paper.
- width: Size::from_mm(210.0),
- height: Size::from_mm(297.0),
-
- // Margins. A bit more on top and bottom.
- margin_left: Size::from_cm(2.5),
- margin_top: Size::from_cm(3.0),
- margin_right: Size::from_cm(2.5),
- margin_bottom: Size::from_cm(3.0),
-
- // Default font family, font size and line spacing.
- font_families: vec![SansSerif, Serif, Monospace],
- font_size: 12.0,
- line_spacing: 1.25,
- }
- }
-}
-
/// A page with text contents in a document.
#[derive(Debug, Clone, PartialEq)]
pub struct Page {
@@ -96,144 +41,3 @@ pub enum TextCommand {
/// Use the indexed font in the documents font list with a given font size.
SetFont(usize, f32),
}
-
-/// A general distance type that can convert between units.
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Size {
- /// The size in typographic points (1/72 inches).
- points: f32,
-}
-
-impl Size {
- /// Create an zeroed size.
- #[inline]
- pub fn zero() -> Size { Size { points: 0.0 } }
-
- /// Create a size from a number of points.
- #[inline]
- pub fn from_points(points: f32) -> Size { Size { points } }
-
- /// Create a size from a number of inches.
- #[inline]
- pub fn from_inches(inches: f32) -> Size { Size { points: 72.0 * inches } }
-
- /// Create a size from a number of millimeters.
- #[inline]
- pub fn from_mm(mm: f32) -> Size { Size { points: 2.83465 * mm } }
-
- /// Create a size from a number of centimeters.
- #[inline]
- pub fn from_cm(cm: f32) -> Size { Size { points: 28.3465 * cm } }
-
- /// Create a size from a number of points.
- #[inline]
- pub fn to_points(&self) -> f32 { self.points }
-
- /// Create a size from a number of inches.
- #[inline]
- pub fn to_inches(&self) -> f32 { self.points * 0.0138889 }
-
- /// Create a size from a number of millimeters.
- #[inline]
- pub fn to_mm(&self) -> f32 { self.points * 0.352778 }
-
- /// Create a size from a number of centimeters.
- #[inline]
- pub fn to_cm(&self) -> f32 { self.points * 0.0352778 }
-}
-
-mod size {
- use super::Size;
- use std::cmp::Ordering;
- use std::fmt;
- use std::iter::Sum;
- use std::ops::*;
-
- impl fmt::Display for Size {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}pt", self.points)
- }
- }
-
- macro_rules! impl_reflexive {
- ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident) => {
- impl $trait for Size {
- type Output = Size;
-
- #[inline]
- fn $func(self, other: Size) -> Size {
- Size { points: $trait::$func(self.points, other.points) }
- }
- }
-
- impl $assign_trait for Size {
- #[inline]
- fn $assign_func(&mut self, other: Size) {
- $assign_trait::$assign_func(&mut self.points, other.points);
- }
- }
- };
- }
-
- macro_rules! impl_num_back {
- ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $ty:ty) => {
- impl $trait<$ty> for Size {
- type Output = Size;
-
- #[inline]
- fn $func(self, other: $ty) -> Size {
- Size { points: $trait::$func(self.points, other as f32) }
- }
- }
-
- impl $assign_trait<$ty> for Size {
- #[inline]
- fn $assign_func(&mut self, other: $ty) {
- $assign_trait::$assign_func(&mut self.points, other as f32);
- }
- }
- };
- }
-
- macro_rules! impl_num_both {
- ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $ty:ty) => {
- impl_num_back!($trait, $func, $assign_trait, $assign_func, $ty);
-
- impl $trait<Size> for $ty {
- type Output = Size;
-
- #[inline]
- fn $func(self, other: Size) -> Size {
- Size { points: $trait::$func(self as f32, other.points) }
- }
- }
- };
- }
-
- impl Neg for Size {
- type Output = Size;
-
- fn neg(self) -> Size {
- Size { points: -self.points }
- }
- }
-
- impl_reflexive!(Add, add, AddAssign, add_assign);
- impl_reflexive!(Sub, sub, SubAssign, sub_assign);
- impl_num_both!(Mul, mul, MulAssign, mul_assign, f32);
- impl_num_both!(Mul, mul, MulAssign, mul_assign, i32);
- impl_num_back!(Div, div, DivAssign, div_assign, f32);
- impl_num_back!(Div, div, DivAssign, div_assign, i32);
-
- impl PartialOrd for Size {
- fn partial_cmp(&self, other: &Size) -> Option<Ordering> {
- self.points.partial_cmp(&other.points)
- }
- }
-
- impl Sum for Size {
- fn sum<I>(iter: I) -> Size where I: Iterator<Item=Size> {
- iter.fold(Size::zero(), Add::add)
- }
- }
-}
diff --git a/src/engine.rs b/src/engine/mod.rs
index ff89d674..f121ac82 100644
--- a/src/engine.rs
+++ b/src/engine/mod.rs
@@ -1,10 +1,13 @@
//! Core typesetting engine.
use crate::syntax::{SyntaxTree, Node};
-use crate::doc::{Document, Size, Page, Text, TextCommand};
-use crate::font::{Font, FontConfig, FontError};
+use crate::doc::{Document, Page, Text, TextCommand};
+use crate::font::{Font, FontFamily, FontConfig, FontError};
use crate::Context;
+mod size;
+pub use size::Size;
+
/// The core typesetting engine, transforming an abstract syntax tree into a document.
pub(crate) struct Engine<'a> {
@@ -138,6 +141,53 @@ impl<'a> Engine<'a> {
}
}
+/// Default styles for a document.
+#[derive(Debug, Clone, PartialEq)]
+pub struct Style {
+ /// The width of the paper.
+ pub width: Size,
+ /// The height of the paper.
+ pub height: Size,
+
+ /// The left margin of the paper.
+ pub margin_left: Size,
+ /// The top margin of the paper.
+ pub margin_top: Size,
+ /// The right margin of the paper.
+ pub margin_right: Size,
+ /// The bottom margin of the paper.
+ pub margin_bottom: Size,
+
+ /// A fallback list of font families to use.
+ pub font_families: Vec<FontFamily>,
+ /// The font size.
+ pub font_size: f32,
+ /// The line spacing (as a multiple of the font size).
+ pub line_spacing: f32,
+}
+
+impl Default for Style {
+ fn default() -> Style {
+ use FontFamily::*;
+ Style {
+ // A4 paper.
+ width: Size::from_mm(210.0),
+ height: Size::from_mm(297.0),
+
+ // Margins. A bit more on top and bottom.
+ margin_left: Size::from_cm(2.5),
+ margin_top: Size::from_cm(3.0),
+ margin_right: Size::from_cm(2.5),
+ margin_bottom: Size::from_cm(3.0),
+
+ // Default font family, font size and line spacing.
+ font_families: vec![SansSerif, Serif, Monospace],
+ font_size: 12.0,
+ line_spacing: 1.25,
+ }
+ }
+}
+
/// The error type for typesetting.
pub enum TypesetError {
/// There was no suitable font.
diff --git a/src/engine/size.rs b/src/engine/size.rs
new file mode 100644
index 00000000..a6624c57
--- /dev/null
+++ b/src/engine/size.rs
@@ -0,0 +1,144 @@
+use std::cmp::Ordering;
+use std::fmt::{self, Display, Debug, Formatter};
+use std::iter::Sum;
+use std::ops::*;
+
+
+/// A general distance type that can convert between units.
+#[derive(Copy, Clone, PartialEq)]
+pub struct Size {
+ /// The size in typographic points (1/72 inches).
+ points: f32,
+}
+
+impl Size {
+ /// Create an zeroed size.
+ #[inline]
+ pub fn zero() -> Size { Size { points: 0.0 } }
+
+ /// Create a size from a number of points.
+ #[inline]
+ pub fn from_points(points: f32) -> Size { Size { points } }
+
+ /// Create a size from a number of inches.
+ #[inline]
+ pub fn from_inches(inches: f32) -> Size { Size { points: 72.0 * inches } }
+
+ /// Create a size from a number of millimeters.
+ #[inline]
+ pub fn from_mm(mm: f32) -> Size { Size { points: 2.83465 * mm } }
+
+ /// Create a size from a number of centimeters.
+ #[inline]
+ pub fn from_cm(cm: f32) -> Size { Size { points: 28.3465 * cm } }
+
+ /// Create a size from a number of points.
+ #[inline]
+ pub fn to_points(&self) -> f32 { self.points }
+
+ /// Create a size from a number of inches.
+ #[inline]
+ pub fn to_inches(&self) -> f32 { self.points * 0.0138889 }
+
+ /// Create a size from a number of millimeters.
+ #[inline]
+ pub fn to_mm(&self) -> f32 { self.points * 0.352778 }
+
+ /// Create a size from a number of centimeters.
+ #[inline]
+ pub fn to_cm(&self) -> f32 { self.points * 0.0352778 }
+}
+
+impl Display for Size {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{}pt", self.points)
+ }
+}
+
+impl Debug for Size {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ Display::fmt(self, f)
+ }
+}
+
+impl PartialOrd for Size {
+ fn partial_cmp(&self, other: &Size) -> Option<Ordering> {
+ self.points.partial_cmp(&other.points)
+ }
+}
+
+impl Neg for Size {
+ type Output = Size;
+
+ fn neg(self) -> Size {
+ Size { points: -self.points }
+ }
+}
+
+impl Sum for Size {
+ fn sum<I>(iter: I) -> Size where I: Iterator<Item=Size> {
+ iter.fold(Size::zero(), Add::add)
+ }
+}
+
+macro_rules! impl_reflexive {
+ ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident) => {
+ impl $trait for Size {
+ type Output = Size;
+
+ #[inline]
+ fn $func(self, other: Size) -> Size {
+ Size { points: $trait::$func(self.points, other.points) }
+ }
+ }
+
+ impl $assign_trait for Size {
+ #[inline]
+ fn $assign_func(&mut self, other: Size) {
+ $assign_trait::$assign_func(&mut self.points, other.points);
+ }
+ }
+ };
+}
+
+macro_rules! impl_num_back {
+ ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $ty:ty) => {
+ impl $trait<$ty> for Size {
+ type Output = Size;
+
+ #[inline]
+ fn $func(self, other: $ty) -> Size {
+ Size { points: $trait::$func(self.points, other as f32) }
+ }
+ }
+
+ impl $assign_trait<$ty> for Size {
+ #[inline]
+ fn $assign_func(&mut self, other: $ty) {
+ $assign_trait::$assign_func(&mut self.points, other as f32);
+ }
+ }
+ };
+}
+
+macro_rules! impl_num_both {
+ ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $ty:ty) => {
+ impl_num_back!($trait, $func, $assign_trait, $assign_func, $ty);
+
+ impl $trait<Size> for $ty {
+ type Output = Size;
+
+ #[inline]
+ fn $func(self, other: Size) -> Size {
+ Size { points: $trait::$func(self as f32, other.points) }
+ }
+ }
+ };
+}
+
+impl_reflexive!(Add, add, AddAssign, add_assign);
+impl_reflexive!(Sub, sub, SubAssign, sub_assign);
+impl_num_both!(Mul, mul, MulAssign, mul_assign, f32);
+impl_num_both!(Mul, mul, MulAssign, mul_assign, i32);
+impl_num_back!(Div, div, DivAssign, div_assign, f32);
+impl_num_back!(Div, div, DivAssign, div_assign, i32);
diff --git a/src/error.rs b/src/error.rs
index cfdb1f0e..442971d0 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,3 +1,5 @@
+//! Error handling.
+
/// Create an error type.
macro_rules! error_type {
(
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index 630a0501..cac60a87 100644
--- a/src/export/pdf.rs
+++ b/src/export/pdf.rs
@@ -6,8 +6,9 @@ use pdf::{PdfWriter, Ref, Rect, Version, Trailer, Content};
use pdf::doc::{Catalog, PageTree, Page, Resource, Text};
use pdf::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags};
use pdf::font::{GlyphUnit, CMapEncoding, WidthRecord, FontStream, EmbeddedFontType};
-use crate::doc::{Document, Size, Text as DocText, TextCommand};
+use crate::doc::{Document, Text as DocText, TextCommand};
use crate::font::{Font, FontError};
+use crate::engine::Size;
/// Exports documents into _PDFs_.
diff --git a/src/font.rs b/src/font.rs
index 294c2b7e..37346a3e 100644
--- a/src/font.rs
+++ b/src/font.rs
@@ -1,6 +1,4 @@
-//! Font loading, utility and subsetting.
-
-#![macro_use]
+//! Font loading and transforming.
use std::collections::HashMap;
use std::path::{Path, PathBuf};
@@ -9,7 +7,7 @@ use byteorder::{BE, ReadBytesExt, WriteBytesExt};
use opentype::{Error as OpentypeError, OpenTypeReader, Outlines, TableRecord, Tag};
use opentype::tables::{Header, Name, CharMap, MaximumProfile, HorizontalMetrics, Post, OS2};
use opentype::global::{MacStyleFlags, NameEntry};
-use crate::doc::{Size, FontFamily};
+use crate::engine::Size;
/// An font wrapper which allows to subset a font.
@@ -54,8 +52,8 @@ impl Font {
/// Create a new font from a font program.
pub fn new(program: Vec<u8>) -> FontResult<Font> {
// Create opentype reader to parse font tables
- let mut readable = Cursor::new(&program);
- let mut reader = OpenTypeReader::new(&mut readable);
+ let cursor = Cursor::new(&program);
+ let mut reader = OpenTypeReader::new(cursor);
// Read the relevant tables
// (all of these are required by the OpenType specification)
@@ -586,8 +584,6 @@ impl<T> TakeInvalid<T> for Option<T> {
}
}
-///////////////////////////////////////////////////////////////////////////////
-
/// A type that provides fonts matching given criteria.
pub trait FontProvider {
/// Returns a font matching the configuration
@@ -599,8 +595,18 @@ pub trait FontProvider {
///
/// Automatically implemented for all types that are [`Read`] and [`Seek`].
pub trait FontSource: Read + Seek {}
+
impl<T> FontSource for T where T: Read + Seek {}
+/// A family of fonts (either generic or named).
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum FontFamily {
+ SansSerif,
+ Serif,
+ Monospace,
+ Named(String),
+}
+
/// Criteria to filter fonts.
#[derive(Debug, Clone, PartialEq)]
pub struct FontConfig {
@@ -694,8 +700,8 @@ impl FileFontDescriptor<'_> {
#[macro_export]
macro_rules! file_font {
($family:expr, [$($generic:ident),*], $path:expr, $bold:expr, $italic:expr) => {{
- let mut families = vec![$crate::doc::FontFamily::Named($family.to_string())];
- families.extend([$($crate::doc::FontFamily::$generic),*].iter().cloned());
+ let mut families = vec![$crate::font::FontFamily::Named($family.to_string())];
+ families.extend([$($crate::font::FontFamily::$generic),*].iter().cloned());
$crate::font::FileFontDescriptor {
path: std::path::Path::new($path),
families,
diff --git a/src/lib.rs b/src/lib.rs
index 4434f62f..9f37efc2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -33,16 +33,19 @@
//! let document = compiler.typeset(src).unwrap();
//!
//! // Export the document into a PDF file.
-//! let mut file = File::create("hello-typeset.pdf").unwrap();
+//! # /*
+//! let file = File::create("hello-typeset.pdf").unwrap();
+//! # */
+//! # let file = File::create("../target/typeset-hello.pdf").unwrap();
//! let exporter = PdfExporter::new();
-//! exporter.export(&document, &mut file).unwrap();
+//! exporter.export(&document, file).unwrap();
//! ```
use crate::syntax::SyntaxTree;
use crate::parsing::{Tokens, Parser, ParseError};
-use crate::doc::{Document, Style};
+use crate::doc::Document;
use crate::font::FontProvider;
-use crate::engine::{Engine, TypesetError};
+use crate::engine::{Engine, Style, TypesetError};
#[macro_use]
mod error;
@@ -50,6 +53,7 @@ mod utility;
pub mod doc;
pub mod engine;
pub mod export;
+#[macro_use]
pub mod font;
pub mod parsing;
pub mod syntax;
@@ -135,6 +139,7 @@ error_type! {
from: (TypesetError, Error::Typeset(err)),
}
+
#[cfg(test)]
mod test {
use std::fs::File;
diff --git a/src/parsing.rs b/src/parsing.rs
index 2737fde4..92eaae75 100644
--- a/src/parsing.rs
+++ b/src/parsing.rs
@@ -1,4 +1,4 @@
-//! Parsing of source code into tokens and syntax trees.
+//! Tokenization and parsing of source code into syntax trees.
use std::fmt;
use std::iter::Peekable;
@@ -475,7 +475,6 @@ mod token_tests {
}
}
-
#[cfg(test)]
mod parse_tests {
use super::*;
diff --git a/src/syntax.rs b/src/syntax.rs
index 38e5a60e..56e11605 100644
--- a/src/syntax.rs
+++ b/src/syntax.rs
@@ -1,4 +1,4 @@
-//! Token and abstract syntax tree representations.
+//! Tokenized and syntax tree representations of source code.
/// A logical unit of the incoming text stream.