Skip to content

Commit

Permalink
Merge pull request #213 from michaelzoech/simple_stroker
Browse files Browse the repository at this point in the history
Add support for FT_Glyph_Stroke and FT_Glyph_StrokeBorder
  • Loading branch information
bvssvni authored Jul 17, 2018
2 parents 5b0e2ae + 0677982 commit 5975d3c
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 1 deletion.
29 changes: 29 additions & 0 deletions src/glyph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use {
FtResult,
Matrix,
RenderMode,
Stroker,
Vector
};

Expand Down Expand Up @@ -88,6 +89,34 @@ impl Glyph {
}
}

pub fn stroke(&self, stroker: &Stroker) -> FtResult<Glyph> {
let mut the_glyph = self.raw;

let err = unsafe {
ffi::FT_Glyph_Stroke(&mut the_glyph, stroker.raw_stroker(), false as ffi::FT_Bool)
};

if err == ffi::FT_Err_Ok {
Ok(unsafe { Glyph::from_raw(self.library_raw, the_glyph) })
} else {
Err(err.into())
}
}

pub fn stroke_border(&self, stroker: &Stroker, inside: bool) -> FtResult<Glyph> {
let mut the_glyph = self.raw;

let err = unsafe {
ffi::FT_Glyph_StrokeBorder(&mut the_glyph, stroker.raw_stroker(), inside as ffi::FT_Bool, false as ffi::FT_Bool)
};

if err == ffi::FT_Err_Ok {
Ok(unsafe { Glyph::from_raw(self.library_raw, the_glyph) })
} else {
Err(err.into())
}
}

pub fn advance_x(&self) -> isize {
unsafe {
(*self.raw).advance.x as isize
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub use glyph_slot::GlyphSlot;
pub use library::{ Library, LcdFilter };
pub use outline::Outline;
pub use render_mode::RenderMode;
pub use stroker::{Stroker, StrokerLineCap, StrokerLineJoin };
pub use freetype_sys as ffi;

pub mod bitmap;
Expand All @@ -62,6 +63,7 @@ pub mod glyph_slot;
pub mod library;
pub mod outline;
pub mod render_mode;
pub mod stroker;
pub mod tt_os2;

pub type BBox = ffi::FT_BBox;
Expand Down
16 changes: 15 additions & 1 deletion src/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::ffi::{ CString, OsStr };
use std::ptr::null_mut;
use std::rc::Rc;
use libc::{ self, c_void, c_long, size_t };
use { Face, FtResult, Error };
use { Face, FtResult, Error, Stroker };
use ffi;

extern "C" fn alloc_library(_memory: ffi::FT_Memory, size: c_long) -> *mut c_void {
Expand Down Expand Up @@ -89,6 +89,20 @@ impl Library {
}
}

pub fn new_stroker(&self) -> FtResult<Stroker> {
let mut stroker = null_mut();

let err = unsafe {
ffi::FT_Stroker_New(self.raw, &mut stroker)
};

if err == ffi::FT_Err_Ok {
Ok(unsafe { Stroker::from_raw(self.raw, stroker) })
} else {
Err(err.into())
}
}

/// Similar to `new_face`, but loads file data from a byte array in memory
pub fn new_memory_face<T>(&self, buffer: T, face_index: isize) -> FtResult<Face>
where
Expand Down
68 changes: 68 additions & 0 deletions src/stroker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use { ffi };

#[repr(u32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StrokerLineCap {
Butt = ffi::FT_STROKER_LINECAP_BUTT,
Round = ffi::FT_STROKER_LINECAP_ROUND,
Square = ffi::FT_STROKER_LINECAP_SQUARE,
}

#[repr(u32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StrokerLineJoin {
Round = ffi::FT_STROKER_LINEJOIN_ROUND,
Bevel = ffi::FT_STROKER_LINEJOIN_BEVEL,
MiterVariable = ffi::FT_STROKER_LINEJOIN_MITER_VARIABLE,
MiterFixed = ffi::FT_STROKER_LINEJOIN_MITER_FIXED,
}

pub struct Stroker {
library_raw: ffi::FT_Library,
raw: ffi::FT_Stroker,
}

impl Stroker {
pub unsafe fn from_raw(library_raw: ffi::FT_Library, raw: ffi::FT_Stroker) -> Self {
ffi::FT_Reference_Library(library_raw);
Stroker {
library_raw: library_raw,
raw: raw,
}
}

pub fn set(&self, radius: ffi::FT_Fixed, line_cap: StrokerLineCap, line_join: StrokerLineJoin, miter_limit: ffi::FT_Fixed) {
unsafe {
ffi::FT_Stroker_Set(self.raw, radius, line_cap as u32, line_join as u32, miter_limit);
}
}

pub fn raw(&self) -> &ffi::FT_StrokerRec {
unsafe {
&*self.raw
}
}

pub fn raw_mut(&mut self) -> &mut ffi::FT_StrokerRec {
unsafe {
&mut *self.raw
}
}

pub(crate) fn raw_stroker(&self) -> ffi::FT_Stroker {
self.raw
}
}

impl Drop for Stroker {

fn drop(&mut self) {
let err = unsafe {
ffi::FT_Stroker_Done(self.raw);
ffi::FT_Done_Library(self.library_raw)
};
if err != ffi::FT_Err_Ok {
panic!("Failed to drop library");
}
}
}

0 comments on commit 5975d3c

Please sign in to comment.