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