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
130
131
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use super::prelude::*;
pub fn resolve_style_attributes(doc: &Document) {
resolve_inherit(&doc.root());
}
fn resolve_inherit(parent: &Node) {
for (id, mut node) in parent.children().svg() {
// Commented stuff is not supported yet, so there is no point in resolving it.
if node.is_text_content() {
// resolve(&mut node, AId::Direction)?;
// resolve(&mut node, AId::FontSizeAdjust)?;
resolve(&mut node, AId::FontStretch);
resolve(&mut node, AId::FontStyle);
resolve(&mut node, AId::FontVariant);
resolve(&mut node, AId::FontWeight);
// resolve(&mut node, AId::GlyphOrientationHorizontal)?;
// resolve(&mut node, AId::GlyphOrientationVertical)?;
// resolve(&mut node, AId::Kerning)?;
// resolve(&mut node, AId::LetterSpacing)?;
resolve(&mut node, AId::TextAnchor);
// resolve(&mut node, AId::TextRendering)?;
// resolve(&mut node, AId::WordSpacing)?;
// resolve(&mut node, AId::WritingMode)?;
resolve_font_family(&mut node);
}
// if node.is_container() || node.is_graphic() {
// resolve(&mut node, AId::ColorInterpolation);
// resolve(&mut node, AId::ColorRendering);
// }
if node.is_shape() || node.is_text_content() || id == EId::G {
resolve(&mut node, AId::Fill);
// a-fill-opacity-005.svg
resolve(&mut node, AId::FillOpacity);
resolve(&mut node, AId::FillRule);
resolve(&mut node, AId::Stroke);
resolve(&mut node, AId::StrokeDasharray);
resolve(&mut node, AId::StrokeDashoffset);
resolve(&mut node, AId::StrokeLinecap);
resolve(&mut node, AId::StrokeLinejoin);
resolve(&mut node, AId::StrokeMiterlimit);
resolve(&mut node, AId::StrokeOpacity);
resolve(&mut node, AId::StrokeWidth);
}
// if node.is_shape() {
// resolve(&mut node, AId::ShapeRendering);
// }
if node.is_graphic() && node.parent().unwrap().is_tag_name(EId::ClipPath) {
resolve(&mut node, AId::ClipRule);
}
// if node.parent().unwrap().has_tag_name(EId::Filter) {
// resolve(&mut node, AId::ColorInterpolationFilters);
// }
// if id == EId::Image {
// resolve(&mut node, AId::ColorProfile);
// resolve(&mut node, AId::ImageRendering);
// }
// if id == EId::Path || id == EId::Line || id == EId::Polyline || id == EId::Polygon {
// resolve(&mut node, AId::MarkerStart);
// resolve(&mut node, AId::MarkerMid);
// resolve(&mut node, AId::MarkerEnd);
// }
if node.has_children() {
resolve_inherit(&node);
}
}
}
fn resolve(node: &mut Node, aid: AId) {
debug_assert!(aid.is_inheritable(), "'{}' is not inheritable", aid);
if !node.has_attribute(aid) {
if let Some(n) = node.ancestors().skip(1).find(|n| n.has_attribute(aid)) {
// unwrap is safe, because we know that node contains an attribute
node.set_attribute(n.attributes().get(aid).cloned().unwrap());
} else {
resolve_default(node, aid);
}
}
}
fn resolve_default(node: &mut Node, aid: AId) {
let mut v = match AValue::default_value(aid) {
Some(v) => v,
None => {
// Technically unreachable.
warn!("'{:?}' doesn't have a default value.", aid);
return;
}
};
// Convert length to number.
// All default values have Unit::None, so it's safe
// and we don't need preproc::conv_units.
if let AValue::Length(len) = v {
debug_assert!(len.unit == Unit::None);
v = AValue::Number(len.num);
}
node.set_attribute((aid, v));
}
fn resolve_font_family(node: &mut Node) {
let aid = AId::FontFamily;
if !node.has_attribute(aid) {
if let Some(n) = node.ancestors().skip(1).find(|n| n.has_attribute(aid)) {
// unwrap is safe, because we know that node contains an attribute
node.set_attribute(n.attributes().get(aid).cloned().unwrap());
} else {
// `font-family` depends on user agent, so we use our own font
// TODO: maybe use a system font
warn!("'font-family' is not set. Fallback to '{}'.", DEFAULT_FONT_FAMILY);
node.set_attribute((aid, DEFAULT_FONT_FAMILY));
}
}
}