Navigation Menu

Skip to content

Commit

Permalink
Allow font bytes to have multiple owners
Browse files Browse the repository at this point in the history
Signed-off-by: Victor Porof <victor.porof@gmail.com>
  • Loading branch information
victorporof committed Dec 20, 2017
1 parent f470811 commit 8cb2483
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -24,5 +24,6 @@
rusti.sh
watch.sh
/examples/**/target
.vscode

Cargo.lock
2 changes: 1 addition & 1 deletion Cargo.toml
@@ -1,7 +1,7 @@
[package]

name = "freetype-rs"
version = "0.16.0"
version = "0.17.0"
authors = ["Coeuvre <coeuvre@gmail.com>"]
keywords = ["freetype", "font", "glyph"]
description = "Bindings for FreeType font library"
Expand Down
26 changes: 16 additions & 10 deletions src/face.rs
@@ -1,7 +1,7 @@
use std::fmt;
use std::ffi::CStr;
use std::rc::Rc;
use { ffi, FtResult, GlyphSlot, Matrix, Vector };
use std::marker::PhantomData;

#[repr(u32)]
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -38,14 +38,14 @@ bitflags! {
}

#[derive(Eq, PartialEq, Hash)]
pub struct Face<'a> {
pub struct Face {
library_raw: ffi::FT_Library,
raw: ffi::FT_Face,
glyph: GlyphSlot,
_phantom: PhantomData<&'a ()>
bytes: Option<Rc<Vec<u8>>>
}

impl<'a> Clone for Face<'a> {
impl Clone for Face {
fn clone(&self) -> Self {
let err = unsafe {
ffi::FT_Reference_Library(self.library_raw)
Expand All @@ -59,18 +59,23 @@ impl<'a> Clone for Face<'a> {
if err != ffi::FT_Err_Ok {
panic!("Failed to reference face");
}
Face { ..*self }
Face {
library_raw: self.library_raw,
raw: self.raw,
glyph: self.glyph,
bytes: self.bytes.clone()
}
}
}

impl<'a> Face<'a> {
pub unsafe fn from_raw(library_raw: ffi::FT_Library, raw: ffi::FT_Face) -> Self {
impl Face {
pub unsafe fn from_raw(library_raw: ffi::FT_Library, raw: ffi::FT_Face, bytes: Option<Rc<Vec<u8>>>) -> Self {
ffi::FT_Reference_Library(library_raw);
Face {
library_raw: library_raw,
raw: raw,
glyph: GlyphSlot::from_raw(library_raw, (*raw).glyph),
_phantom: PhantomData
bytes: bytes,
}
}

Expand Down Expand Up @@ -354,15 +359,15 @@ impl<'a> Face<'a> {
}
}

impl<'a> fmt::Debug for Face<'a> {
impl fmt::Debug for Face {
fn fmt(&self, form: &mut fmt::Formatter) -> fmt::Result {
let name = self.style_name().unwrap_or("[unknown name]".to_owned());
try!(form.write_str("Font Face: "));
form.write_str(&name[..])
}
}

impl<'a> Drop for Face<'a> {
impl Drop for Face {
fn drop(&mut self) {
let err = unsafe {
ffi::FT_Done_Face(self.raw)
Expand All @@ -376,5 +381,6 @@ impl<'a> Drop for Face<'a> {
if err != ffi::FT_Err_Ok {
panic!("Failed to drop library")
}
self.bytes = None;
}
}
13 changes: 9 additions & 4 deletions src/library.rs
@@ -1,5 +1,6 @@
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 ffi;
Expand Down Expand Up @@ -69,7 +70,7 @@ impl Library {

/// Open a font file using its pathname. `face_index` should be 0 if there is only 1 font
/// in the file.
pub fn new_face<P>(&self, path: P, face_index: isize) -> FtResult<Face<'static>>
pub fn new_face<P>(&self, path: P, face_index: isize) -> FtResult<Face>
where P: AsRef<OsStr>
{
let mut face = null_mut();
Expand All @@ -82,22 +83,26 @@ impl Library {
ffi::FT_New_Face(self.raw, path.as_ptr() as *const _, face_index as ffi::FT_Long, &mut face)
};
if err == ffi::FT_Err_Ok {
Ok(unsafe { Face::from_raw(self.raw, face) })
Ok(unsafe { Face::from_raw(self.raw, face, None) })
} else {
Err(err.into())
}
}

/// Similar to `new_face`, but loads file data from a byte array in memory
pub fn new_memory_face<'a>(&self, buffer: &'a [u8], face_index: isize) -> FtResult<Face<'a>> {
pub fn new_memory_face<T>(&self, buffer: T, face_index: isize) -> FtResult<Face>
where
T: Into<Rc<Vec<u8>>>
{
let mut face = null_mut();
let buffer = buffer.into();

let err = unsafe {
ffi::FT_New_Memory_Face(self.raw, buffer.as_ptr(), buffer.len() as ffi::FT_Long,
face_index as ffi::FT_Long, &mut face)
};
if err == ffi::FT_Err_Ok {
Ok(unsafe { Face::from_raw(self.raw, face) })
Ok(unsafe { Face::from_raw(self.raw, face, Some(buffer)) })
} else {
Err(err.into())
}
Expand Down

0 comments on commit 8cb2483

Please sign in to comment.