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
|
/* 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 https://mozilla.org/MPL/2.0/. */
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use std::sync::Arc;
use app_units::Au;
use euclid::num::Zero;
use fonts::platform::font::PlatformFont;
use fonts::{
Font, FontData, FontDescriptor, FontIdentifier, FontTemplate, PlatformFontMethods,
ShapingFlags, ShapingOptions,
};
use servo_url::ServoUrl;
use style::properties::longhands::font_variant_caps::computed_value::T as FontVariantCaps;
use style::values::computed::{FontStretch, FontStyle, FontWeight};
use unicode_script::Script;
fn make_font(path: PathBuf) -> Font {
let identifier = FontIdentifier::Web(ServoUrl::from_file_path(path.clone()).unwrap());
let file = File::open(path).unwrap();
let data = Arc::new(FontData::from_bytes(
file.bytes().map(Result::unwrap).collect(),
));
let platform_font =
PlatformFont::new_from_data(identifier.clone(), data.as_arc().clone(), 0, None).unwrap();
let template = FontTemplate {
identifier,
descriptor: platform_font.descriptor(),
stylesheet: None,
};
let descriptor = FontDescriptor {
weight: FontWeight::normal(),
stretch: FontStretch::hundred(),
style: FontStyle::normal(),
variant: FontVariantCaps::Normal,
pt_size: Au::from_px(24),
};
Font::new(
Arc::new(atomic_refcell::AtomicRefCell::new(template)),
descriptor,
data,
None,
)
.unwrap()
}
#[test]
fn test_font_can_do_fast_shaping() {
let dejavu_sans = make_font(
[
env!("CARGO_MANIFEST_DIR"),
"tests",
"support",
"dejavu-fonts-ttf-2.37",
"ttf",
"DejaVuSans.ttf",
]
.iter()
.collect(),
);
let dejavu_sans_fast_shapeable = make_font(
[
env!("CARGO_MANIFEST_DIR"),
"tests",
"support",
"dejavu-fonts-ttf-2.37",
"ttf",
"DejaVuSansNoGSUBNoGPOS.ttf",
]
.iter()
.collect(),
);
// Fast shaping requires a font with a kern table and no GPOS or GSUB tables.
let shaping_options = ShapingOptions {
letter_spacing: None,
word_spacing: Au::zero(),
script: Script::Latin,
flags: ShapingFlags::empty(),
};
assert!(!dejavu_sans.can_do_fast_shaping("WAVE", &shaping_options));
assert!(dejavu_sans_fast_shapeable.can_do_fast_shaping("WAVE", &shaping_options));
// Non-Latin script should never have fast shaping.
let shaping_options = ShapingOptions {
letter_spacing: None,
word_spacing: Au::zero(),
script: Script::Cherokee,
flags: ShapingFlags::empty(),
};
assert!(!dejavu_sans.can_do_fast_shaping("WAVE", &shaping_options));
assert!(!dejavu_sans_fast_shapeable.can_do_fast_shaping("WAVE", &shaping_options));
// Right-to-left text should never use fast shaping.
let shaping_options = ShapingOptions {
letter_spacing: None,
word_spacing: Au::zero(),
script: Script::Latin,
flags: ShapingFlags::RTL_FLAG,
};
assert!(!dejavu_sans.can_do_fast_shaping("WAVE", &shaping_options));
assert!(!dejavu_sans_fast_shapeable.can_do_fast_shaping("WAVE", &shaping_options));
}
|