1
pub mod compare_surfaces;
2
pub mod reference_utils;
3

            
4
use cairo;
5
use gio;
6
use glib;
7
use std::env;
8
use std::path::PathBuf;
9
use std::sync::Once;
10

            
11
use crate::{
12
    surface_utils::shared_surface::{SharedImageSurface, SurfaceType},
13
    CairoRenderer, Loader, LoadingError, RenderingError, SvgHandle,
14
};
15

            
16
86
pub fn load_svg(input: &'static [u8]) -> Result<SvgHandle, LoadingError> {
17
88
    let bytes = glib::Bytes::from_static(input);
18
86
    let stream = gio::MemoryInputStream::from_bytes(&bytes);
19

            
20
87
    Loader::new().read_stream(&stream, None::<&gio::File>, None::<&gio::Cancellable>)
21
87
}
22

            
23
#[derive(Copy, Clone)]
24
pub struct SurfaceSize(pub i32, pub i32);
25

            
26
122
pub fn render_document<F: FnOnce(&cairo::Context)>(
27
    svg: &SvgHandle,
28
    surface_size: SurfaceSize,
29
    cr_transform: F,
30
    viewport: cairo::Rectangle,
31
) -> Result<SharedImageSurface, RenderingError> {
32
122
    let renderer = CairoRenderer::new(svg);
33

            
34
122
    let SurfaceSize(width, height) = surface_size;
35

            
36
122
    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height).unwrap();
37

            
38
    let res = {
39
122
        let cr = cairo::Context::new(&output).expect("Failed to create a cairo context");
40
122
        cr_transform(&cr);
41
244
        Ok(renderer.render_document(&cr, &viewport)?)
42
122
    };
43

            
44
244
    res.and_then(|_| Ok(SharedImageSurface::wrap(output, SurfaceType::SRgb)?))
45
122
}
46

            
47
#[cfg(all(
48
    all(not(target_os = "macos"), not(target_os = "windows")),
49
    system_deps_have_fontconfig,
50
    system_deps_have_pangoft2
51
))]
52
mod pango_ft2 {
53
    use super::*;
54
    use glib::prelude::*;
55
    use glib::translate::*;
56
    use libc;
57
    use pangocairo::FontMap;
58
    use std::ffi::CString;
59

            
60
    extern "C" {
61
        // pango_fc_font_map_set_config (PangoFcFontMap *fcfontmap,
62
        //                               FcConfig       *fcconfig);
63
        // This is not bound in gtk-rs, and PangoFcFontMap is not even exposed, so we'll bind it by hand.
64
        fn pango_fc_font_map_set_config(
65
            font_map: *mut libc::c_void,
66
            config: *mut fontconfig_sys::FcConfig,
67
        );
68
    }
69

            
70
778
    pub unsafe fn load_test_fonts() {
71
778
        let tests_resources_path: PathBuf = [
72
778
            env::var("CARGO_MANIFEST_DIR")
73
                .expect("Manifest directory unknown")
74
                .as_str(),
75
            "tests",
76
            "resources",
77
        ]
78
        .iter()
79
776
        .collect();
80

            
81
777
        let config = fontconfig_sys::FcConfigCreate();
82
778
        if fontconfig_sys::FcConfigSetCurrent(config) == 0 {
83
            panic!("Could not set a fontconfig configuration");
84
        }
85

            
86
778
        let fonts_dot_conf_path = tests_resources_path.clone().join("fonts.conf");
87
778
        let fonts_dot_conf_cstring = CString::new(fonts_dot_conf_path.to_str().unwrap()).unwrap();
88
796
        if fontconfig_sys::FcConfigParseAndLoad(config, fonts_dot_conf_cstring.as_ptr().cast(), 1)
89
            == 0
90
        {
91
            panic!("Could not parse fontconfig configuration from tests/resources/fonts.conf");
92
        }
93

            
94
776
        let tests_resources_cstring = CString::new(tests_resources_path.to_str().unwrap()).unwrap();
95
782
        if fontconfig_sys::FcConfigAppFontAddDir(config, tests_resources_cstring.as_ptr().cast())
96
            == 0
97
        {
98
            panic!("Could not load fonts from directory tests/resources");
99
        }
100

            
101
778
        let font_map = FontMap::for_font_type(cairo::FontType::FontTypeFt).unwrap();
102
782
        let raw_font_map: *mut pango::ffi::PangoFontMap = font_map.to_glib_none().0;
103

            
104
778
        pango_fc_font_map_set_config(raw_font_map as *mut _, config);
105
779
        fontconfig_sys::FcConfigDestroy(config);
106

            
107
778
        FontMap::set_default(Some(&font_map.downcast::<pangocairo::FontMap>().unwrap()));
108
778
    }
109
}
110

            
111
#[cfg(all(
112
    all(not(target_os = "macos"), not(target_os = "windows")),
113
    system_deps_have_fontconfig,
114
    system_deps_have_pangoft2
115
))]
116
778
pub fn setup_font_map() {
117
    unsafe {
118
778
        self::pango_ft2::load_test_fonts();
119
    }
120
778
}
121

            
122
#[cfg(any(
123
    any(target_os = "macos", target_os = "windows"),
124
    not(system_deps_have_fontconfig),
125
    not(system_deps_have_pangoft2)
126
))]
127
pub fn setup_font_map() {}
128

            
129
728
pub fn setup_language() {
130
    static ONCE: Once = Once::new();
131

            
132
730
    ONCE.call_once(|| {
133
        // For systemLanguage attribute tests.
134
        // The trailing ":" is intentional to test gitlab#425.
135
2
        env::set_var("LANGUAGE", "de:en_US:en:");
136
2
        env::set_var("LC_ALL", "de:en_US:en:");
137
2
    });
138
728
}