summaryrefslogtreecommitdiff
path: root/src/layout/mod.rs
blob: 7bc62bd3f4d05339602013ac31cd0d7abcfe81ae (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! Layouting engine.

use crate::doc::Document;
use crate::font::{Font, FontLoader, FontFamily, FontError};
use crate::syntax::SyntaxTree;

mod size;
pub use size::Size;


/// Layout a syntax tree given a context.
#[allow(unused_variables)]
pub fn layout(tree: &SyntaxTree, ctx: &LayoutContext) -> LayoutResult<Layout> {
    Ok(Layout {})
}

/// A collection of layouted content.
pub struct Layout {}

impl Layout {
    /// Convert this layout into a document given the list of fonts referenced by it.
    pub fn into_document(self, fonts: Vec<Font>) -> Document {
        Document {
            pages: vec![],
            fonts,
        }
    }
}

/// The context for layouting.
pub struct LayoutContext<'a, 'p> {
    pub loader: &'a FontLoader<'p>,
}

/// Default styles for pages.
#[derive(Debug, Clone, PartialEq)]
pub struct PageStyle {
    /// 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,
}

impl Default for PageStyle {
    fn default() -> PageStyle {
        PageStyle {
            // 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(3.0),
            margin_top: Size::from_cm(3.0),
            margin_right: Size::from_cm(3.0),
            margin_bottom: Size::from_cm(3.0),
        }
    }
}

/// Default styles for texts.
#[derive(Debug, Clone, PartialEq)]
pub struct TextStyle {
    /// 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,
    /// The spacing for paragraphs (as a multiple of the line spacing).
    pub paragraph_spacing: f32,
}

impl Default for TextStyle {
    fn default() -> TextStyle {
        use FontFamily::*;
        TextStyle {
            // Default font family, font size and line spacing.
            font_families: vec![SansSerif, Serif, Monospace],
            font_size: 11.0,
            line_spacing: 1.25,
            paragraph_spacing: 1.5,
        }
    }
}

/// The error type for layouting.
pub enum LayoutError {
    /// There was no suitable font.
    MissingFont,
    /// An error occured while gathering font data.
    Font(FontError),
}

/// The result type for layouting.
pub type LayoutResult<T> = Result<T, LayoutError>;

error_type! {
    err: LayoutError,
    show: f => match err {
        LayoutError::MissingFont => write!(f, "missing font"),
        LayoutError::Font(err) => write!(f, "font error: {}", err),
    },
    source: match err {
        LayoutError::Font(err) => Some(err),
        _ => None,
    },
    from: (std::io::Error, LayoutError::Font(FontError::Io(err))),
    from: (FontError, LayoutError::Font(err)),
}