Pass in the font context to the canvas rendering context constructor so that it
can be reused. Creating a system font source can do I/O on some platforms, so obviously we don't want to do it every frame.
This commit is contained in:
parent
e1bcc11ace
commit
9138e1e0bb
|
@ -39,6 +39,8 @@ struct PFCanvas;
|
|||
typedef struct PFCanvas *PFCanvasRef;
|
||||
struct PFPath;
|
||||
typedef struct PFPath *PFPathRef;
|
||||
struct PFCanvasFontContext;
|
||||
typedef struct PFCanvasFontContext *PFCanvasFontContextRef;
|
||||
|
||||
// `geometry`
|
||||
|
||||
|
@ -103,8 +105,10 @@ typedef struct PFSceneProxy *PFSceneProxyRef;
|
|||
|
||||
// `canvas`
|
||||
|
||||
PFCanvasRef PFCanvasCreate(const PFPoint2DF *size);
|
||||
PFCanvasRef PFCanvasCreate(PFCanvasFontContextRef font_context, const PFPoint2DF *size);
|
||||
void PFCanvasDestroy(PFCanvasRef canvas);
|
||||
PFCanvasFontContextRef PFCanvasFontContextCreate();
|
||||
void PFCanvasFontContextDestroy(PFCanvasFontContextRef font_context);
|
||||
PFSceneRef PFCanvasCreateScene(PFCanvasRef canvas);
|
||||
void PFCanvasFillRect(PFCanvasRef canvas, const PFRectF *rect);
|
||||
void PFCanvasStrokeRect(PFCanvasRef canvas, const PFRectF *rect);
|
||||
|
|
20
c/src/lib.rs
20
c/src/lib.rs
|
@ -11,7 +11,7 @@
|
|||
//! C bindings to Pathfinder.
|
||||
|
||||
use gl;
|
||||
use pathfinder_canvas::{CanvasRenderingContext2D, Path2D};
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
|
||||
use pathfinder_geometry::basic::point::{Point2DF, Point2DI};
|
||||
use pathfinder_geometry::basic::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::color::ColorF;
|
||||
|
@ -39,6 +39,7 @@ pub const PF_CLEAR_FLAGS_HAS_RECT: u8 = 0x8;
|
|||
// `canvas`
|
||||
pub type PFCanvasRef = *mut CanvasRenderingContext2D;
|
||||
pub type PFPathRef = *mut Path2D;
|
||||
pub type PFCanvasFontContextRef = *mut CanvasFontContext;
|
||||
|
||||
// `geometry`
|
||||
#[repr(C)]
|
||||
|
@ -102,8 +103,11 @@ pub struct PFRenderOptions {
|
|||
// `canvas`
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasCreate(size: *const PFPoint2DF) -> PFCanvasRef {
|
||||
Box::into_raw(Box::new(CanvasRenderingContext2D::new((*size).to_rust())))
|
||||
pub unsafe extern "C" fn PFCanvasCreate(font_context: PFCanvasFontContextRef,
|
||||
size: *const PFPoint2DF)
|
||||
-> PFCanvasRef {
|
||||
Box::into_raw(Box::new(CanvasRenderingContext2D::new(*Box::from_raw(font_context),
|
||||
(*size).to_rust())))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -111,6 +115,16 @@ pub unsafe extern "C" fn PFCanvasDestroy(canvas: PFCanvasRef) {
|
|||
drop(Box::from_raw(canvas))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasFontContextCreate() -> PFCanvasFontContextRef {
|
||||
Box::into_raw(Box::new(CanvasFontContext::new()))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasFontContextDestroy(font_context: PFCanvasFontContextRef) {
|
||||
drop(Box::from_raw(font_context))
|
||||
}
|
||||
|
||||
/// Consumes the canvas.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasCreateScene(canvas: PFCanvasRef) -> PFSceneRef {
|
||||
|
|
|
@ -35,41 +35,24 @@ pub struct CanvasRenderingContext2D {
|
|||
scene: Scene,
|
||||
current_state: State,
|
||||
saved_states: Vec<State>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
font_source: SystemSource,
|
||||
#[allow(dead_code)]
|
||||
default_font_collection: Arc<FontCollection>,
|
||||
font_context: CanvasFontContext,
|
||||
}
|
||||
|
||||
impl CanvasRenderingContext2D {
|
||||
#[inline]
|
||||
pub fn new(size: Point2DF) -> CanvasRenderingContext2D {
|
||||
pub fn new(font_context: CanvasFontContext, size: Point2DF) -> CanvasRenderingContext2D {
|
||||
let mut scene = Scene::new();
|
||||
scene.set_view_box(RectF::new(Point2DF::default(), size));
|
||||
CanvasRenderingContext2D::from_scene(scene)
|
||||
CanvasRenderingContext2D::from_scene(font_context, scene)
|
||||
}
|
||||
|
||||
pub fn from_scene(scene: Scene) -> CanvasRenderingContext2D {
|
||||
// TODO(pcwalton): Allow the user to cache this?
|
||||
let font_source = SystemSource::new();
|
||||
|
||||
let mut default_font_collection = FontCollection::new();
|
||||
let default_font =
|
||||
font_source.select_best_match(&[FamilyName::SansSerif], &Properties::new())
|
||||
.expect("Failed to select the default font!")
|
||||
.load()
|
||||
.expect("Failed to load the default font!");
|
||||
default_font_collection.add_family(FontFamily::new_from_font(default_font));
|
||||
let default_font_collection = Arc::new(default_font_collection);
|
||||
|
||||
pub fn from_scene(font_context: CanvasFontContext, scene: Scene) -> CanvasRenderingContext2D {
|
||||
CanvasRenderingContext2D {
|
||||
scene,
|
||||
current_state: State::default(default_font_collection.clone()),
|
||||
current_state: State::default(font_context.default_font_collection.clone()),
|
||||
saved_states: vec![],
|
||||
|
||||
font_source,
|
||||
default_font_collection,
|
||||
font_context,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,3 +318,31 @@ impl FillStyle {
|
|||
match *self { FillStyle::Color(color) => Paint { color } }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CanvasFontContext {
|
||||
#[allow(dead_code)]
|
||||
font_source: Arc<SystemSource>,
|
||||
#[allow(dead_code)]
|
||||
default_font_collection: Arc<FontCollection>,
|
||||
}
|
||||
|
||||
impl CanvasFontContext {
|
||||
pub fn new() -> CanvasFontContext {
|
||||
let font_source = Arc::new(SystemSource::new());
|
||||
|
||||
let mut default_font_collection = FontCollection::new();
|
||||
let default_font =
|
||||
font_source.select_best_match(&[FamilyName::SansSerif], &Properties::new())
|
||||
.expect("Failed to select the default font!")
|
||||
.load()
|
||||
.expect("Failed to load the default font!");
|
||||
default_font_collection.add_family(FontFamily::new_from_font(default_font));
|
||||
let default_font_collection = Arc::new(default_font_collection);
|
||||
|
||||
CanvasFontContext {
|
||||
font_source,
|
||||
default_font_collection,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,8 @@ int main(int argc, const char **argv) {
|
|||
});
|
||||
|
||||
// Make a canvas. We're going to draw a house.
|
||||
PFCanvasRef canvas = PFCanvasCreate(&(PFPoint2DF){640.0f, 480.0f});
|
||||
PFCanvasRef canvas = PFCanvasCreate(PFCanvasFontContextCreate(),
|
||||
&(PFPoint2DF){640.0f, 480.0f});
|
||||
|
||||
// Set line width.
|
||||
PFCanvasSetLineWidth(canvas, 10.0f);
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use pathfinder_canvas::{CanvasRenderingContext2D, Path2D};
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
|
||||
use pathfinder_geometry::basic::point::{Point2DF, Point2DI};
|
||||
use pathfinder_geometry::basic::rect::RectF;
|
||||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_geometry::stroke::LineJoin;
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::FilesystemResourceLoader;
|
||||
use pathfinder_gpu::{ClearParams, Device};
|
||||
|
@ -55,7 +54,7 @@ fn main() {
|
|||
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
|
||||
|
||||
// Make a canvas. We're going to draw a house.
|
||||
let mut canvas = CanvasRenderingContext2D::new(window_size.to_f32());
|
||||
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
|
||||
|
||||
// Set line width.
|
||||
canvas.set_line_width(10.0);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use pathfinder_canvas::{CanvasRenderingContext2D, FillStyle, Path2D};
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, FillStyle, Path2D};
|
||||
use pathfinder_geometry::basic::point::{Point2DF, Point2DI};
|
||||
use pathfinder_geometry::color::{ColorF, ColorU};
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
|
@ -85,6 +85,7 @@ fn main() {
|
|||
|
||||
struct MoireRenderer {
|
||||
renderer: Renderer<GLDevice>,
|
||||
font_context: CanvasFontContext,
|
||||
scene: SceneProxy,
|
||||
frame: i32,
|
||||
window_size: Point2DI,
|
||||
|
@ -98,6 +99,7 @@ impl MoireRenderer {
|
|||
-> MoireRenderer {
|
||||
MoireRenderer {
|
||||
renderer,
|
||||
font_context: CanvasFontContext::new(),
|
||||
scene: SceneProxy::new(RayonExecutor),
|
||||
frame: 0,
|
||||
window_size,
|
||||
|
@ -128,7 +130,8 @@ impl MoireRenderer {
|
|||
});
|
||||
|
||||
// Make a canvas.
|
||||
let mut canvas = CanvasRenderingContext2D::new(self.drawable_size.to_f32());
|
||||
let mut canvas = CanvasRenderingContext2D::new(self.font_context.clone(),
|
||||
self.drawable_size.to_f32());
|
||||
canvas.set_line_width(CIRCLE_THICKNESS * self.device_pixel_ratio);
|
||||
canvas.set_stroke_style(FillStyle::Color(foreground_color.to_u8()));
|
||||
canvas.set_global_alpha(0.75);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use pathfinder_canvas::CanvasRenderingContext2D;
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D};
|
||||
use pathfinder_geometry::basic::point::{Point2DF, Point2DI};
|
||||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
|
@ -53,7 +53,7 @@ fn main() {
|
|||
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
|
||||
|
||||
// Make a canvas. We're going to draw some text.
|
||||
let mut canvas = CanvasRenderingContext2D::new(window_size.to_f32());
|
||||
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
|
||||
|
||||
// Draw the text.
|
||||
canvas.set_font_size(32.0);
|
||||
|
|
Loading…
Reference in New Issue