tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

basic.rs (5687B)


      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 std::sync::Arc;
      6 use std::mem;
      7 
      8 use api::{
      9    IdNamespace, FontTemplate, FontKey, FontInstanceKey, FontInstanceOptions,
     10    FontInstancePlatformOptions, ColorF, FontInstanceFlags, units::DevicePoint,
     11 };
     12 use glutin::ContextBuilder;
     13 use glutin::dpi::PhysicalSize;
     14 use glutin::event::{Event, WindowEvent};
     15 use glutin::event_loop::{ControlFlow, EventLoop};
     16 use glutin::window::WindowBuilder;
     17 use rayon::ThreadPoolBuilder;
     18 use wr_glyph_rasterizer::RasterizedGlyph;
     19 use wr_glyph_rasterizer::{
     20    SharedFontResources, BaseFontInstance, GlyphRasterizer, FontInstance, GlyphKey,
     21    SubpixelDirection, profiler::GlyphRasterizeProfiler,
     22 };
     23 
     24 #[path = "common/boilerplate.rs"]
     25 mod boilerplate;
     26 
     27 struct Profiler;
     28 
     29 impl GlyphRasterizeProfiler for Profiler {
     30    fn start_time(&mut self) {}
     31    fn end_time(&mut self) -> f64 {
     32        0.
     33    }
     34    fn set(&mut self, _value: f64) {}
     35 }
     36 
     37 fn load_glyphs() -> Vec<RasterizedGlyph> {
     38    let namespace = IdNamespace(0);
     39    let mut fonts = SharedFontResources::new(namespace);
     40 
     41    let font_key = FontKey::new(namespace, 0);
     42    let raw_font_data = include_bytes!("../../wrench/reftests/text/FreeSans.ttf");
     43    let font_template = FontTemplate::Raw(Arc::new(raw_font_data.to_vec()), 0);
     44    let shared_font_key = fonts
     45        .font_keys
     46        .add_key(&font_key, &font_template)
     47        .expect("Failed to add font key");
     48 
     49    let font_instance_key = FontInstanceKey::new(namespace, 1);
     50    fonts.templates.add_font(shared_font_key, font_template);
     51    assert!(fonts.templates.has_font(&shared_font_key));
     52 
     53    // AddFontInstance will only be processed here, not in the resource cache, so it
     54    // is safe to take the options rather than clone them.
     55    let base = BaseFontInstance::new(
     56        font_instance_key,
     57        shared_font_key,
     58        32.,
     59        mem::take(&mut Some(FontInstanceOptions::default())),
     60        mem::take(&mut Some(FontInstancePlatformOptions::default())),
     61        mem::take(&mut Vec::new()),
     62    );
     63    let shared_instance = fonts
     64        .instance_keys
     65        .add_key(base)
     66        .expect("Failed to add font instance key");
     67    fonts.instances.add_font_instance(shared_instance);
     68 
     69    let workers = {
     70        let worker = ThreadPoolBuilder::new()
     71            .thread_name(|idx| format!("WRWorker#{}", idx))
     72            .build();
     73        Arc::new(worker.unwrap())
     74    };
     75    let mut glyph_rasterizer = GlyphRasterizer::new(workers, None, false);
     76 
     77    glyph_rasterizer.add_font(
     78        shared_font_key,
     79        fonts
     80            .templates
     81            .get_font(&shared_font_key)
     82            .expect("Could not find FontTemplate"),
     83    );
     84 
     85    let mut font = FontInstance::new(
     86        fonts
     87            .instances
     88            .get_font_instance(font_instance_key)
     89            .expect("Could not found BaseFontInstance"),
     90        ColorF::BLACK.into(),
     91        api::FontRenderMode::Alpha,
     92        FontInstanceFlags::SUBPIXEL_POSITION | FontInstanceFlags::FONT_SMOOTHING,
     93    );
     94 
     95    glyph_rasterizer.prepare_font(&mut font);
     96 
     97    let glyph_keys = [
     98        glyph_rasterizer
     99            .get_glyph_index(shared_font_key, 'A')
    100            .expect("Failed to get glyph index"),
    101        glyph_rasterizer
    102            .get_glyph_index(shared_font_key, 'B')
    103            .expect("Failed to get glyph index"),
    104        glyph_rasterizer
    105            .get_glyph_index(shared_font_key, 'C')
    106            .expect("Failed to get glyph index"),
    107    ];
    108 
    109    let glyph_keys = glyph_keys.map(|g| {
    110        GlyphKey::new(
    111            g,
    112            DevicePoint::new(100., 100.),
    113            SubpixelDirection::Horizontal,
    114        )
    115    });
    116 
    117    glyph_rasterizer.request_glyphs(font, &glyph_keys, |_| true);
    118 
    119    let mut glyphs = vec![];
    120    glyph_rasterizer.resolve_glyphs(
    121        |job, _| {
    122            if let Ok(glyph) = job.result {
    123                glyphs.push(glyph);
    124            }
    125        },
    126        &mut Profiler,
    127    );
    128 
    129    glyphs
    130 }
    131 
    132 fn main() {
    133    let glyphs = load_glyphs();
    134 
    135    let el = EventLoop::new();
    136    let wb = WindowBuilder::new()
    137        .with_title("A fantastic window!")
    138        .with_inner_size(PhysicalSize::new(1900. as f64, 1300. as f64));
    139 
    140    let windowed_context = ContextBuilder::new()
    141        .with_gl(glutin::GlRequest::GlThenGles {
    142            opengl_version: (3, 2),
    143            opengles_version: (3, 0),
    144        })
    145        .build_windowed(wb, &el)
    146        .unwrap();
    147 
    148    let windowed_context = unsafe { windowed_context.make_current().unwrap() };
    149 
    150    let gl = boilerplate::load(windowed_context.context(), glyphs);
    151 
    152    el.run(move |event, _, control_flow| {
    153        *control_flow = ControlFlow::Wait;
    154 
    155        match event {
    156            Event::LoopDestroyed => (),
    157            Event::WindowEvent { event, .. } => match event {
    158                WindowEvent::Resized(physical_size) => windowed_context.resize(physical_size),
    159                WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
    160                _ => (),
    161            },
    162            Event::RedrawRequested(_) => {
    163                let size = windowed_context.window().inner_size();
    164                let scale_factor = windowed_context.window().scale_factor();
    165                gl.draw_frame(
    166                    size.width as f32,
    167                    size.height as f32,
    168                    [0., 0., 0., 1.0],
    169                    [1., 1., 1., 1.0],
    170                    scale_factor as f32,
    171                );
    172                windowed_context.swap_buffers().unwrap();
    173            }
    174            _ => (),
    175        }
    176    });
    177 }