Add C bindings to the canvas text APIs

This commit is contained in:
Patrick Walton 2019-06-20 16:07:38 -07:00
parent 2129e4f2e1
commit 36db39883c
4 changed files with 73 additions and 1 deletions

1
Cargo.lock generated
View File

@ -1318,6 +1318,7 @@ name = "pathfinder_c"
version = "0.1.0"
dependencies = [
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_canvas 0.1.0",
"pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",

View File

@ -9,6 +9,7 @@ crate-type = ["staticlib"]
[dependencies]
gl = "0.6"
libc = "0.2"
[dependencies.pathfinder_canvas]
path = "../canvas"

View File

@ -56,6 +56,10 @@ typedef struct PFCanvasFontContext *PFCanvasFontContextRef;
typedef uint8_t PFLineCap;
typedef uint8_t PFLineJoin;
typedef uint8_t PFArcDirection;
struct PFTextMetrics {
float width;
};
typedef struct PFTextMetrics PFTextMetrics;
// `geometry`
@ -125,6 +129,18 @@ PFCanvasFontContextRef PFCanvasFontContextClone(PFCanvasFontContextRef font_cont
PFSceneRef PFCanvasCreateScene(PFCanvasRef canvas);
void PFCanvasFillRect(PFCanvasRef canvas, const PFRectF *rect);
void PFCanvasStrokeRect(PFCanvasRef canvas, const PFRectF *rect);
void PFCanvasFillText(PFCanvasRef canvas,
const char *string,
size_t string_len,
const PFVector2F *position);
void PFCanvasStrokeText(PFCanvasRef canvas,
const char *string,
size_t string_len,
const PFVector2F *position);
void PFCanvasMeasureText(PFCanvasRef canvas,
const char *string,
size_t string_len,
PFTextMetrics *out_text_metrics);
void PFCanvasSetLineWidth(PFCanvasRef canvas, float new_line_width);
void PFCanvasSetLineCap(PFCanvasRef canvas, PFLineCap new_line_cap);
void PFCanvasSetLineJoin(PFCanvasRef canvas, PFLineJoin new_line_join);

View File

@ -11,7 +11,8 @@
//! C bindings to Pathfinder.
use gl;
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, LineJoin, Path2D};
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, LineJoin};
use pathfinder_canvas::{Path2D, TextMetrics};
use pathfinder_geometry::basic::rect::{RectF, RectI};
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::color::ColorF;
@ -29,6 +30,7 @@ use pathfinder_simd::default::F32x4;
use std::ffi::CString;
use std::os::raw::{c_char, c_void};
use std::slice;
use std::str;
// Constants
@ -60,6 +62,10 @@ pub type PFCanvasFontContextRef = *mut CanvasFontContext;
pub type PFLineCap = u8;
pub type PFLineJoin = u8;
pub type PFArcDirection = u8;
#[repr(C)]
pub struct PFTextMetrics {
pub width: f32,
}
// `geometry`
#[repr(C)]
@ -155,6 +161,8 @@ pub unsafe extern "C" fn PFCanvasCreateScene(canvas: PFCanvasRef) -> PFSceneRef
Box::into_raw(Box::new(Box::from_raw(canvas).into_scene()))
}
// Drawing rectangles
#[no_mangle]
pub unsafe extern "C" fn PFCanvasFillRect(canvas: PFCanvasRef, rect: *const PFRectF) {
(*canvas).fill_rect((*rect).to_rust())
@ -165,6 +173,33 @@ pub unsafe extern "C" fn PFCanvasStrokeRect(canvas: PFCanvasRef, rect: *const PF
(*canvas).stroke_rect((*rect).to_rust())
}
// Drawing text
#[no_mangle]
pub unsafe extern "C" fn PFCanvasFillText(canvas: PFCanvasRef,
string: *const c_char,
string_len: usize,
position: *const PFVector2F) {
(*canvas).fill_text(to_rust_string(&string, string_len), (*position).to_rust())
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasStrokeText(canvas: PFCanvasRef,
string: *const c_char,
string_len: usize,
position: *const PFVector2F) {
(*canvas).stroke_text(to_rust_string(&string, string_len), (*position).to_rust())
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasMeasureText(canvas: PFCanvasRef,
string: *const c_char,
string_len: usize,
out_text_metrics: *mut PFTextMetrics) {
debug_assert!(!out_text_metrics.is_null());
*out_text_metrics = (*canvas).measure_text(to_rust_string(&string, string_len)).to_c()
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasSetLineWidth(canvas: PFCanvasRef, new_line_width: f32) {
(*canvas).set_line_width(new_line_width)
@ -389,6 +424,25 @@ pub unsafe extern "C" fn PFSceneProxyDestroy(scene_proxy: PFSceneProxyRef) {
drop(Box::from_raw(scene_proxy))
}
// Helpers for `canvas`
unsafe fn to_rust_string(ptr: &*const c_char, mut len: usize) -> &str {
if len == 0 {
len = libc::strlen(*ptr);
}
str::from_utf8(slice::from_raw_parts(*ptr as *const u8, len)).unwrap()
}
trait TextMetricsExt {
fn to_c(&self) -> PFTextMetrics;
}
impl TextMetricsExt for TextMetrics {
fn to_c(&self) -> PFTextMetrics {
PFTextMetrics { width: self.width }
}
}
// Helpers for `geometry`
impl PFColorF {