@@ -324,6 +324,38 @@ impl<'fc> Pattern<'fc> {
324324 }
325325 }
326326
327+ /// Returns a [`FontSet`] containing fonts sorted by closeness to this pattern.
328+ ///
329+ /// If `trim` is true, elements in the list which don't include Unicode coverage not provided by
330+ /// earlier elements in the list are elided.
331+ ///
332+ /// See the [Fontconfig reference][1] for more details.
333+ ///
334+ /// [1]: https://www.freedesktop.org/software/fontconfig/fontconfig-devel/fcfontsort.html
335+ pub fn sort_fonts ( & mut self , trim : bool ) -> FontSet < ' fc > {
336+ // Docs: This function should be called only after FcConfigSubstitute and FcDefaultSubstitute
337+ // have been called for p; otherwise the results will not be correct.
338+ self . config_substitute ( ) ;
339+ self . default_substitute ( ) ;
340+
341+ // FcFontSort always returns a (possibly empty) set so we don't need to check this.
342+ let mut res = sys:: FcResultNoMatch ;
343+ let unicode_coverage = ptr:: null_mut ( ) ;
344+ let config = ptr:: null_mut ( ) ;
345+ unsafe {
346+ let raw_set = ffi_dispatch ! (
347+ LIB ,
348+ FcFontSort ,
349+ config,
350+ self . pat,
351+ trim as FcBool ,
352+ unicode_coverage,
353+ & mut res
354+ ) ;
355+ FontSet :: from_raw ( self . fc , raw_set)
356+ }
357+ }
358+
327359 /// Get the "fullname" (human-readable name) of this pattern.
328360 pub fn name ( & self ) -> Option < & str > {
329361 self . get_string ( FC_FULLNAME )
@@ -539,31 +571,6 @@ pub fn list_fonts<'fc>(pattern: &Pattern<'fc>, objects: Option<&ObjectSet>) -> F
539571 }
540572}
541573
542- /// Returns a [`FontSet`] containing fonts sorted by closeness to the supplied `pattern`. If `trim` is true, elements in
543- /// the list which don't include Unicode coverage not provided by earlier elements in the list are elided.
544- ///
545- /// See the [fontconfig reference][1] for more details.
546- ///
547- /// [1]: https://www.freedesktop.org/software/fontconfig/fontconfig-devel/fcfontsort.html
548- pub fn sort_fonts < ' fc > ( pattern : & Pattern < ' fc > , trim : bool ) -> FontSet < ' fc > {
549- // FcFontSort always returns a (possibly empty) set so we don't need to check this.
550- let mut res = sys:: FcResultNoMatch ;
551- let unicode_coverage = ptr:: null_mut ( ) ;
552- let config = ptr:: null_mut ( ) ;
553- unsafe {
554- let raw_set = ffi_dispatch ! (
555- LIB ,
556- FcFontSort ,
557- config,
558- pattern. pat,
559- trim as FcBool ,
560- unicode_coverage,
561- & mut res
562- ) ;
563- FontSet :: from_raw ( pattern. fc , raw_set)
564- }
565- }
566-
567574/// Wrapper around `FcObjectSet`.
568575pub struct ObjectSet {
569576 fcset : * mut sys:: FcObjectSet ,
@@ -671,4 +678,24 @@ mod tests {
671678 let langs = pattern. lang_set ( ) . unwrap ( ) . collect :: < Vec < _ > > ( ) ;
672679 assert ! ( langs. iter( ) . find( |&&l| l == "ie" ) . is_some( ) ) ;
673680 }
681+
682+ #[ test]
683+ fn test_sort_fonts ( ) {
684+ let fc = Fontconfig :: new ( ) . unwrap ( ) ;
685+ let mut pat = Pattern :: new ( & fc) ;
686+ let family = CString :: new ( "dejavu sans" ) . unwrap ( ) ;
687+ pat. add_string ( FC_FAMILY , & family) ;
688+
689+ let style = CString :: new ( "oblique" ) . unwrap ( ) ;
690+ pat. add_string ( FC_STYLE , & style) ;
691+
692+ let font_set = pat. sort_fonts ( false ) ;
693+
694+ for pattern in font_set. iter ( ) {
695+ println ! ( "{:?}" , pattern. name( ) ) ;
696+ }
697+
698+ // Ensure that the set can be iterated again
699+ assert ! ( font_set. iter( ) . count( ) > 0 ) ;
700+ }
674701}
0 commit comments