pathfinder/font-renderer/src/tests.rs

167 lines
5.3 KiB
Rust

// pathfinder/font-renderer/src/tests.rs
use app_units::Au;
use env_logger;
use euclid::Size2D;
use euclid::approxeq::ApproxEq;
use pathfinder_path_utils::{PathBuffer, Subpath};
use std::fs::File;
use std::io::Read;
use std::sync::Arc;
use {FontContext, FontInstance, FontKey, GlyphDimensions, GlyphKey, SubpixelOffset};
static TEST_FONT_PATH: &'static str = "../resources/fonts/nimbus-sans/NimbusSanL-Regu.ttf";
const TEST_FONT_SIZE: Au = Au(60 * 16);
const TEST_GLYPH_ID: u32 = 68; // 'a'
const EXPECTED_GLYPH_ORIGIN: [i32; 2] = [0, 9];
const EXPECTED_GLYPH_SIZE: [u32; 2] = [9, 9];
const EXPECTED_GLYPH_ADVANCE: f32 = 9.0;
static EXPECTED_GLYPH_ENDPOINTS: [[f32; 2]; 34] = [
[ 548.0, 77.0 ],
[ 548.0, 10.0 ],
[ 490.0, 0.0 ],
[ 402.0, 82.0 ],
[ 323.0, 24.0 ],
[ 219.0, 0.0 ],
[ 89.0, 44.0 ],
[ 43.0, 158.0 ],
[ 138.0, 301.0 ],
[ 233.0, 324.0 ],
[ 310.0, 333.0 ],
[ 381.0, 353.0 ],
[ 399.0, 392.0 ],
[ 399.0, 414.0 ],
[ 362.0, 476.0 ],
[ 278.0, 494.0 ],
[ 153.0, 400.0 ],
[ 67.0, 400.0 ],
[ 104.0, 512.0 ],
[ 282.0, 576.0 ],
[ 444.0, 529.0 ],
[ 484.0, 430.0 ],
[ 484.0, 117.0 ],
[ 530.0, 75.0 ],
[ 399.0, 289.0 ],
[ 349.0, 273.0 ],
[ 261.0, 258.0 ],
[ 165.0, 228.0 ],
[ 132.0, 161.0 ],
[ 157.0, 101.0 ],
[ 238.0, 75.0 ],
[ 365.0, 124.0 ],
[ 396.0, 169.0 ],
[ 399.0, 193.0 ],
];
static EXPECTED_GLYPH_CONTROL_POINTS: [[f32; 2]; 29] = [
[ 512.0, 0.0 ],
[ 410.0, 0.0 ],
[ 362.0, 43.0 ],
[ 276.0, 0.0 ],
[ 137.0, 0.0 ],
[ 43.0, 86.0 ],
[ 43.0, 262.0 ],
[ 169.0, 314.0 ],
[ 241.0, 325.0 ],
[ 365.0, 340.0 ],
[ 398.0, 366.0 ],
[ 399.0, 457.0 ],
[ 330.0, 494.0 ],
[ 163.0, 494.0 ],
[ 70.0, 474.0 ],
[ 160.0, 576.0 ],
[ 394.0, 576.0 ],
[ 484.0, 493.0 ],
[ 484.0, 75.0 ],
[ 537.0, 75.0 ],
[ 377.0, 278.0 ],
[ 325.0, 268.0 ],
[ 195.0, 249.0 ],
[ 132.0, 205.0 ],
[ 132.0, 125.0 ],
[ 183.0, 75.0 ],
[ 313.0, 75.0 ],
[ 390.0, 147.0 ],
[ 399.0, 177.0 ],
];
static EXPECTED_GLYPH_SUBPATHS: [Subpath; 2] = [
Subpath {
first_endpoint_index: 0,
last_endpoint_index: 24,
},
Subpath {
first_endpoint_index: 24,
last_endpoint_index: 34,
},
];
#[test]
fn test_font_context_glyph_dimensions() {
let mut font_context = FontContext::new().unwrap();
let font_key = FontKey::new();
let mut bytes = vec![];
File::open(TEST_FONT_PATH).unwrap().read_to_end(&mut bytes).unwrap();
font_context.add_font_from_memory(&font_key, Arc::new(bytes), 0).unwrap();
let font_instance = FontInstance::new(&font_key, TEST_FONT_SIZE);
let glyph_key = GlyphKey::new(TEST_GLYPH_ID, SubpixelOffset(0));
let glyph_dimensions = font_context.glyph_dimensions(&font_instance, &glyph_key).unwrap();
assert_eq!(glyph_dimensions, GlyphDimensions {
origin: EXPECTED_GLYPH_ORIGIN.into(),
size: Size2D::new(EXPECTED_GLYPH_SIZE[0], EXPECTED_GLYPH_SIZE[1]),
advance: EXPECTED_GLYPH_ADVANCE,
})
}
#[test]
fn test_font_context_glyph_outline() {
drop(env_logger::init());
let mut font_context = FontContext::new().unwrap();
let font_key = FontKey::new();
let mut bytes = vec![];
File::open(TEST_FONT_PATH).unwrap().read_to_end(&mut bytes).unwrap();
font_context.add_font_from_memory(&font_key, Arc::new(bytes), 0).unwrap();
let font_instance = FontInstance::new(&font_key, TEST_FONT_SIZE);
let glyph_key = GlyphKey::new(TEST_GLYPH_ID, SubpixelOffset(0));
let glyph_outline = font_context.glyph_outline(&font_instance, &glyph_key).unwrap();
let mut glyph_outline_buffer = PathBuffer::new();
glyph_outline_buffer.add_stream(glyph_outline);
info!("endpoints: {:#?}", glyph_outline_buffer.endpoints);
info!("control points: {:#?}", glyph_outline_buffer.control_points);
assert_eq!(glyph_outline_buffer.endpoints.len(), EXPECTED_GLYPH_ENDPOINTS.len());
for (expected_position, endpoint) in
EXPECTED_GLYPH_ENDPOINTS.iter().zip(glyph_outline_buffer.endpoints.iter()) {
let actual_position = endpoint.position;
info!("expected endpoint: {:?} actual endpoint: {:?}", expected_position, actual_position);
assert!(expected_position[0].approx_eq(&actual_position.x) &&
expected_position[1].approx_eq(&actual_position.y));
}
assert_eq!(glyph_outline_buffer.control_points.len(), EXPECTED_GLYPH_CONTROL_POINTS.len());
for (expected_position, actual_position) in
EXPECTED_GLYPH_CONTROL_POINTS.iter().zip(glyph_outline_buffer.control_points.iter()) {
info!("expected control point: {:?} actual control point: {:?}",
expected_position,
actual_position);
assert!(expected_position[0].approx_eq(&actual_position.x) &&
expected_position[1].approx_eq(&actual_position.y));
}
assert_eq!(glyph_outline_buffer.subpaths.len(), EXPECTED_GLYPH_SUBPATHS.len());
for (expected_subpath, actual_subpath) in
EXPECTED_GLYPH_SUBPATHS.iter().zip(glyph_outline_buffer.subpaths.iter()) {
assert_eq!(expected_subpath.first_endpoint_index, actual_subpath.first_endpoint_index);
assert_eq!(expected_subpath.last_endpoint_index, actual_subpath.last_endpoint_index);
}
}