aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock5
-rw-r--r--ffi-util/Cargo.toml6
-rw-r--r--ffi-util/src/lib.rs102
-rw-r--r--font/Cargo.lock5
-rw-r--r--font/Cargo.toml1
-rw-r--r--font/src/ft/list_fonts.rs147
-rw-r--r--font/src/lib.rs3
7 files changed, 160 insertions, 109 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0d81b264..1a8a7937 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -231,6 +231,10 @@ dependencies = [
]
[[package]]
+name = "ffi-util"
+version = "0.1.0"
+
+[[package]]
name = "filetime"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -247,6 +251,7 @@ dependencies = [
"core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ffi-util 0.1.0",
"freetype-rs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
diff --git a/ffi-util/Cargo.toml b/ffi-util/Cargo.toml
new file mode 100644
index 00000000..740a3b95
--- /dev/null
+++ b/ffi-util/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "ffi-util"
+version = "0.1.0"
+authors = ["Joe Wilm <joe@jwilm.com>"]
+
+[dependencies]
diff --git a/ffi-util/src/lib.rs b/ffi-util/src/lib.rs
new file mode 100644
index 00000000..be82e560
--- /dev/null
+++ b/ffi-util/src/lib.rs
@@ -0,0 +1,102 @@
+// Copyright 2011 Google Inc.
+// 2013 Jack Lloyd
+// 2013-2014 Steven Fackler
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+use std::cell::UnsafeCell;
+
+/// This is intended to be used as the inner type for `FooRef` types converted from raw C pointers.
+/// It has an `UnsafeCell` internally to inform the compiler about aliasability and doesn't
+/// implement `Copy`, so it can't be dereferenced.
+pub struct Opaque(UnsafeCell<()>);
+
+/// A type implemented by wrappers over foreign types.
+///
+/// This should not be implemented by anything outside of this crate; new methods may be added at
+/// any time.
+pub trait ForeignType: Sized {
+ /// The raw C type.
+ type CType;
+
+ /// The type representing a reference to this type.
+ type Ref: ForeignTypeRef<CType = Self::CType>;
+
+ /// Constructs an instance of this type from its raw type.
+ unsafe fn from_ptr(ptr: *mut Self::CType) -> Self;
+}
+
+/// A trait implemented by types which reference borrowed foreign types.
+///
+/// This should not be implemented by anything outside of this crate; new methods may be added at
+/// any time.
+pub trait ForeignTypeRef: Sized {
+ /// The raw C type.
+ type CType;
+
+ /// Constructs a shared instance of this type from its raw type.
+ unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self {
+ &*(ptr as *mut _)
+ }
+
+ /// Constructs a mutable reference of this type from its raw type.
+ unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self {
+ &mut *(ptr as *mut _)
+ }
+
+ /// Returns a raw pointer to the wrapped value.
+ fn as_ptr(&self) -> *mut Self::CType {
+ self as *const _ as *mut _
+ }
+}
+
+#[macro_export]
+macro_rules! ffi_type {
+ ($n:ident, $r:ident, $c:path, $d:path) => {
+ pub struct $n(*mut $c);
+
+ impl $crate::ForeignType for $n {
+ type CType = $c;
+ type Ref = $r;
+
+ unsafe fn from_ptr(ptr: *mut $c) -> $n {
+ $n(ptr)
+ }
+ }
+
+ impl Drop for $n {
+ fn drop(&mut self) {
+ unsafe { $d(self.0) }
+ }
+ }
+
+ impl ::std::ops::Deref for $n {
+ type Target = $r;
+
+ fn deref(&self) -> &$r {
+ unsafe { $crate::ForeignTypeRef::from_ptr(self.0) }
+ }
+ }
+
+ impl ::std::ops::DerefMut for $n {
+ fn deref_mut(&mut self) -> &mut $r {
+ unsafe { $crate::ForeignTypeRef::from_ptr_mut(self.0) }
+ }
+ }
+
+ pub struct $r($crate::Opaque);
+
+ impl $crate::ForeignTypeRef for $r {
+ type CType = $c;
+ }
+ }
+}
diff --git a/font/Cargo.lock b/font/Cargo.lock
index 5dde9e48..9464e209 100644
--- a/font/Cargo.lock
+++ b/font/Cargo.lock
@@ -7,6 +7,7 @@ dependencies = [
"core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ffi-util 0.1.0",
"freetype-rs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
@@ -76,6 +77,10 @@ dependencies = [
]
[[package]]
+name = "ffi-util"
+version = "0.1.0"
+
+[[package]]
name = "freetype-rs"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/font/Cargo.toml b/font/Cargo.toml
index d6cfcc38..f0c3e06a 100644
--- a/font/Cargo.toml
+++ b/font/Cargo.toml
@@ -8,6 +8,7 @@ license = "Apache-2.0"
[dependencies]
euclid = "0.6.8"
libc = "0.2.11"
+ffi-util = { path = "../ffi-util" }
[target.'cfg(not(target_os = "macos"))'.dependencies]
servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig" }
diff --git a/font/src/ft/list_fonts.rs b/font/src/ft/list_fonts.rs
index 86ee9708..0fbc7231 100644
--- a/font/src/ft/list_fonts.rs
+++ b/font/src/ft/list_fonts.rs
@@ -20,12 +20,14 @@ mod fc {
use std::ptr;
use std::ffi::{CStr, CString};
use std::str;
- use std::ops::{Deref, DerefMut};
+ use std::ops::Deref;
+
+ use ffi_util::ForeignTypeRef;
use libc::{c_char, c_int};
use fontconfig::fontconfig as ffi;
- use self::ffi::{FcConfigGetCurrent, FcConfigGetFonts};
+ use self::ffi::{FcConfigGetCurrent, FcConfigGetFonts, FcSetSystem, FcSetApplication};
use self::ffi::{FcPatternGetString, FcPatternCreate, FcPatternAddString};
use self::ffi::{FcPatternGetInteger};
use self::ffi::{FcObjectSetCreate, FcObjectSetAdd};
@@ -33,15 +35,6 @@ mod fc {
use self::ffi::{FcChar8, FcConfig, FcPattern, FcFontSet, FcObjectSet};
use self::ffi::{FcFontSetDestroy, FcPatternDestroy, FcObjectSetDestroy, FcConfigDestroy};
- /// FcConfig - Font Configuration
- pub struct Config(*mut FcConfig);
-
- /// FcFontSet
- pub struct FontSet(*mut FcFontSet);
-
- /// FcFontSet reference
- pub struct FontSetRef(*mut FcFontSet);
-
/// Iterator over a font set
pub struct FontSetIter<'a> {
font_set: &'a FontSetRef,
@@ -49,51 +42,10 @@ mod fc {
current: usize,
}
- macro_rules! ref_type {
- ($($owned:ty => $refty:ty),*) => {
- $(
- impl Deref for $owned {
- type Target = $refty;
- fn deref(&self) -> &Self::Target {
- unsafe {
- &*(self.0 as *mut _)
- }
- }
- }
-
- impl DerefMut for $owned {
- fn deref_mut(&mut self) -> &mut Self::Target {
- unsafe {
- &mut *(self.0 as *mut _)
- }
- }
- }
- )*
- }
- }
-
- /// FcPattern
- pub struct Pattern(*mut FcPattern);
-
- /// FcObjectSet
- pub struct ObjectSet(*mut FcObjectSet);
-
- /// FcObjectSet reference
- pub struct ObjectSetRef(*mut FcObjectSet);
-
- ref_type! {
- ObjectSet => ObjectSetRef,
- Pattern => PatternRef,
- FontSet => FontSetRef
- }
-
- impl Drop for ObjectSet {
- fn drop(&mut self) {
- unsafe {
- FcObjectSetDestroy(self.0);
- }
- }
- }
+ ffi_type!(Pattern, PatternRef, FcPattern, FcPatternDestroy);
+ ffi_type!(Config, ConfigRef, FcConfig, FcConfigDestroy);
+ ffi_type!(ObjectSet, ObjectSetRef, FcObjectSet, FcObjectSetDestroy);
+ ffi_type!(FontSet, FontSetRef, FcFontSet, FcFontSetDestroy);
impl ObjectSet {
pub fn new() -> ObjectSet {
@@ -103,11 +55,10 @@ mod fc {
}
}
-
impl ObjectSetRef {
fn add(&mut self, property: &[u8]) {
unsafe {
- FcObjectSetAdd(self.0, property.as_ptr() as *mut c_char);
+ FcObjectSetAdd(self.as_ptr(), property.as_ptr() as *mut c_char);
}
}
@@ -144,21 +95,11 @@ mod fc {
}
}
- impl Drop for Pattern {
- fn drop(&mut self) {
- unsafe {
- FcPatternDestroy(self.0);
- }
- }
- }
-
- /// FcPattern reference
- pub struct PatternRef(*mut FcPattern);
-
/// Available font sets
+ #[derive(Debug, Copy, Clone)]
pub enum SetName {
- System = 0,
- Application = 1,
+ System = FcSetSystem as isize,
+ Application = FcSetApplication as isize,
}
pub unsafe fn char8_to_string(fc_str: *mut FcChar8) -> String {
@@ -173,7 +114,7 @@ mod fc {
let mut format: *mut FcChar8 = ptr::null_mut();
let result = FcPatternGetString(
- self.0,
+ self.as_ptr(),
$property.as_ptr() as *mut c_char,
id as c_int,
&mut format
@@ -197,7 +138,7 @@ mod fc {
let mut index = 0 as c_int;
unsafe {
let result = FcPatternGetInteger(
- self.0,
+ self.as_ptr(),
$property.as_ptr() as *mut c_char,
id as c_int,
&mut index
@@ -228,7 +169,7 @@ mod fc {
let value = value.as_ptr();
FcPatternAddString(
- self.0,
+ self.as_ptr(),
object.as_ptr() as *mut c_char,
value as *mut FcChar8
) == 1
@@ -255,11 +196,11 @@ mod fc {
type IntoIter = FontSetIter<'a>;
fn into_iter(self) -> FontSetIter<'a> {
let num_fonts = unsafe {
- (*self.0).nfont as isize
+ (*self.as_ptr()).nfont as isize
};
FontSetIter {
- font_set: unsafe { &*(self.0 as *mut _) },
+ font_set: self.deref(),
num_fonts: num_fonts as _,
current: 0,
}
@@ -271,7 +212,7 @@ mod fc {
type IntoIter = FontSetIter<'a>;
fn into_iter(self) -> FontSetIter<'a> {
let num_fonts = unsafe {
- (*self.0).nfont as isize
+ (*self.as_ptr()).nfont as isize
};
FontSetIter {
@@ -290,8 +231,8 @@ mod fc {
None
} else {
let pattern = unsafe {
- let ptr = *(*self.font_set.0).fonts.offset(self.current as isize);
- &*(ptr as *mut _)
+ let ptr = *(*self.font_set.as_ptr()).fonts.offset(self.current as isize);
+ PatternRef::from_ptr(ptr)
};
self.current += 1;
@@ -302,18 +243,18 @@ mod fc {
impl FontSet {
pub fn list(
- config: &Config,
+ config: &ConfigRef,
source: &mut FontSetRef,
pattern: &PatternRef,
objects: &ObjectSetRef
) -> FontSet {
let raw = unsafe {
FcFontSetList(
- config.0,
- &mut source.0,
+ config.as_ptr(),
+ &mut source.as_ptr(),
1 /* nsets */,
- pattern.0,
- objects.0
+ pattern.as_ptr(),
+ objects.as_ptr(),
)
};
FontSet(raw)
@@ -322,34 +263,20 @@ mod fc {
impl Config {
/// Get the current configuration
- pub fn get_current() -> Config {
- Config(unsafe { FcConfigGetCurrent() })
- }
-
- /// Returns one of the two sets of fonts from the configuration as
- /// specified by `set`.
- pub fn get_fonts<'a>(&'a self, set: SetName) -> &'a FontSetRef {
- unsafe {
- let ptr = FcConfigGetFonts(self.0, set as u32);
- &*(ptr as *mut _)
- }
- }
- }
-
- impl Drop for FontSet {
- fn drop(&mut self) {
+ pub fn get_current() -> &'static ConfigRef {
unsafe {
- FcFontSetDestroy(self.0)
+ ConfigRef::from_ptr(FcConfigGetCurrent())
}
}
}
- impl Drop for Config {
- fn drop(&mut self) {
+ impl ConfigRef {
+ /// Returns one of the two sets of fonts from the configuration as
+ /// specified by `set`.
+ pub fn get_fonts<'a>(&'a self, set: SetName) -> &'a FontSetRef {
unsafe {
- if self.0 != FcConfigGetCurrent() {
- FcConfigDestroy(self.0)
- }
+ let ptr = FcConfigGetFonts(self.as_ptr(), set as u32);
+ FontSetRef::from_ptr(ptr)
}
}
}
@@ -363,9 +290,11 @@ fn list_families() -> Vec<String> {
for font in font_set {
if let Some(format) = font.fontformat(0) {
if format == "TrueType" || format == "CFF" {
- let id = 0;
- while let Some(family) = font.family(id) {
- families.push(family);
+ for id in 0.. {
+ match font.family(id) {
+ Some(family) => families.push(family),
+ None => break,
+ }
}
}
}
diff --git a/font/src/lib.rs b/font/src/lib.rs
index ca8de0a2..7ec5984c 100644
--- a/font/src/lib.rs
+++ b/font/src/lib.rs
@@ -36,6 +36,9 @@ extern crate core_graphics;
extern crate euclid;
extern crate libc;
+#[macro_use]
+extern crate ffi_util;
+
use std::fmt;
use std::sync::atomic::{AtomicU32, ATOMIC_U32_INIT, Ordering};