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
119
120
121
122
123
124
125
126
127
128
129
|
//! Styles for text and pages.
use toddle::fallback;
use toddle::query::{FallbackTree, FontVariant, FontStyle, FontWeight};
use crate::length::{Length, Size, Margins, Value4, ScaleLength};
use crate::paper::{Paper, PaperClass, PAPER_A4};
/// Defines properties of pages and text.
#[derive(Debug, Default, Clone, PartialEq)]
pub struct LayoutStyle {
/// The style for text.
pub text: TextStyle,
/// The style for pages.
pub page: PageStyle,
}
/// Defines which fonts to use and how to space text.
#[derive(Debug, Clone, PartialEq)]
pub struct TextStyle {
/// A tree of font names and generic family names.
pub fallback: FallbackTree,
/// The selected font variant.
pub variant: FontVariant,
/// Whether the bolder toggle is active or inactive. This determines
/// whether the next `*` adds or removes font weight.
pub bolder: bool,
/// The base font size.
pub base_font_size: Length,
/// The font scale to apply on the base font size.
pub font_scale: f64,
/// The word spacing (as a multiple of the font size).
pub word_spacing_scale: f64,
/// The line spacing (as a multiple of the font size).
pub line_spacing_scale: f64,
/// The paragraphs spacing (as a multiple of the font size).
pub paragraph_spacing_scale: f64,
}
impl TextStyle {
/// The scaled font size.
pub fn font_size(&self) -> Length {
self.base_font_size * self.font_scale
}
/// The absolute word spacing.
pub fn word_spacing(&self) -> Length {
self.word_spacing_scale * self.font_size()
}
/// The absolute line spacing.
pub fn line_spacing(&self) -> Length {
(self.line_spacing_scale - 1.0) * self.font_size()
}
/// The absolute paragraph spacing.
pub fn paragraph_spacing(&self) -> Length {
(self.paragraph_spacing_scale - 1.0) * self.font_size()
}
}
impl Default for TextStyle {
fn default() -> TextStyle {
TextStyle {
fallback: fallback! {
list: ["sans-serif"],
classes: {
"serif" => ["source serif pro", "noto serif"],
"sans-serif" => ["source sans pro", "noto sans"],
"monospace" => ["source code pro", "noto sans mono"],
"math" => ["latin modern math", "serif"],
},
base: ["source sans pro", "noto sans",
"noto emoji", "latin modern math"],
},
variant: FontVariant {
style: FontStyle::Normal,
weight: FontWeight(400),
},
bolder: false,
base_font_size: Length::pt(11.0),
font_scale: 1.0,
word_spacing_scale: 0.25,
line_spacing_scale: 1.2,
paragraph_spacing_scale: 1.5,
}
}
}
/// Defines the size and margins of a page.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PageStyle {
/// The class of this page.
pub class: PaperClass,
/// The width and height of the page.
pub dimensions: Size,
/// The amount of white space on each side. If a side is set to `None`, the
/// default for the paper class is used.
pub margins: Value4<Option<ScaleLength>>,
}
impl PageStyle {
/// The default page style for the given paper.
pub fn new(paper: Paper) -> PageStyle {
PageStyle {
class: paper.class,
dimensions: paper.size(),
margins: Value4::with_all(None),
}
}
/// The absolute margins.
pub fn margins(&self) -> Margins {
let dims = self.dimensions;
let default = self.class.default_margins();
Margins {
left: self.margins.left.unwrap_or(default.left).scaled(dims.x),
top: self.margins.top.unwrap_or(default.top).scaled(dims.y),
right: self.margins.right.unwrap_or(default.right).scaled(dims.x),
bottom: self.margins.bottom.unwrap_or(default.bottom).scaled(dims.y),
}
}
}
impl Default for PageStyle {
fn default() -> PageStyle {
PageStyle::new(PAPER_A4)
}
}
|