summaryrefslogtreecommitdiffstats
path: root/font
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2017-06-28 20:36:01 -0700
committerJoe Wilm <jwilm@users.noreply.github.com>2017-10-08 22:20:58 -0700
commit6c74c51ceff3ec1af0b3973e373aba6e315beffa (patch)
treeae4d738d6896790b5fa0eb7cdc32204afcd02ee4 /font
parent65065e06d19216ed5de9b1db952db76a5457492e (diff)
Extend and improve FcPattern bindings
The fontconfig `FcPattern` type is wrapped as `fc::Pattern` and `fc::Pattern` ref. All methods for accessing data on the pattern now return an `Iterator`. This API turns out to be much more ergonomic than providing an integer index. We also override the default `nth` implementation of `Iterator` on these accessors to allow random (incremental only) access. For instance, accessing `family` attributes from a pattern: let families = pattern.family(); let second = pattern.nth(1); Or printing available styles for style in pattern.style() { println!("style={}", style); }
Diffstat (limited to 'font')
-rw-r--r--font/src/ft/fc/mod.rs195
-rw-r--r--font/src/ft/fc/pattern.rs447
-rw-r--r--font/src/ft/mod.rs8
-rw-r--r--font/src/lib.rs2
4 files changed, 559 insertions, 93 deletions
diff --git a/font/src/ft/fc/mod.rs b/font/src/ft/fc/mod.rs
index d0a55fad..c4cb40eb 100644
--- a/font/src/ft/fc/mod.rs
+++ b/font/src/ft/fc/mod.rs
@@ -13,6 +13,7 @@
// limitations under the License.
//
use std::ptr;
+use std::fmt;
use foreign_types::{ForeignType, ForeignTypeRef};
@@ -27,19 +28,19 @@ use self::ffi::{FC_WEIGHT_THIN, FC_WEIGHT_EXTRALIGHT, FC_WEIGHT_LIGHT};
use self::ffi::{FC_WEIGHT_BOOK, FC_WEIGHT_REGULAR, FC_WEIGHT_MEDIUM, FC_WEIGHT_SEMIBOLD};
use self::ffi::{FC_WEIGHT_BOLD, FC_WEIGHT_EXTRABOLD, FC_WEIGHT_BLACK, FC_WEIGHT_EXTRABLACK};
-mod config;
+pub mod config;
pub use self::config::{Config, ConfigRef};
-mod font_set;
+pub mod font_set;
pub use self::font_set::{FontSet, FontSetRef};
-mod object_set;
+pub mod object_set;
pub use self::object_set::{ObjectSet, ObjectSetRef};
-mod char_set;
+pub mod char_set;
pub use self::char_set::{CharSet, CharSetRef};
-mod pattern;
+pub mod pattern;
pub use self::pattern::{Pattern, PatternRef};
/// Find the font closest matching the provided pattern.
@@ -162,6 +163,143 @@ pub enum Weight {
Extrablack = FC_WEIGHT_EXTRABLACK as isize,
}
+#[derive(Debug, Copy, Clone)]
+pub enum Width {
+ Ultracondensed,
+ Extracondensed,
+ Condensed,
+ Semicondensed,
+ Normal,
+ Semiexpanded,
+ Expanded,
+ Extraexpanded,
+ Ultraexpanded,
+ Other(i32)
+}
+
+impl Width {
+ fn to_isize(&self) -> isize {
+ use self::Width::*;
+ match *self {
+ Ultracondensed => 50,
+ Extracondensed => 63,
+ Condensed => 75,
+ Semicondensed => 87,
+ Normal => 100,
+ Semiexpanded => 113,
+ Expanded => 125,
+ Extraexpanded => 150,
+ Ultraexpanded => 200,
+ Other(value) => value as isize
+ }
+ }
+}
+
+impl From<isize> for Width {
+ fn from(value: isize) -> Self {
+ match value {
+ 50 => Width::Ultracondensed,
+ 63 => Width::Extracondensed,
+ 75 => Width::Condensed,
+ 87 => Width::Semicondensed,
+ 100 => Width::Normal,
+ 113 => Width::Semiexpanded,
+ 125 => Width::Expanded,
+ 150 => Width::Extraexpanded,
+ 200 => Width::Ultraexpanded,
+ _ => Width::Other(value as _)
+ }
+ }
+}
+
+/// Subpixel geometry
+pub enum Rgba {
+ Unknown,
+ Rgb,
+ Bgr,
+ Vrgb,
+ Vbgr,
+ None
+}
+
+impl Rgba {
+ fn to_isize(&self) -> isize {
+ match *self {
+ Rgba::Unknown => 0,
+ Rgba::Rgb => 1,
+ Rgba::Bgr => 2,
+ Rgba::Vrgb => 3,
+ Rgba::Vbgr => 4,
+ Rgba::None => 5
+ }
+ }
+}
+
+impl fmt::Display for Rgba {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use self::Rgba::*;
+ f.write_str(match *self {
+ Unknown => "unknown",
+ Rgb => "rgb",
+ Bgr => "bgr",
+ Vrgb => "vrgb",
+ Vbgr => "vbgr",
+ None => "none",
+ })
+ }
+}
+
+impl From<isize> for Rgba {
+ fn from(val: isize) -> Rgba {
+ match val {
+ 1 => Rgba::Rgb,
+ 2 => Rgba::Bgr,
+ 3 => Rgba::Vrgb,
+ 4 => Rgba::Vbgr,
+ 5 => Rgba::None,
+ _ => Rgba::Unknown,
+ }
+ }
+}
+
+/// Hinting Style
+#[derive(Debug, Copy, Clone)]
+pub enum HintStyle {
+ None,
+ Slight,
+ Medium,
+ Full
+}
+
+impl fmt::Display for HintStyle {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(match *self {
+ HintStyle::None => "none",
+ HintStyle::Slight => "slight",
+ HintStyle::Medium => "medium",
+ HintStyle::Full => "full",
+ })
+ }
+}
+
+/// Lcd filter, used to reduce color fringing with subpixel rendering
+pub enum LcdFilter {
+ None,
+ Default,
+ Light,
+ Legacy
+}
+
+impl fmt::Display for LcdFilter {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(match *self {
+ LcdFilter::None => "none",
+ LcdFilter::Default => "default",
+ LcdFilter::Light => "light",
+ LcdFilter::Legacy => "legacy",
+ })
+ }
+}
#[cfg(test)]
mod tests {
@@ -176,15 +314,17 @@ mod tests {
let config = Config::get_current();
let font = super::font_match(config, &mut pattern).expect("match font monospace");
- print!("family={:?}", font.family(0));
- for i in 0.. {
- if let Some(style) = font.style(i) {
- print!(", style={:?}, ", style);
- } else {
- break;
- }
- }
- info!("");
+ print!("index={:?}; ", font.index());
+ print!("family={:?}; ", font.family());
+ print!("style={:?}; ", font.style());
+ print!("antialias={:?}; ", font.antialias());
+ print!("autohint={:?}; ", font.autohint());
+ print!("hinting={:?}; ", font.hinting());
+ print!("rgba={:?}; ", font.rgba());
+ print!("embeddedbitmap={:?}; ", font.embeddedbitmap());
+ print!("lcdfilter={:?}; ", font.lcdfilter());
+ print!("hintstyle={:?}", font.hintstyle());
+ println!("");
}
#[test]
@@ -198,14 +338,12 @@ mod tests {
.expect("sort font monospace");
for font in fonts.into_iter().take(10) {
- print!("family={:?}", font.family(0));
- for i in 0.. {
- if let Some(style) = font.style(i) {
- print!(", style={:?}", style);
- } else {
- break;
- }
- }
+ let font = font.render_prepare(&config, &pattern);
+ print!("index={:?}; ", font.index());
+ print!("family={:?}; ", font.family());
+ print!("style={:?}; ", font.style());
+ print!("rgba={:?}", font.rgba());
+ print!("rgba={:?}", font.rgba());
println!("");
}
}
@@ -222,14 +360,11 @@ mod tests {
let fonts = super::font_sort(config, &mut pattern).expect("font_sort");
for font in fonts.into_iter().take(10) {
- print!("family={:?}", font.family(0));
- for i in 0.. {
- if let Some(style) = font.style(i) {
- print!(", style={:?}", style);
- } else {
- break;
- }
- }
+ let font = font.render_prepare(&config, &pattern);
+ print!("index={:?}; ", font.index());
+ print!("family={:?}; ", font.family());
+ print!("style={:?}; ", font.style());
+ print!("rgba={:?}", font.rgba());
println!("");
}
}
diff --git a/font/src/ft/fc/pattern.rs b/font/src/ft/fc/pattern.rs
index a7cd9ec7..040fae8f 100644
--- a/font/src/ft/fc/pattern.rs
+++ b/font/src/ft/fc/pattern.rs
@@ -12,20 +12,308 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::ptr;
+use std::fmt;
use std::ffi::{CStr, CString};
use std::path::PathBuf;
use std::str;
+use std::mem;
use libc::{c_char, c_int};
-use foreign_types::{ForeignTypeRef};
+use foreign_types::{ForeignType, ForeignTypeRef};
use super::ffi::FcResultMatch;
use super::ffi::{FcPatternDestroy, FcPatternAddCharSet};
use super::ffi::{FcPatternGetString, FcPatternCreate, FcPatternAddString};
use super::ffi::{FcPatternGetInteger, FcPatternAddInteger};
use super::ffi::{FcChar8, FcPattern, FcDefaultSubstitute, FcConfigSubstitute};
+use super::ffi::{FcFontRenderPrepare, FcPatternGetBool, FcBool};
-use super::{MatchKind, ConfigRef, CharSetRef, Weight, Slant};
+use super::{MatchKind, ConfigRef, CharSetRef, Weight, Slant, Width, Rgba, HintStyle, LcdFilter};
+
+pub struct StringPropertyIter<'a> {
+ pattern: &'a PatternRef,
+ object: &'a [u8],
+ index: usize
+}
+
+impl<'a> StringPropertyIter<'a> {
+ fn new<'b>(pattern: &'b PatternRef, object: &'b [u8]) -> StringPropertyIter<'b> {
+ StringPropertyIter {
+ pattern: pattern,
+ object: object,
+ index: 0
+ }
+ }
+
+ fn get_value(&self, index: usize) -> Option<&'a str> {
+ let mut value: *mut FcChar8 = ptr::null_mut();
+
+ let result = unsafe {
+ FcPatternGetString(
+ self.pattern.as_ptr(),
+ self.object.as_ptr() as *mut c_char,
+ index as c_int,
+ &mut value
+ )
+ };
+
+ if result == FcResultMatch {
+ // Transmute here is to extend lifetime of the str to that of the iterator
+ //
+ // Potential unsafety? What happens if the pattern is modified while this ptr is
+ // borrowed out?
+ Some(unsafe {
+ mem::transmute(CStr::from_ptr(value as *const c_char).to_str().unwrap())
+ })
+ } else {
+ None
+ }
+ }
+}
+
+/// Iterator over interger properties
+pub struct BooleanPropertyIter<'a> {
+ pattern: &'a PatternRef,
+ object: &'a [u8],
+ index: usize
+}
+
+
+impl<'a> BooleanPropertyIter<'a> {
+ fn new<'b>(pattern: &'b PatternRef, object: &'b [u8]) -> BooleanPropertyIter<'b> {
+ BooleanPropertyIter {
+ pattern: pattern,
+ object: object,
+ index: 0
+ }
+ }
+
+ fn get_value(&self, index: usize) -> Option<bool> {
+ let mut value: FcBool = 0;
+
+ let result = unsafe {
+ FcPatternGetBool(
+ self.pattern.as_ptr(),
+ self.object.as_ptr() as *mut c_char,
+ index as c_int,
+ &mut value
+ )
+ };
+
+ if result == FcResultMatch {
+ Some(!(value == 0))
+ } else {
+ None
+ }
+ }
+}
+
+/// Iterator over interger properties
+pub struct IntPropertyIter<'a> {
+ pattern: &'a PatternRef,
+ object: &'a [u8],
+ index: usize
+}
+
+
+impl<'a> IntPropertyIter<'a> {
+ fn new<'b>(pattern: &'b PatternRef, object: &'b [u8]) -> IntPropertyIter<'b> {
+ IntPropertyIter {
+ pattern: pattern,
+ object: object,
+ index: 0
+ }
+ }
+
+ fn get_value(&self, index: usize) -> Option<isize> {
+ let mut value = 0 as c_int;
+
+ let result = unsafe {
+ FcPatternGetInteger(
+ self.pattern.as_ptr(),
+ self.object.as_ptr() as *mut c_char,
+ index as c_int,
+ &mut value
+ )
+ };
+
+ if result == FcResultMatch {
+ Some(value as isize)
+ } else {
+ None
+ }
+ }
+}
+
+pub struct RgbaPropertyIter<'a> {
+ inner: IntPropertyIter<'a>,
+}
+
+impl<'a> RgbaPropertyIter<'a> {
+ fn new<'b>(pattern: &'b PatternRef, object: &'b [u8]) -> RgbaPropertyIter<'b> {
+ RgbaPropertyIter {
+ inner: IntPropertyIter::new(pattern, object)
+ }
+ }
+
+ #[inline]
+ fn inner<'b>(&'b mut self) -> &'b mut IntPropertyIter<'a> {
+ &mut self.inner
+ }
+
+ fn get_value(&self, index: usize) -> Option<Rgba> {
+ self.inner.get_value(index)
+ .map(Rgba::from)
+ }
+}
+
+pub struct HintStylePropertyIter<'a> {
+ inner: IntPropertyIter<'a>,
+}
+
+impl<'a> HintStylePropertyIter<'a> {
+ fn new<'b>(pattern: &'b PatternRef) -> HintStylePropertyIter<'b> {
+ HintStylePropertyIter {
+ inner: IntPropertyIter::new(pattern, b"hintstyle\0")
+ }
+ }
+
+ #[inline]
+ fn inner<'b>(&'b mut self) -> &'b mut IntPropertyIter<'a> {
+ &mut self.inner
+ }
+
+ fn get_value(&self, index: usize) -> Option<HintStyle> {
+ self.inner.get_value(index)
+ .and_then(|hint_style| {
+ Some(match hint_style {
+ 0 => HintStyle::None,
+ 1 => HintStyle::Slight,
+ 2 => HintStyle::Medium,
+ 3 => HintStyle::Full,
+ _ => return None
+ })
+ })
+ }
+}
+
+pub struct LcdFilterPropertyIter<'a> {
+ inner: IntPropertyIter<'a>,
+}
+
+impl<'a> LcdFilterPropertyIter<'a> {
+ fn new<'b>(pattern: &'b PatternRef) -> LcdFilterPropertyIter<'b> {
+ LcdFilterPropertyIter {
+ inner: IntPropertyIter::new(pattern, b"lcdfilter\0")
+ }
+ }
+
+ #[inline]
+ fn inner<'b>(&'b mut self) -> &'b mut IntPropertyIter<'a> {
+ &mut self.inner
+ }
+
+ fn get_value(&self, index: usize) -> Option<LcdFilter> {
+ self.inner.get_value(index)
+ .and_then(|hint_style| {
+ Some(match hint_style {
+ 0 => LcdFilter::None,
+ 1 => LcdFilter::Default,
+ 2 => LcdFilter::Light,
+ 3 => LcdFilter::Legacy,
+ _ => return None
+ })
+ })
+ }
+}
+
+/// Implement debug for a property iterator
+macro_rules! impl_property_iter_debug {
+ ($iter:ty => $item:ty) => {
+ impl<'a> fmt::Debug for $iter {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "[")?;
+ for i in 0.. {
+ match self.get_value(i) {
+ Some(val) => {
+ if i > 0 {
+ write!(f, ", {}", val)?;
+ } else {
+ write!(f, "{}", val)?;
+ }
+ },
+ _ => break
+ }
+ }
+ write!(f, "]")
+ }
+ }
+ }
+}
+
+/// Implement Iterator and Debug for a property iterator
+macro_rules! impl_property_iter {
+ ($($iter:ty => $item:ty),*) => {
+ $(
+ impl<'a> Iterator for $iter {
+ type Item = $item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let res = self.get_value(self.index);
+ self.index += 1;
+ res
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.index += n;
+ self.next()
+ }
+ }
+ impl_property_iter_debug!($iter => $item);
+ )*
+ }
+}
+
+/// Implement Iterator and Debug for a property iterator which internally relies
+/// on another property iterator.
+macro_rules! impl_derived_property_iter {
+ ($($iter:ty => $item:ty),*) => {
+ $(
+ impl<'a> Iterator for $iter {
+ type Item = $item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let index = { self.inner().index };
+ let res = self.get_value(index);
+ self.inner().index += 1;
+ res
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.inner().index += n;
+ self.next()
+ }
+ }
+ impl_property_iter_debug!($iter => $item);
+ )*
+ }
+}
+
+// Basic Iterators
+impl_property_iter! {
+ StringPropertyIter<'a> => &'a str,
+ IntPropertyIter<'a> => isize,
+ BooleanPropertyIter<'a> => bool
+}
+
+// Derived Iterators
+impl_derived_property_iter! {
+ RgbaPropertyIter<'a> => Rgba,
+ HintStylePropertyIter<'a> => HintStyle,
+ LcdFilterPropertyIter<'a> => LcdFilter
+}
foreign_type! {
type CType = FcPattern;
@@ -34,13 +322,20 @@ foreign_type! {
pub struct PatternRef;
}
-macro_rules! pattern_add_string {
- ($($name:ident => $object:expr),*) => {
+macro_rules! pattern_string_accessors {
+ ($([$getter:ident, $setter:ident] => $object_name:expr),*) => {
$(
#[inline]
- pub fn $name(&mut self, value: &str) -> bool {
+ pub fn $setter(&mut self, value: &str) -> bool {
unsafe {
- self.add_string($object, value)
+ self.add_string($object_name, value)
+ }
+ }
+
+ #[inline]
+ pub fn $getter(&self) -> StringPropertyIter {
+ unsafe {
+ self.get_string($object_name)
}
}
)*
@@ -66,18 +361,6 @@ impl Pattern {
}
}
-macro_rules! pattern_get_string {
- ($($method:ident() => $property:expr),+) => {
- $(
- pub fn $method(&self, id: isize) -> Option<String> {
- unsafe {
- self.get_string($property, id)
- }
- }
- )+
- };
-}
-
macro_rules! pattern_add_integer {
($($method:ident() => $property:expr),+) => {
$(
@@ -98,29 +381,25 @@ macro_rules! pattern_add_integer {
macro_rules! pattern_get_integer {
($($method:ident() => $property:expr),+) => {
$(
- pub fn $method(&self, id: isize) -> Option<isize> {
- let mut index = 0 as c_int;
+ pub fn $method(&self) -> IntPropertyIter {
unsafe {
- let result = FcPatternGetInteger(
- self.as_ptr(),
- $property.as_ptr() as *mut c_char,
- id as c_int,
- &mut index
- );
-
- if result == FcResultMatch {
- Some(index as isize)
- } else {
- None
- }
+ self.get_integer($property)
}
}
)+
};
}
-unsafe fn char8_to_string(fc_str: *mut FcChar8) -> String {
- str::from_utf8(CStr::from_ptr(fc_str as *const c_char).to_bytes()).unwrap().to_owned()
+macro_rules! boolean_getter {
+ ($($method:ident() => $property:expr),*) => {
+ $(
+ pub fn $method(&self) -> BooleanPropertyIter {
+ unsafe {
+ self.get_boolean($property)
+ }
+ }
+ )*
+ }
}
impl PatternRef {
@@ -151,26 +430,54 @@ impl PatternRef {
) == 1
}
- unsafe fn get_string(&self, object: &[u8], index: isize) -> Option<String> {
- let mut format: *mut FcChar8 = ptr::null_mut();
+ unsafe fn get_string<'a>(&'a self, object: &'a [u8]) -> StringPropertyIter<'a> {
+ StringPropertyIter::new(self, object)
+ }
- let result = FcPatternGetString(
- self.as_ptr(),
- object.as_ptr() as *mut c_char,
- index as c_int,
- &mut format
- );
+ unsafe fn get_integer<'a>(&'a self, object: &'a [u8]) -> IntPropertyIter<'a> {
+ IntPropertyIter::new(self, object)
+ }
- if result == FcResultMatch {
- Some(char8_to_string(format))
- } else {
- None
- }
+ unsafe fn get_boolean<'a>(&'a self, object: &'a [u8]) -> BooleanPropertyIter<'a> {
+ BooleanPropertyIter::new(self, object)
}
- pattern_add_string! {
- add_family => b"family\0",
- add_style => b"style\0"
+ pub fn hintstyle<'a>(&'a self) -> HintStylePropertyIter<'a> {
+ HintStylePropertyIter::new(self)
+ }
+
+ pub fn lcdfilter<'a>(&'a self) -> LcdFilterPropertyIter<'a> {
+ LcdFilterPropertyIter::new(self)
+ }
+
+ boolean_getter! {
+ antialias() => b"antialias\0",
+ hinting() => b"hinting\0",
+ verticallayout() => b"verticallayout\0",
+ autohint() => b"autohint\0",
+ globaladvance() => b"globaladvance\0",
+ scalable() => b"scalable\0",
+ symbol() => b"symbol\0",
+ color() => b"color\0",
+ minspace() => b"minspace\0",
+ embolden() => b"embolden\0",
+ embeddedbitmap() => b"embeddedbitmap\0",
+ decorative() => b"decorative\0"
+ }
+
+ pattern_string_accessors! {
+ [family, add_family] => b"family\0",
+ [familylang, add_familylang] => b"familylang\0",
+ [style, add_style] => b"style\0",
+ [stylelang, add_stylelang] => b"stylelang\0",
+ [fullname, add_fullname] => b"fullname\0",
+ [fullnamelang, add_fullnamelang] => b"fullnamelang\0",
+ [foundry, add_foundry] => b"foundry\0",
+ [capability, add_capability] => b"capability\0",
+ [fontformat, add_fontformat] => b"fontformat\0",
+ [fontfeatures, add_fontfeatures] => b"fontfeatures\0",
+ [namelang, add_namelang] => b"namelang\0",
+ [postscriptname, add_postscriptname] => b"postscriptname\0"
}
pub fn set_slant(&mut self, slant: Slant) -> bool {
@@ -185,6 +492,36 @@ impl PatternRef {
}
}
+ pub fn set_width(&mut self, width: Width) -> bool {
+ unsafe {
+ self.add_integer(b"width\0", width.to_isize())
+ }
+ }
+
+ pub fn get_width(&self) -> Option<Width> {
+ unsafe {
+ self.get_integer(b"width\0")
+ .nth(0)
+ .map(Width::from)
+ }
+ }
+
+ pub fn rgba(&self) -> RgbaPropertyIter {
+ RgbaPropertyIter::new(self, b"rgba\0")
+ }
+
+ pub fn set_rgba(&self, rgba: Rgba) -> bool {
+ unsafe {
+ self.add_integer(b"rgba\0", rgba.to_isize())
+ }
+ }
+
+ pub fn render_prepare(&self, config: &ConfigRef, request: &PatternRef) -> Pattern {
+ unsafe {
+ let ptr = FcFontRenderPrepare(config.as_ptr(), request.as_ptr(), self.as_ptr());
+ Pattern::from_ptr(ptr)
+ }
+ }
/// Add charset to the pattern
///
@@ -202,18 +539,12 @@ impl PatternRef {
}
}
- pub fn file(&self, index: isize) -> Option<PathBuf> {
+ pub fn file(&self, index: usize) -> Option<PathBuf> {
unsafe {
- self.get_string(b"file\0", index)
+ self.get_string(b"file\0").nth(index)
}.map(From::from)
}
- pattern_get_string! {
- fontformat() => b"fontformat\0",
- family() => b"family\0",
- style() => b"style\0"
- }
-
pattern_get_integer! {
index() => b"index\0"
}
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index 89ca6047..7a75d11f 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -19,7 +19,7 @@ use std::cmp::min;
use freetype::{self, Library, Face};
-mod fc;
+pub mod fc;
use super::{FontDesc, RasterizedGlyph, Metrics, Size, FontKey, GlyphKey, Weight, Slant, Style};
@@ -142,7 +142,7 @@ impl FreeTypeRasterizer {
let font = fc::font_match(fc::Config::get_current(), &mut pattern)
.ok_or_else(|| Error::MissingFont(desc.to_owned()))?;
- if let (Some(path), Some(index)) = (font.file(0), font.index(0)) {
+ if let (Some(path), Some(index)) = (font.file(0), font.index().nth(0)) {
return Ok(self.library.new_face(path, index)?);
}
@@ -160,7 +160,7 @@ impl FreeTypeRasterizer {
let font = fc::font_match(fc::Config::get_current(), &mut pattern)
.ok_or_else(|| Error::MissingFont(desc.to_owned()))?;
- if let (Some(path), Some(index)) = (font.file(0), font.index(0)) {
+ if let (Some(path), Some(index)) = (font.file(0), font.index().nth(0)) {
println!("got font path={:?}", path);
Ok(self.library.new_face(path, index)?)
}
@@ -293,7 +293,7 @@ impl FreeTypeRasterizer {
let config = fc::Config::get_current();
match fc::font_match(config, &mut pattern) {
Some(font) => {
- if let (Some(path), Some(index)) = (font.file(0), font.index(0)) {
+ if let (Some(path), Some(index)) = (font.file(0), font.index().nth(0)) {
match self.keys.get(&path) {
// We've previously loaded this font, so don't
// load it again.
diff --git a/font/src/lib.rs b/font/src/lib.rs
index 401a29c0..f02df436 100644
--- a/font/src/lib.rs
+++ b/font/src/lib.rs
@@ -48,7 +48,7 @@ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
// If target isn't macos, reexport everything from ft
#[cfg(not(target_os = "macos"))]
-mod ft;
+pub mod ft;
#[cfg(not(target_os = "macos"))]
pub use ft::{FreeTypeRasterizer as Rasterizer, Error};