mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-18 13:55:23 -05:00
Add ffi-util crate and use in fontconfig wrapper
This cleans up and fixes the C-type wrapping for fontconfig.
This commit is contained in:
parent
44c6171bc0
commit
a00970c9a8
7 changed files with 160 additions and 109 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -230,6 +230,10 @@ dependencies = [
|
||||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffi-util"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -247,6 +251,7 @@ dependencies = [
|
||||||
"core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
|
||||||
|
|
6
ffi-util/Cargo.toml
Normal file
6
ffi-util/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "ffi-util"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Joe Wilm <joe@jwilm.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
102
ffi-util/src/lib.rs
Normal file
102
ffi-util/src/lib.rs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
font/Cargo.lock
generated
5
font/Cargo.lock
generated
|
@ -7,6 +7,7 @@ dependencies = [
|
||||||
"core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
|
||||||
|
@ -75,6 +76,10 @@ dependencies = [
|
||||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffi-util"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "freetype-rs"
|
name = "freetype-rs"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
|
@ -8,6 +8,7 @@ license = "Apache-2.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
euclid = "0.6.8"
|
euclid = "0.6.8"
|
||||||
libc = "0.2.11"
|
libc = "0.2.11"
|
||||||
|
ffi-util = { path = "../ffi-util" }
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "macos"))'.dependencies]
|
[target.'cfg(not(target_os = "macos"))'.dependencies]
|
||||||
servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig" }
|
servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig" }
|
||||||
|
|
|
@ -20,12 +20,14 @@ mod fc {
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use ffi_util::ForeignTypeRef;
|
||||||
|
|
||||||
use libc::{c_char, c_int};
|
use libc::{c_char, c_int};
|
||||||
use fontconfig::fontconfig as ffi;
|
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::{FcPatternGetString, FcPatternCreate, FcPatternAddString};
|
||||||
use self::ffi::{FcPatternGetInteger};
|
use self::ffi::{FcPatternGetInteger};
|
||||||
use self::ffi::{FcObjectSetCreate, FcObjectSetAdd};
|
use self::ffi::{FcObjectSetCreate, FcObjectSetAdd};
|
||||||
|
@ -33,15 +35,6 @@ mod fc {
|
||||||
use self::ffi::{FcChar8, FcConfig, FcPattern, FcFontSet, FcObjectSet};
|
use self::ffi::{FcChar8, FcConfig, FcPattern, FcFontSet, FcObjectSet};
|
||||||
use self::ffi::{FcFontSetDestroy, FcPatternDestroy, FcObjectSetDestroy, FcConfigDestroy};
|
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
|
/// Iterator over a font set
|
||||||
pub struct FontSetIter<'a> {
|
pub struct FontSetIter<'a> {
|
||||||
font_set: &'a FontSetRef,
|
font_set: &'a FontSetRef,
|
||||||
|
@ -49,51 +42,10 @@ mod fc {
|
||||||
current: usize,
|
current: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! ref_type {
|
ffi_type!(Pattern, PatternRef, FcPattern, FcPatternDestroy);
|
||||||
($($owned:ty => $refty:ty),*) => {
|
ffi_type!(Config, ConfigRef, FcConfig, FcConfigDestroy);
|
||||||
$(
|
ffi_type!(ObjectSet, ObjectSetRef, FcObjectSet, FcObjectSetDestroy);
|
||||||
impl Deref for $owned {
|
ffi_type!(FontSet, FontSetRef, FcFontSet, FcFontSetDestroy);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectSet {
|
impl ObjectSet {
|
||||||
pub fn new() -> ObjectSet {
|
pub fn new() -> ObjectSet {
|
||||||
|
@ -103,11 +55,10 @@ mod fc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ObjectSetRef {
|
impl ObjectSetRef {
|
||||||
fn add(&mut self, property: &[u8]) {
|
fn add(&mut self, property: &[u8]) {
|
||||||
unsafe {
|
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
|
/// Available font sets
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum SetName {
|
pub enum SetName {
|
||||||
System = 0,
|
System = FcSetSystem as isize,
|
||||||
Application = 1,
|
Application = FcSetApplication as isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn char8_to_string(fc_str: *mut FcChar8) -> String {
|
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 mut format: *mut FcChar8 = ptr::null_mut();
|
||||||
|
|
||||||
let result = FcPatternGetString(
|
let result = FcPatternGetString(
|
||||||
self.0,
|
self.as_ptr(),
|
||||||
$property.as_ptr() as *mut c_char,
|
$property.as_ptr() as *mut c_char,
|
||||||
id as c_int,
|
id as c_int,
|
||||||
&mut format
|
&mut format
|
||||||
|
@ -197,7 +138,7 @@ mod fc {
|
||||||
let mut index = 0 as c_int;
|
let mut index = 0 as c_int;
|
||||||
unsafe {
|
unsafe {
|
||||||
let result = FcPatternGetInteger(
|
let result = FcPatternGetInteger(
|
||||||
self.0,
|
self.as_ptr(),
|
||||||
$property.as_ptr() as *mut c_char,
|
$property.as_ptr() as *mut c_char,
|
||||||
id as c_int,
|
id as c_int,
|
||||||
&mut index
|
&mut index
|
||||||
|
@ -228,7 +169,7 @@ mod fc {
|
||||||
let value = value.as_ptr();
|
let value = value.as_ptr();
|
||||||
|
|
||||||
FcPatternAddString(
|
FcPatternAddString(
|
||||||
self.0,
|
self.as_ptr(),
|
||||||
object.as_ptr() as *mut c_char,
|
object.as_ptr() as *mut c_char,
|
||||||
value as *mut FcChar8
|
value as *mut FcChar8
|
||||||
) == 1
|
) == 1
|
||||||
|
@ -255,11 +196,11 @@ mod fc {
|
||||||
type IntoIter = FontSetIter<'a>;
|
type IntoIter = FontSetIter<'a>;
|
||||||
fn into_iter(self) -> FontSetIter<'a> {
|
fn into_iter(self) -> FontSetIter<'a> {
|
||||||
let num_fonts = unsafe {
|
let num_fonts = unsafe {
|
||||||
(*self.0).nfont as isize
|
(*self.as_ptr()).nfont as isize
|
||||||
};
|
};
|
||||||
|
|
||||||
FontSetIter {
|
FontSetIter {
|
||||||
font_set: unsafe { &*(self.0 as *mut _) },
|
font_set: self.deref(),
|
||||||
num_fonts: num_fonts as _,
|
num_fonts: num_fonts as _,
|
||||||
current: 0,
|
current: 0,
|
||||||
}
|
}
|
||||||
|
@ -271,7 +212,7 @@ mod fc {
|
||||||
type IntoIter = FontSetIter<'a>;
|
type IntoIter = FontSetIter<'a>;
|
||||||
fn into_iter(self) -> FontSetIter<'a> {
|
fn into_iter(self) -> FontSetIter<'a> {
|
||||||
let num_fonts = unsafe {
|
let num_fonts = unsafe {
|
||||||
(*self.0).nfont as isize
|
(*self.as_ptr()).nfont as isize
|
||||||
};
|
};
|
||||||
|
|
||||||
FontSetIter {
|
FontSetIter {
|
||||||
|
@ -290,8 +231,8 @@ mod fc {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let pattern = unsafe {
|
let pattern = unsafe {
|
||||||
let ptr = *(*self.font_set.0).fonts.offset(self.current as isize);
|
let ptr = *(*self.font_set.as_ptr()).fonts.offset(self.current as isize);
|
||||||
&*(ptr as *mut _)
|
PatternRef::from_ptr(ptr)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.current += 1;
|
self.current += 1;
|
||||||
|
@ -302,18 +243,18 @@ mod fc {
|
||||||
|
|
||||||
impl FontSet {
|
impl FontSet {
|
||||||
pub fn list(
|
pub fn list(
|
||||||
config: &Config,
|
config: &ConfigRef,
|
||||||
source: &mut FontSetRef,
|
source: &mut FontSetRef,
|
||||||
pattern: &PatternRef,
|
pattern: &PatternRef,
|
||||||
objects: &ObjectSetRef
|
objects: &ObjectSetRef
|
||||||
) -> FontSet {
|
) -> FontSet {
|
||||||
let raw = unsafe {
|
let raw = unsafe {
|
||||||
FcFontSetList(
|
FcFontSetList(
|
||||||
config.0,
|
config.as_ptr(),
|
||||||
&mut source.0,
|
&mut source.as_ptr(),
|
||||||
1 /* nsets */,
|
1 /* nsets */,
|
||||||
pattern.0,
|
pattern.as_ptr(),
|
||||||
objects.0
|
objects.as_ptr(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
FontSet(raw)
|
FontSet(raw)
|
||||||
|
@ -322,34 +263,20 @@ mod fc {
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Get the current configuration
|
/// Get the current configuration
|
||||||
pub fn get_current() -> Config {
|
pub fn get_current() -> &'static ConfigRef {
|
||||||
Config(unsafe { FcConfigGetCurrent() })
|
unsafe {
|
||||||
|
ConfigRef::from_ptr(FcConfigGetCurrent())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ConfigRef {
|
||||||
/// Returns one of the two sets of fonts from the configuration as
|
/// Returns one of the two sets of fonts from the configuration as
|
||||||
/// specified by `set`.
|
/// specified by `set`.
|
||||||
pub fn get_fonts<'a>(&'a self, set: SetName) -> &'a FontSetRef {
|
pub fn get_fonts<'a>(&'a self, set: SetName) -> &'a FontSetRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = FcConfigGetFonts(self.0, set as u32);
|
let ptr = FcConfigGetFonts(self.as_ptr(), set as u32);
|
||||||
&*(ptr as *mut _)
|
FontSetRef::from_ptr(ptr)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for FontSet {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
FcFontSetDestroy(self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Config {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
if self.0 != FcConfigGetCurrent() {
|
|
||||||
FcConfigDestroy(self.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,9 +290,11 @@ fn list_families() -> Vec<String> {
|
||||||
for font in font_set {
|
for font in font_set {
|
||||||
if let Some(format) = font.fontformat(0) {
|
if let Some(format) = font.fontformat(0) {
|
||||||
if format == "TrueType" || format == "CFF" {
|
if format == "TrueType" || format == "CFF" {
|
||||||
let id = 0;
|
for id in 0.. {
|
||||||
while let Some(family) = font.family(id) {
|
match font.family(id) {
|
||||||
families.push(family);
|
Some(family) => families.push(family),
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,9 @@ extern crate core_graphics;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate ffi_util;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::atomic::{AtomicU32, ATOMIC_U32_INIT, Ordering};
|
use std::sync::atomic::{AtomicU32, ATOMIC_U32_INIT, Ordering};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue