177 lines
5.5 KiB
Rust
177 lines
5.5 KiB
Rust
/* 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 http://mozilla.org/MPL/2.0/. */
|
|
|
|
use std::sync::Arc;
|
|
use std::mem;
|
|
|
|
use api::{
|
|
IdNamespace, FontTemplate, FontKey, FontInstanceKey, FontInstanceOptions,
|
|
FontInstancePlatformOptions, ColorF, FontInstanceFlags, units::DevicePoint,
|
|
};
|
|
use glutin::ContextBuilder;
|
|
use glutin::dpi::PhysicalSize;
|
|
use glutin::event::{Event, WindowEvent};
|
|
use glutin::event_loop::{ControlFlow, EventLoop};
|
|
use glutin::window::WindowBuilder;
|
|
use rayon::ThreadPoolBuilder;
|
|
use wr_glyph_rasterizer::RasterizedGlyph;
|
|
use wr_glyph_rasterizer::{
|
|
SharedFontResources, BaseFontInstance, GlyphRasterizer, FontInstance, GlyphKey,
|
|
SubpixelDirection, profiler::GlyphRasterizeProfiler,
|
|
};
|
|
|
|
#[path = "common/boilerplate.rs"]
|
|
mod boilerplate;
|
|
|
|
struct Profiler;
|
|
|
|
impl GlyphRasterizeProfiler for Profiler {
|
|
fn start_time(&mut self) {}
|
|
fn end_time(&mut self) -> f64 {
|
|
0.
|
|
}
|
|
fn set(&mut self, _value: f64) {}
|
|
}
|
|
|
|
fn load_glyphs() -> Vec<RasterizedGlyph> {
|
|
let namespace = IdNamespace(0);
|
|
let mut fonts = SharedFontResources::new(namespace);
|
|
|
|
let font_key = FontKey::new(namespace, 0);
|
|
let raw_font_data = include_bytes!("../../wrench/reftests/text/FreeSans.ttf");
|
|
let font_template = FontTemplate::Raw(Arc::new(raw_font_data.to_vec()), 0);
|
|
let shared_font_key = fonts
|
|
.font_keys
|
|
.add_key(&font_key, &font_template)
|
|
.expect("Failed to add font key");
|
|
|
|
let font_instance_key = FontInstanceKey::new(namespace, 1);
|
|
fonts.templates.add_font(shared_font_key, font_template);
|
|
assert!(fonts.templates.has_font(&shared_font_key));
|
|
|
|
// AddFontInstance will only be processed here, not in the resource cache, so it
|
|
// is safe to take the options rather than clone them.
|
|
let base = BaseFontInstance::new(
|
|
font_instance_key,
|
|
shared_font_key,
|
|
32.,
|
|
mem::take(&mut Some(FontInstanceOptions::default())),
|
|
mem::take(&mut Some(FontInstancePlatformOptions::default())),
|
|
mem::take(&mut Vec::new()),
|
|
);
|
|
let shared_instance = fonts
|
|
.instance_keys
|
|
.add_key(base)
|
|
.expect("Failed to add font instance key");
|
|
fonts.instances.add_font_instance(shared_instance);
|
|
|
|
let workers = {
|
|
let worker = ThreadPoolBuilder::new()
|
|
.thread_name(|idx| format!("WRWorker#{}", idx))
|
|
.build();
|
|
Arc::new(worker.unwrap())
|
|
};
|
|
let mut glyph_rasterizer = GlyphRasterizer::new(workers, false);
|
|
|
|
glyph_rasterizer.add_font(
|
|
shared_font_key,
|
|
fonts
|
|
.templates
|
|
.get_font(&shared_font_key)
|
|
.expect("Could not find FontTemplate"),
|
|
);
|
|
|
|
let mut font = FontInstance::new(
|
|
fonts
|
|
.instances
|
|
.get_font_instance(font_instance_key)
|
|
.expect("Could not found BaseFontInstance"),
|
|
ColorF::BLACK.into(),
|
|
api::FontRenderMode::Alpha,
|
|
FontInstanceFlags::SUBPIXEL_POSITION | FontInstanceFlags::FONT_SMOOTHING,
|
|
);
|
|
|
|
glyph_rasterizer.prepare_font(&mut font);
|
|
|
|
let glyph_keys = [
|
|
glyph_rasterizer
|
|
.get_glyph_index(shared_font_key, 'A')
|
|
.expect("Failed to get glyph index"),
|
|
glyph_rasterizer
|
|
.get_glyph_index(shared_font_key, 'B')
|
|
.expect("Failed to get glyph index"),
|
|
glyph_rasterizer
|
|
.get_glyph_index(shared_font_key, 'C')
|
|
.expect("Failed to get glyph index"),
|
|
];
|
|
|
|
let glyph_keys = glyph_keys.map(|g| {
|
|
GlyphKey::new(
|
|
g,
|
|
DevicePoint::new(100., 100.),
|
|
SubpixelDirection::Horizontal,
|
|
)
|
|
});
|
|
|
|
glyph_rasterizer.request_glyphs(font, &glyph_keys, |_| true);
|
|
|
|
let mut glyphs = vec![];
|
|
glyph_rasterizer.resolve_glyphs(
|
|
|job, _| {
|
|
if let Ok(glyph) = job.result {
|
|
glyphs.push(glyph);
|
|
}
|
|
},
|
|
&mut Profiler,
|
|
);
|
|
|
|
glyphs
|
|
}
|
|
|
|
fn main() {
|
|
let glyphs = load_glyphs();
|
|
|
|
let el = EventLoop::new();
|
|
let wb = WindowBuilder::new()
|
|
.with_title("A fantastic window!")
|
|
.with_inner_size(PhysicalSize::new(1900. as f64, 1300. as f64));
|
|
|
|
let windowed_context = ContextBuilder::new()
|
|
.with_gl(glutin::GlRequest::GlThenGles {
|
|
opengl_version: (3, 2),
|
|
opengles_version: (3, 0),
|
|
})
|
|
.build_windowed(wb, &el)
|
|
.unwrap();
|
|
|
|
let windowed_context = unsafe { windowed_context.make_current().unwrap() };
|
|
|
|
let gl = boilerplate::load(windowed_context.context(), glyphs);
|
|
|
|
el.run(move |event, _, control_flow| {
|
|
*control_flow = ControlFlow::Wait;
|
|
|
|
match event {
|
|
Event::LoopDestroyed => (),
|
|
Event::WindowEvent { event, .. } => match event {
|
|
WindowEvent::Resized(physical_size) => windowed_context.resize(physical_size),
|
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
|
_ => (),
|
|
},
|
|
Event::RedrawRequested(_) => {
|
|
let size = windowed_context.window().inner_size();
|
|
let scale_factor = windowed_context.window().scale_factor();
|
|
gl.draw_frame(
|
|
size.width as f32,
|
|
size.height as f32,
|
|
[0., 0., 0., 1.0],
|
|
[1., 1., 1., 1.0],
|
|
scale_factor as f32,
|
|
);
|
|
windowed_context.swap_buffers().unwrap();
|
|
}
|
|
_ => (),
|
|
}
|
|
});
|
|
}
|