summaryrefslogtreecommitdiff
path: root/font/src/ft/fc
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-07-19 20:35:15 +0000
committerGitHub <noreply@github.com>2020-07-19 20:35:15 +0000
commit714bbb769ec1ff4a32e594aa6d67d13b98814caa (patch)
tree453e5dc8b23b209f8bbac5a288d0b8584aaa8ffc /font/src/ft/fc
parentfa79758f5645bff66f8d12797832fa2b57157975 (diff)
downloadalacritty-714bbb769ec1ff4a32e594aa6d67d13b98814caa.tar.gz
alacritty-714bbb769ec1ff4a32e594aa6d67d13b98814caa.zip
Bump version to 0.5.0-rc2v0.5.0-rc2
Diffstat (limited to 'font/src/ft/fc')
-rw-r--r--font/src/ft/fc/char_set.rs70
-rw-r--r--font/src/ft/fc/config.rs29
-rw-r--r--font/src/ft/fc/font_set.rs87
-rw-r--r--font/src/ft/fc/mod.rs337
-rw-r--r--font/src/ft/fc/object_set.rs48
-rw-r--r--font/src/ft/fc/pattern.rs627
6 files changed, 0 insertions, 1198 deletions
diff --git a/font/src/ft/fc/char_set.rs b/font/src/ft/fc/char_set.rs
deleted file mode 100644
index 9579b7b9..00000000
--- a/font/src/ft/fc/char_set.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use std::ptr::NonNull;
-
-use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
-
-use super::ffi::FcCharSetCreate;
-use super::ffi::{
- FcBool, FcCharSet, FcCharSetAddChar, FcCharSetCopy, FcCharSetCount, FcCharSetDestroy,
- FcCharSetHasChar, FcCharSetMerge, FcCharSetSubtract, FcCharSetUnion,
-};
-
-foreign_type! {
- pub unsafe type CharSet {
- type CType = FcCharSet;
- fn drop = FcCharSetDestroy;
- fn clone = FcCharSetCopy;
- }
-}
-
-impl CharSet {
- pub fn new() -> Self {
- Self::default()
- }
-}
-
-impl Default for CharSet {
- fn default() -> Self {
- CharSet(unsafe { NonNull::new(FcCharSetCreate()).unwrap() })
- }
-}
-
-impl CharSetRef {
- pub fn add(&mut self, glyph: char) -> bool {
- unsafe { FcCharSetAddChar(self.as_ptr(), glyph as _) == 1 }
- }
-
- pub fn has_char(&self, glyph: char) -> bool {
- unsafe { FcCharSetHasChar(self.as_ptr(), glyph as _) == 1 }
- }
-
- pub fn count(&self) -> u32 {
- unsafe { FcCharSetCount(self.as_ptr()) as u32 }
- }
-
- pub fn union(&self, other: &CharSetRef) -> CharSet {
- unsafe {
- let ptr = FcCharSetUnion(self.as_ptr() as _, other.as_ptr() as _);
- CharSet::from_ptr(ptr)
- }
- }
-
- pub fn subtract(&self, other: &CharSetRef) -> CharSet {
- unsafe {
- let ptr = FcCharSetSubtract(self.as_ptr() as _, other.as_ptr() as _);
- CharSet::from_ptr(ptr)
- }
- }
-
- pub fn merge(&self, other: &CharSetRef) -> Result<bool, ()> {
- unsafe {
- // Value is just an indicator whether something was added or not.
- let mut value: FcBool = 0;
- let res = FcCharSetMerge(self.as_ptr() as _, other.as_ptr() as _, &mut value);
- if res == 0 {
- Err(())
- } else {
- Ok(value != 0)
- }
- }
- }
-}
diff --git a/font/src/ft/fc/config.rs b/font/src/ft/fc/config.rs
deleted file mode 100644
index ac87a284..00000000
--- a/font/src/ft/fc/config.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use foreign_types::{foreign_type, ForeignTypeRef};
-
-use super::ffi::{FcConfig, FcConfigDestroy, FcConfigGetCurrent, FcConfigGetFonts};
-use super::{FontSetRef, SetName};
-
-foreign_type! {
- pub unsafe type Config {
- type CType = FcConfig;
- fn drop = FcConfigDestroy;
- }
-}
-
-impl Config {
- /// Get the current configuration.
- pub fn get_current() -> &'static ConfigRef {
- unsafe { ConfigRef::from_ptr(FcConfigGetCurrent()) }
- }
-}
-
-impl ConfigRef {
- /// Returns one of the two sets of fonts from the configuration as
- /// specified by `set`.
- pub fn get_fonts(&self, set: SetName) -> &FontSetRef {
- unsafe {
- let ptr = FcConfigGetFonts(self.as_ptr(), set as u32);
- FontSetRef::from_ptr(ptr)
- }
- }
-}
diff --git a/font/src/ft/fc/font_set.rs b/font/src/ft/fc/font_set.rs
deleted file mode 100644
index 2f003312..00000000
--- a/font/src/ft/fc/font_set.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-use std::ops::Deref;
-use std::ptr::NonNull;
-
-use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
-use log::trace;
-
-use super::{ConfigRef, ObjectSetRef, PatternRef};
-
-use super::ffi::{FcFontSet, FcFontSetDestroy, FcFontSetList};
-
-foreign_type! {
- pub unsafe type FontSet {
- type CType = FcFontSet;
- fn drop = FcFontSetDestroy;
- }
-}
-
-impl FontSet {
- pub fn list(
- config: &ConfigRef,
- source: &mut FontSetRef,
- pattern: &PatternRef,
- objects: &ObjectSetRef,
- ) -> FontSet {
- let raw = unsafe {
- FcFontSetList(
- config.as_ptr(),
- &mut source.as_ptr(),
- 1, // nsets.
- pattern.as_ptr(),
- objects.as_ptr(),
- )
- };
- FontSet(NonNull::new(raw).unwrap())
- }
-}
-
-/// Iterator over a font set.
-pub struct Iter<'a> {
- font_set: &'a FontSetRef,
- num_fonts: usize,
- current: usize,
-}
-
-impl<'a> IntoIterator for &'a FontSet {
- type IntoIter = Iter<'a>;
- type Item = &'a PatternRef;
-
- fn into_iter(self) -> Iter<'a> {
- let num_fonts = unsafe { (*self.as_ptr()).nfont as isize };
-
- trace!("Number of fonts is {}", num_fonts);
-
- Iter { font_set: self.deref(), num_fonts: num_fonts as _, current: 0 }
- }
-}
-
-impl<'a> IntoIterator for &'a FontSetRef {
- type IntoIter = Iter<'a>;
- type Item = &'a PatternRef;
-
- fn into_iter(self) -> Iter<'a> {
- let num_fonts = unsafe { (*self.as_ptr()).nfont as isize };
-
- trace!("Number of fonts is {}", num_fonts);
-
- Iter { font_set: self, num_fonts: num_fonts as _, current: 0 }
- }
-}
-
-impl<'a> Iterator for Iter<'a> {
- type Item = &'a PatternRef;
-
- fn next(&mut self) -> Option<Self::Item> {
- if self.current == self.num_fonts {
- None
- } else {
- let pattern = unsafe {
- let ptr = *(*self.font_set.as_ptr()).fonts.add(self.current);
- PatternRef::from_ptr(ptr)
- };
-
- self.current += 1;
- Some(pattern)
- }
- }
-}
diff --git a/font/src/ft/fc/mod.rs b/font/src/ft/fc/mod.rs
deleted file mode 100644
index 1058bea3..00000000
--- a/font/src/ft/fc/mod.rs
+++ /dev/null
@@ -1,337 +0,0 @@
-use std::fmt;
-use std::ptr;
-
-use foreign_types::{ForeignType, ForeignTypeRef};
-
-use fontconfig::fontconfig as ffi;
-
-use ffi::FcResultNoMatch;
-use ffi::{FcFontList, FcFontMatch, FcFontSort};
-use ffi::{FcMatchFont, FcMatchPattern, FcMatchScan};
-use ffi::{FcSetApplication, FcSetSystem};
-use ffi::{FC_SLANT_ITALIC, FC_SLANT_OBLIQUE, FC_SLANT_ROMAN};
-use ffi::{FC_WEIGHT_BLACK, FC_WEIGHT_BOLD, FC_WEIGHT_EXTRABLACK, FC_WEIGHT_EXTRABOLD};
-use ffi::{FC_WEIGHT_BOOK, FC_WEIGHT_MEDIUM, FC_WEIGHT_REGULAR, FC_WEIGHT_SEMIBOLD};
-use ffi::{FC_WEIGHT_EXTRALIGHT, FC_WEIGHT_LIGHT, FC_WEIGHT_THIN};
-
-pub mod config;
-pub use config::{Config, ConfigRef};
-
-pub mod font_set;
-pub use font_set::{FontSet, FontSetRef};
-
-pub mod object_set;
-pub use object_set::{ObjectSet, ObjectSetRef};
-
-pub mod char_set;
-pub use char_set::{CharSet, CharSetRef};
-
-pub mod pattern;
-pub use pattern::{FTFaceLocation, Pattern, PatternHash, PatternRef};
-
-/// Find the font closest matching the provided pattern.
-///
-/// The returned pattern is the result of Pattern::render_prepare.
-pub fn font_match(config: &ConfigRef, pattern: &PatternRef) -> Option<Pattern> {
- unsafe {
- // What is this result actually used for? Seems redundant with
- // return type.
- let mut result = FcResultNoMatch;
- let ptr = FcFontMatch(config.as_ptr(), pattern.as_ptr(), &mut result);
-
- if ptr.is_null() {
- None
- } else {
- Some(Pattern::from_ptr(ptr))
- }
- }
-}
-
-/// List fonts by closeness to the pattern.
-pub fn font_sort(config: &ConfigRef, pattern: &PatternRef) -> Option<FontSet> {
- unsafe {
- // What is this result actually used for? Seems redundant with
- // return type.
- let mut result = FcResultNoMatch;
-
- let mut charsets: *mut _ = ptr::null_mut();
- let ptr = FcFontSort(
- config.as_ptr(),
- pattern.as_ptr(),
- 1, // Trim font list.
- &mut charsets,
- &mut result,
- );
-
- if ptr.is_null() {
- None
- } else {
- Some(FontSet::from_ptr(ptr))
- }
- }
-}
-
-/// List fonts matching pattern.
-pub fn font_list(
- config: &ConfigRef,
- pattern: &PatternRef,
- objects: &ObjectSetRef,
-) -> Option<FontSet> {
- unsafe {
- let ptr = FcFontList(config.as_ptr(), pattern.as_ptr(), objects.as_ptr());
-
- if ptr.is_null() {
- None
- } else {
- Some(FontSet::from_ptr(ptr))
- }
- }
-}
-
-/// Available font sets.
-#[derive(Debug, Copy, Clone)]
-pub enum SetName {
- System = FcSetSystem as isize,
- Application = FcSetApplication as isize,
-}
-
-/// When matching, how to match.
-#[derive(Debug, Copy, Clone)]
-pub enum MatchKind {
- Font = FcMatchFont as isize,
- Pattern = FcMatchPattern as isize,
- Scan = FcMatchScan as isize,
-}
-
-#[derive(Debug, Copy, Clone)]
-pub enum Slant {
- Italic = FC_SLANT_ITALIC as isize,
- Oblique = FC_SLANT_OBLIQUE as isize,
- Roman = FC_SLANT_ROMAN as isize,
-}
-
-#[derive(Debug, Copy, Clone)]
-pub enum Weight {
- Thin = FC_WEIGHT_THIN as isize,
- Extralight = FC_WEIGHT_EXTRALIGHT as isize,
- Light = FC_WEIGHT_LIGHT as isize,
- Book = FC_WEIGHT_BOOK as isize,
- Regular = FC_WEIGHT_REGULAR as isize,
- Medium = FC_WEIGHT_MEDIUM as isize,
- Semibold = FC_WEIGHT_SEMIBOLD as isize,
- Bold = FC_WEIGHT_BOLD as isize,
- Extrabold = FC_WEIGHT_EXTRABOLD as isize,
- Black = FC_WEIGHT_BLACK as isize,
- 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 {
- match self {
- Width::Ultracondensed => 50,
- Width::Extracondensed => 63,
- Width::Condensed => 75,
- Width::Semicondensed => 87,
- Width::Normal => 100,
- Width::Semiexpanded => 113,
- Width::Expanded => 125,
- Width::Extraexpanded => 150,
- Width::Ultraexpanded => 200,
- Width::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.
-#[derive(Debug)]
-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 {
- f.write_str(match *self {
- Rgba::Unknown => "unknown",
- Rgba::Rgb => "rgb",
- Rgba::Bgr => "bgr",
- Rgba::Vrgb => "vrgb",
- Rgba::Vbgr => "vbgr",
- Rgba::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 {
- use super::*;
-
- #[test]
- fn font_match() {
- let mut pattern = Pattern::new();
- pattern.add_family("monospace");
- pattern.add_style("regular");
-
- let config = Config::get_current();
- pattern.config_substitute(config, MatchKind::Pattern);
- pattern.default_substitute();
- let font = super::font_match(config, &pattern).expect("match font monospace");
-
- 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]
- fn font_sort() {
- let mut pattern = Pattern::new();
- pattern.add_family("monospace");
- pattern.set_slant(Slant::Italic);
-
- let config = Config::get_current();
- pattern.config_substitute(config, MatchKind::Pattern);
- pattern.default_substitute();
- let fonts = super::font_sort(config, &pattern).expect("sort font monospace");
-
- for font in fonts.into_iter().take(10) {
- let font = pattern.render_prepare(&config, &font);
- print!("index={:?}; ", font.index());
- print!("family={:?}; ", font.family());
- print!("style={:?}; ", font.style());
- print!("rgba={:?}", font.rgba());
- print!("rgba={:?}", font.rgba());
- println!();
- }
- }
-
- #[test]
- fn font_sort_with_glyph() {
- let mut charset = CharSet::new();
- charset.add('💖');
- let mut pattern = Pattern::new();
- pattern.add_charset(&charset);
- drop(charset);
-
- let config = Config::get_current();
- pattern.config_substitute(config, MatchKind::Pattern);
- pattern.default_substitute();
- let fonts = super::font_sort(config, &pattern).expect("font_sort");
-
- for font in fonts.into_iter().take(10) {
- let font = pattern.render_prepare(&config, &font);
- print!("index={:?}; ", font.index());
- print!("family={:?}; ", font.family());
- print!("style={:?}; ", font.style());
- print!("rgba={:?}", font.rgba());
- println!();
- }
- }
-}
diff --git a/font/src/ft/fc/object_set.rs b/font/src/ft/fc/object_set.rs
deleted file mode 100644
index 74faabbf..00000000
--- a/font/src/ft/fc/object_set.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use std::ptr::NonNull;
-
-use libc::c_char;
-
-use super::ffi::{FcObjectSet, FcObjectSetAdd, FcObjectSetCreate, FcObjectSetDestroy};
-use foreign_types::{foreign_type, ForeignTypeRef};
-
-foreign_type! {
- pub unsafe type ObjectSet {
- type CType = FcObjectSet;
- fn drop = FcObjectSetDestroy;
- }
-}
-
-impl ObjectSet {
- pub fn new() -> Self {
- Self::default()
- }
-}
-
-impl Default for ObjectSet {
- fn default() -> Self {
- ObjectSet(unsafe { NonNull::new(FcObjectSetCreate()).unwrap() })
- }
-}
-
-impl ObjectSetRef {
- fn add(&mut self, property: &[u8]) {
- unsafe {
- FcObjectSetAdd(self.as_ptr(), property.as_ptr() as *mut c_char);
- }
- }
-
- #[inline]
- pub fn add_file(&mut self) {
- self.add(b"file\0");
- }
-
- #[inline]
- pub fn add_index(&mut self) {
- self.add(b"index\0");
- }
-
- #[inline]
- pub fn add_style(&mut self) {
- self.add(b"style\0");
- }
-}
diff --git a/font/src/ft/fc/pattern.rs b/font/src/ft/fc/pattern.rs
deleted file mode 100644
index 19d72b47..00000000
--- a/font/src/ft/fc/pattern.rs
+++ /dev/null
@@ -1,627 +0,0 @@
-use std::ffi::{CStr, CString};
-use std::fmt;
-use std::mem;
-use std::path::PathBuf;
-use std::ptr::{self, NonNull};
-use std::str;
-
-use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
-use libc::{c_char, c_double, c_int};
-
-use super::ffi::FcMatrix;
-use super::ffi::FcResultMatch;
-use super::ffi::{FcBool, FcFontRenderPrepare, FcPatternGetBool, FcPatternGetDouble};
-use super::ffi::{FcChar8, FcConfigSubstitute, FcDefaultSubstitute, FcPattern, FcPatternHash};
-use super::ffi::{
- FcPatternAddCharSet, FcPatternDestroy, FcPatternDuplicate, FcPatternGetCharSet,
- FcPatternGetMatrix,
-};
-use super::ffi::{FcPatternAddDouble, FcPatternAddString, FcPatternCreate, FcPatternGetString};
-use super::ffi::{FcPatternAddInteger, FcPatternGetInteger, FcPatternPrint};
-
-use super::{CharSetRef, ConfigRef, HintStyle, LcdFilter, MatchKind, Rgba, Slant, Weight, Width};
-
-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, 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 integer 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, 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 integer 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, 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(pattern: &PatternRef) -> HintStylePropertyIter {
- 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(pattern: &PatternRef) -> LcdFilterPropertyIter {
- 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,
- })
- })
- }
-}
-
-/// Iterator over integer properties.
-pub struct DoublePropertyIter<'a> {
- pattern: &'a PatternRef,
- object: &'a [u8],
- index: usize,
-}
-
-impl<'a> DoublePropertyIter<'a> {
- fn new<'b>(pattern: &'b PatternRef, object: &'b [u8]) -> DoublePropertyIter<'b> {
- DoublePropertyIter { pattern, object, index: 0 }
- }
-
- fn get_value(&self, index: usize) -> Option<f64> {
- let mut value = f64::from(0);
-
- let result = unsafe {
- FcPatternGetDouble(
- self.pattern.as_ptr(),
- self.object.as_ptr() as *mut c_char,
- index as c_int,
- &mut value,
- )
- };
-
- if result == FcResultMatch {
- Some(value as f64)
- } else {
- 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,
- DoublePropertyIter<'a> => f64,
- BooleanPropertyIter<'a> => bool
-}
-
-// Derived Iterators.
-impl_derived_property_iter! {
- RgbaPropertyIter<'a> => Rgba,
- HintStylePropertyIter<'a> => HintStyle,
- LcdFilterPropertyIter<'a> => LcdFilter
-}
-
-foreign_type! {
- pub unsafe type Pattern {
- type CType = FcPattern;
- fn drop = FcPatternDestroy;
- fn clone = FcPatternDuplicate;
- }
-}
-
-macro_rules! string_accessor {
- ($([$getter:ident, $setter:ident] => $object_name:expr),*) => {
- $(
- #[inline]
- pub fn $setter(&mut self, value: &str) -> bool {
- unsafe {
- self.add_string($object_name, value)
- }
- }
-
- #[inline]
- pub fn $getter(&self) -> StringPropertyIter {
- unsafe {
- self.get_string($object_name)
- }
- }
- )*
- }
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub struct PatternHash(pub u32);
-
-#[derive(Hash, Eq, PartialEq, Debug)]
-pub struct FTFaceLocation {
- pub path: PathBuf,
- pub index: isize,
-}
-
-impl FTFaceLocation {
- pub fn new(path: PathBuf, index: isize) -> Self {
- Self { path, index }
- }
-}
-
-impl Pattern {
- pub fn new() -> Self {
- Self::default()
- }
-}
-
-impl Default for Pattern {
- fn default() -> Self {
- Pattern(unsafe { NonNull::new(FcPatternCreate()).unwrap() })
- }
-}
-
-macro_rules! pattern_get_integer {
- ($($method:ident() => $property:expr),+) => {
- $(
- pub fn $method(&self) -> IntPropertyIter {
- unsafe {
- self.get_integer($property)
- }
- }
- )+
- };
-}
-
-macro_rules! boolean_getter {
- ($($method:ident() => $property:expr),*) => {
- $(
- pub fn $method(&self) -> BooleanPropertyIter {
- unsafe {
- self.get_boolean($property)
- }
- }
- )*
- }
-}
-
-macro_rules! double_getter {
- ($($method:ident() => $property:expr),*) => {
- $(
- pub fn $method(&self) -> DoublePropertyIter {
- unsafe {
- self.get_double($property)
- }
- }
- )*
- }
-}
-
-impl PatternRef {
- 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"
- }
-
- double_getter! {
- size() => b"size\0",
- aspect() => b"aspect\0",
- pixelsize() => b"pixelsize\0",
- pixelsizefixupfactor() => b"pixelsizefixupfactor\0",
- scale() => b"scale\0",
- dpi() => b"dpi\0"
- }
-
- string_accessor! {
- [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"
- }
-
- pattern_get_integer! {
- index() => b"index\0"
- }
-
- /// Prints the pattern to stdout.
- ///
- /// FontConfig doesn't expose a way to iterate over all members of a pattern;
- /// instead, we just defer to FcPatternPrint. Otherwise, this could have been
- /// a `fmt::Debug` impl.
- pub fn print(&self) {
- unsafe { FcPatternPrint(self.as_ptr()) }
- }
-
- /// Add a string value to the pattern.
- ///
- /// If the returned value is `true`, the value is added at the end of
- /// any existing list, otherwise it is inserted at the beginning.
- ///
- /// # Unsafety
- ///
- /// `object` is not checked to be a valid null-terminated string.
- unsafe fn add_string(&mut self, object: &[u8], value: &str) -> bool {
- let value = CString::new(&value[..]).unwrap();
- let value = value.as_ptr();
-
- FcPatternAddString(self.as_ptr(), object.as_ptr() as *mut c_char, value as *mut FcChar8)
- == 1
- }
-
- unsafe fn add_integer(&self, object: &[u8], int: isize) -> bool {
- FcPatternAddInteger(self.as_ptr(), object.as_ptr() as *mut c_char, int as c_int) == 1
- }
-
- unsafe fn add_double(&self, object: &[u8], value: f64) -> bool {
- FcPatternAddDouble(self.as_ptr(), object.as_ptr() as *mut c_char, value as c_double) == 1
- }
-
- unsafe fn get_string<'a>(&'a self, object: &'a [u8]) -> StringPropertyIter<'a> {
- StringPropertyIter::new(self, object)
- }
-
- unsafe fn get_integer<'a>(&'a self, object: &'a [u8]) -> IntPropertyIter<'a> {
- IntPropertyIter::new(self, object)
- }
-
- unsafe fn get_double<'a>(&'a self, object: &'a [u8]) -> DoublePropertyIter<'a> {
- DoublePropertyIter::new(self, object)
- }
-
- unsafe fn get_boolean<'a>(&'a self, object: &'a [u8]) -> BooleanPropertyIter<'a> {
- BooleanPropertyIter::new(self, object)
- }
-
- pub fn hintstyle(&self) -> HintStylePropertyIter {
- HintStylePropertyIter::new(self)
- }
-
- pub fn lcdfilter(&self) -> LcdFilterPropertyIter {
- LcdFilterPropertyIter::new(self)
- }
-
- pub fn set_slant(&mut self, slant: Slant) -> bool {
- unsafe { self.add_integer(b"slant\0", slant as isize) }
- }
-
- pub fn add_pixelsize(&mut self, size: f64) -> bool {
- unsafe { self.add_double(b"pixelsize\0", size) }
- }
-
- pub fn set_weight(&mut self, weight: Weight) -> bool {
- unsafe { self.add_integer(b"weight\0", weight as isize) }
- }
-
- 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").next().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(), self.as_ptr(), request.as_ptr());
- Pattern::from_ptr(ptr)
- }
- }
-
- pub fn hash(&self) -> PatternHash {
- unsafe { PatternHash(FcPatternHash(self.as_ptr())) }
- }
-
- /// Add charset to the pattern.
- ///
- /// The referenced charset is copied by Fontconfig internally using
- /// FcValueSave so that no references to application provided memory are
- /// retained. That is, the CharSet can be safely dropped immediately
- /// after being added to the pattern.
- pub fn add_charset(&self, charset: &CharSetRef) -> bool {
- unsafe {
- FcPatternAddCharSet(
- self.as_ptr(),
- b"charset\0".as_ptr() as *mut c_char,
- charset.as_ptr(),
- ) == 1
- }
- }
-
- /// Get charset from the pattern.
- pub fn get_charset(&self) -> Option<&CharSetRef> {
- unsafe {
- let mut charset = ptr::null_mut();
-
- let result = FcPatternGetCharSet(
- self.as_ptr(),
- b"charset\0".as_ptr() as *mut c_char,
- 0,
- &mut charset,
- );
-
- if result == FcResultMatch {
- Some(&*(charset as *const CharSetRef))
- } else {
- None
- }
- }
- }
-
- /// Get matrix from the pattern.
- pub fn get_matrix(&self) -> Option<FcMatrix> {
- unsafe {
- let mut matrix = ptr::null_mut();
- let result = FcPatternGetMatrix(
- self.as_ptr(),
- b"matrix\0".as_ptr() as *mut c_char,
- 0,
- &mut matrix,
- );
-
- if result == FcResultMatch {
- Some(*matrix)
- } else {
- None
- }
- }
- }
-
- pub fn file(&self, index: usize) -> Option<PathBuf> {
- unsafe { self.get_string(b"file\0").nth(index) }.map(From::from)
- }
-
- pub fn ft_face_location(&self, index: usize) -> Option<FTFaceLocation> {
- match (self.file(index), self.index().next()) {
- (Some(path), Some(index)) => Some(FTFaceLocation::new(path, index)),
- _ => None,
- }
- }
-
- pub fn config_substitute(&mut self, config: &ConfigRef, kind: MatchKind) {
- unsafe {
- FcConfigSubstitute(config.as_ptr(), self.as_ptr(), kind as u32);
- }
- }
-
- pub fn default_substitute(&mut self) {
- unsafe {
- FcDefaultSubstitute(self.as_ptr());
- }
- }
-}