aboutsummaryrefslogtreecommitdiffstats
path: root/components/fonts/tests/font.rs
blob: 2f735fb229e810c1a70af2610078d7e50b3ae13e (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
/* 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));
}