1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 use super::*;
6 use std::sync::Arc;
7 
8 #[test]
test_system_family_iter()9 fn test_system_family_iter() {
10     let system_fc = FontCollection::system();
11     let count = system_fc.families_iter().count();
12     assert!(count > 0);
13     assert!(system_fc
14         .families_iter()
15         .find(|f| f.name() == "Arial")
16         .is_some());
17 }
18 
19 #[test]
test_descriptor_round_trip()20 fn test_descriptor_round_trip() {
21     let system_fc = FontCollection::system();
22 
23     let arial_family = system_fc.get_font_family_by_name("Arial").unwrap();
24     let arial_font = arial_family.get_first_matching_font(
25         FontWeight::Regular,
26         FontStretch::Normal,
27         FontStyle::Normal,
28     );
29 
30     let descriptor = arial_font.to_descriptor();
31     assert!(descriptor.family_name == "Arial");
32 
33     let arial_font_2 = system_fc.get_font_from_descriptor(&descriptor).unwrap();
34     let descriptor2 = arial_font_2.to_descriptor();
35     assert_eq!(descriptor, descriptor2);
36 }
37 
38 #[test]
test_get_font_file_bytes()39 fn test_get_font_file_bytes() {
40     let system_fc = FontCollection::system();
41 
42     let arial_family = system_fc.get_font_family_by_name("Arial").unwrap();
43     let arial_font = arial_family.get_first_matching_font(
44         FontWeight::Regular,
45         FontStretch::Normal,
46         FontStyle::Normal,
47     );
48     let face = arial_font.create_font_face();
49     let files = face.get_files();
50     assert!(files.len() > 0);
51 
52     let bytes = files[0].get_font_file_bytes();
53     assert!(bytes.len() > 0);
54 }
55 
56 #[test]
test_font_file_is_monospace()57 fn test_font_file_is_monospace() {
58     let system_fc = FontCollection::system();
59 
60     let arial_family = system_fc.get_font_family_by_name("Arial").unwrap();
61     let arial_font = arial_family.get_first_matching_font(
62         FontWeight::Regular,
63         FontStretch::Normal,
64         FontStyle::Normal,
65     );
66     assert!(arial_font.is_monospace() == Some(false));
67 
68     let courier_new_family = system_fc.get_font_family_by_name("Courier New").unwrap();
69     let courier_new_font = courier_new_family.get_first_matching_font(
70         FontWeight::Regular,
71         FontStretch::Normal,
72         FontStyle::Normal,
73     );
74     assert!(courier_new_font.is_monospace() == Some(true));
75 }
76 
77 #[test]
test_create_font_file_from_bytes()78 fn test_create_font_file_from_bytes() {
79     let system_fc = FontCollection::system();
80 
81     let arial_family = system_fc.get_font_family_by_name("Arial").unwrap();
82     let arial_font = arial_family.get_first_matching_font(
83         FontWeight::Regular,
84         FontStretch::Normal,
85         FontStyle::Normal,
86     );
87     let face = arial_font.create_font_face();
88     let files = face.get_files();
89     assert!(files.len() > 0);
90 
91     let bytes = files[0].get_font_file_bytes();
92     assert!(bytes.len() > 0);
93 
94     // now go back
95     let new_font = FontFile::new_from_data(Arc::new(bytes));
96     assert!(new_font.is_some());
97 
98     let _new_font = new_font.unwrap();
99 }
100 
101 #[test]
test_glyph_image()102 fn test_glyph_image() {
103     let system_fc = FontCollection::system();
104     let arial_family = system_fc.get_font_family_by_name("Arial").unwrap();
105     let arial_font = arial_family.get_first_matching_font(
106         FontWeight::Regular,
107         FontStretch::Normal,
108         FontStyle::Normal,
109     );
110 
111     let face = arial_font.create_font_face();
112     let a_index = face.get_glyph_indices(&['A' as u32])[0];
113 
114     let gm = face.get_design_glyph_metrics(&[a_index], false)[0];
115 
116     let device_pixel_ratio = 1.0f32;
117     let em_size = 10.0f32;
118 
119     let design_units_per_em = match face.metrics() {
120         FontMetrics::Metrics0(ref metrics) => metrics.designUnitsPerEm,
121         FontMetrics::Metrics1(ref metrics) => metrics.designUnitsPerEm,
122     };
123     let design_units_per_pixel = design_units_per_em as f32 / 16.;
124 
125     let scaled_design_units_to_pixels = (em_size * device_pixel_ratio) / design_units_per_pixel;
126 
127     let width = (gm.advanceWidth as i32 - (gm.leftSideBearing + gm.rightSideBearing)) as f32
128         * scaled_design_units_to_pixels;
129     let height = (gm.advanceHeight as i32 - (gm.topSideBearing + gm.bottomSideBearing)) as f32
130         * scaled_design_units_to_pixels;
131     let x = (-gm.leftSideBearing) as f32 * scaled_design_units_to_pixels;
132     let y = (gm.verticalOriginY - gm.topSideBearing) as f32 * scaled_design_units_to_pixels;
133 
134     // FIXME I'm pretty sure we need to do a proper RoundOut type
135     // operation on this rect to properly handle any aliasing
136     let left_i = x.floor() as i32;
137     let top_i = (height - y).floor() as i32;
138     let width_u = width.ceil() as u32;
139     let height_u = height.ceil() as u32;
140 
141     println!(
142         "GlyphDimensions: {} {} {} {}",
143         left_i, top_i, width_u, height_u
144     );
145 
146     let gdi_interop = GdiInterop::create();
147     let rt = gdi_interop.create_bitmap_render_target(width_u, height_u);
148     let rp = RenderingParams::create_for_primary_monitor();
149     rt.set_pixels_per_dip(device_pixel_ratio);
150     rt.draw_glyph_run(
151         x as f32,
152         y as f32,
153         DWRITE_MEASURING_MODE_NATURAL,
154         &face,
155         em_size,
156         &[a_index],
157         &[0f32],
158         &[GlyphOffset {
159             advanceOffset: 0.,
160             ascenderOffset: 0.,
161         }],
162         &rp,
163         &(255.0f32, 255.0f32, 255.0f32),
164     );
165     let bytes = rt.get_opaque_values_as_mask();
166     println!("bytes length: {}", bytes.len());
167 }
168