@@ -15,7 +15,7 @@ use font_descriptor::{CTFontSymbolicTraits, CTFontTraits, SymbolicTraitAccessors
15
15
use font_manager:: create_font_descriptor;
16
16
17
17
use core_foundation:: array:: { CFArray , CFArrayRef } ;
18
- use core_foundation:: base:: { CFIndex , CFOptionFlags , CFType , CFTypeID , CFTypeRef , TCFType } ;
18
+ use core_foundation:: base:: { CFIndex , CFOptionFlags , CFType , CFTypeID , CFTypeRef , TCFType , TCFTypeRef } ;
19
19
use core_foundation:: data:: { CFData , CFDataRef } ;
20
20
use core_foundation:: dictionary:: { CFDictionary , CFDictionaryRef } ;
21
21
use core_foundation:: number:: CFNumber ;
@@ -32,6 +32,8 @@ use libc::{self, size_t};
32
32
use std:: os:: raw:: c_void;
33
33
use std:: ptr;
34
34
35
+ use crate :: font_manager:: create_font_descriptors;
36
+
35
37
type CGContextRef = * mut <CGContext as ForeignType >:: CType ;
36
38
type CGFontRef = * mut <CGFont as ForeignType >:: CType ;
37
39
type CGPathRef = * mut <CGPath as ForeignType >:: CType ;
@@ -127,7 +129,21 @@ pub fn new_from_descriptor(desc: &CTFontDescriptor, pt_size: f64) -> CTFont {
127
129
128
130
pub fn new_from_buffer ( buffer : & [ u8 ] ) -> Result < CTFont , ( ) > {
129
131
let ct_font_descriptor = create_font_descriptor ( buffer) ?;
130
- Ok ( new_from_descriptor ( & ct_font_descriptor, 16.0 ) )
132
+ Ok ( new_from_name ( & ct_font_descriptor. postscript_name ( ) , 16.0 ) ?)
133
+ }
134
+
135
+ pub fn new_fonts_from_buffer ( buffer : & [ u8 ] ) -> Result < Vec < CTFont > , ( ) > {
136
+ let ct_font_descriptors = create_font_descriptors ( buffer) ?;
137
+
138
+ let mut ct_fonts = Vec :: new ( ) ;
139
+ unsafe {
140
+ for descriptor_ptr in ct_font_descriptors. get_all_values ( ) . into_iter ( ) {
141
+ let descriptor = CTFontDescriptor :: wrap_under_get_rule ( CTFontDescriptorRef :: from_void_ptr ( descriptor_ptr) ) ;
142
+ ct_fonts. push ( new_from_name ( & descriptor. font_name ( ) , 16.0 ) ?) ;
143
+ }
144
+ }
145
+
146
+ Ok ( ct_fonts)
131
147
}
132
148
133
149
pub fn new_from_name ( name : & str , pt_size : f64 ) -> Result < CTFont , ( ) > {
@@ -646,6 +662,40 @@ extern {
646
662
fn CTFontGetTypeID ( ) -> CFTypeID ;
647
663
}
648
664
665
+ #[ test]
666
+ fn test_font_descriptor_and_variation ( ) {
667
+ use std:: io:: Read ;
668
+ let mut f = std:: fs:: File :: open ( "/System/Library/Fonts/Helvetica.ttc" ) . unwrap ( ) ;
669
+ let mut font_data = Vec :: new ( ) ;
670
+ f. read_to_end ( & mut font_data) . unwrap ( ) ;
671
+ let descriptors = crate :: font_manager:: create_font_descriptors ( & font_data) . unwrap ( ) ;
672
+
673
+ unsafe {
674
+ for descriptor_ptr in descriptors. get_all_values ( ) . into_iter ( ) {
675
+ let descriptor = CTFontDescriptor :: wrap_under_get_rule ( CTFontDescriptorRef :: from_void_ptr ( descriptor_ptr) ) ;
676
+
677
+ // when create ttc/otc fonts from descriptor, all font variations are the same
678
+ let font = new_from_descriptor ( & descriptor, 12. ) ;
679
+ println ! ( "font name= {:?}, desc.name= {:?}" , font. face_name( ) , descriptor. font_name( ) ) ;
680
+
681
+ let sym = font. symbolic_traits ( ) ;
682
+ assert_eq ! ( false , sym. is_italic( ) ) ;
683
+ assert_eq ! ( false , sym. is_bold( ) ) ;
684
+ assert_eq ! ( false , sym. is_expanded( ) ) ;
685
+ assert_eq ! ( false , sym. is_condensed( ) ) ;
686
+ assert_eq ! ( false , sym. is_monospace( ) ) ;
687
+
688
+ let all_traits = font. all_traits ( ) ;
689
+ assert_eq ! ( 0. , all_traits. normalized_weight( ) ) ;
690
+ assert_eq ! ( 0. , all_traits. normalized_width( ) ) ;
691
+
692
+ // we have to create them from font name
693
+ let font = new_from_name ( & descriptor. font_name ( ) , 12. ) . unwrap ( ) ;
694
+ debug_font_traits ( & font) ;
695
+ }
696
+ }
697
+ }
698
+
649
699
#[ test]
650
700
fn copy_font ( ) {
651
701
use std:: io:: Read ;
@@ -741,4 +791,4 @@ fn copy_system_font() {
741
791
assert ! ( matching. attributes( ) . find( CFString :: from_static_string( "NSFontSizeAttribute" ) ) . is_none( ) ) ;
742
792
743
793
assert_eq ! ( small. postscript_name( ) , cgfont. postscript_name( ) ) ;
744
- }
794
+ }
0 commit comments