12
12
use font_descriptor;
13
13
use font_descriptor:: { CTFontDescriptor , CTFontDescriptorRef , CTFontOrientation } ;
14
14
use font_descriptor:: { CTFontSymbolicTraits , CTFontTraits , SymbolicTraitAccessors , TraitAccessors } ;
15
- use font_manager:: create_font_descriptor;
15
+ use font_manager:: { create_font_descriptor, create_font_descriptors , create_font_descriptor_with_data } ;
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 ;
@@ -31,6 +31,7 @@ use foreign_types::ForeignType;
31
31
use libc:: { self , size_t} ;
32
32
use std:: os:: raw:: c_void;
33
33
use std:: ptr;
34
+ use std:: sync:: Arc ;
34
35
35
36
type CGContextRef = * mut <CGContext as ForeignType >:: CType ;
36
37
type CGFontRef = * mut <CGFont as ForeignType >:: CType ;
@@ -127,7 +128,26 @@ pub fn new_from_descriptor(desc: &CTFontDescriptor, pt_size: f64) -> CTFont {
127
128
128
129
pub fn new_from_buffer ( buffer : & [ u8 ] ) -> Result < CTFont , ( ) > {
129
130
let ct_font_descriptor = create_font_descriptor ( buffer) ?;
130
- Ok ( new_from_descriptor ( & ct_font_descriptor, 16.0 ) )
131
+ Ok ( new_from_name ( & ct_font_descriptor. font_name ( ) , 16.0 ) ?)
132
+ }
133
+
134
+ pub fn new_from_arc_buffer < T : AsRef < [ u8 ] > + Sync + Send > ( buffer : Arc < T > ) -> Result < CTFont , ( ) > {
135
+ let ct_font_descriptor = create_font_descriptor_with_data ( CFData :: from_arc ( buffer) ) ?;
136
+ Ok ( new_from_name ( & ct_font_descriptor. font_name ( ) , 16.0 ) ?)
137
+ }
138
+
139
+ pub fn new_fonts_from_buffer ( buffer : & [ u8 ] ) -> Result < Vec < CTFont > , ( ) > {
140
+ let ct_font_descriptors = create_font_descriptors ( buffer) ?;
141
+
142
+ let mut ct_fonts = Vec :: new ( ) ;
143
+ unsafe {
144
+ for descriptor_ptr in ct_font_descriptors. get_all_values ( ) . into_iter ( ) {
145
+ let descriptor = CTFontDescriptor :: wrap_under_get_rule ( CTFontDescriptorRef :: from_void_ptr ( descriptor_ptr) ) ;
146
+ ct_fonts. push ( new_from_name ( & descriptor. font_name ( ) , 16.0 ) ?) ;
147
+ }
148
+ }
149
+
150
+ Ok ( ct_fonts)
131
151
}
132
152
133
153
pub fn new_from_name ( name : & str , pt_size : f64 ) -> Result < CTFont , ( ) > {
@@ -646,6 +666,40 @@ extern {
646
666
fn CTFontGetTypeID ( ) -> CFTypeID ;
647
667
}
648
668
669
+ #[ test]
670
+ fn test_font_descriptor_and_variation ( ) {
671
+ use std:: io:: Read ;
672
+ let mut f = std:: fs:: File :: open ( "/System/Library/Fonts/Helvetica.ttc" ) . unwrap ( ) ;
673
+ let mut font_data = Vec :: new ( ) ;
674
+ f. read_to_end ( & mut font_data) . unwrap ( ) ;
675
+ let descriptors = create_font_descriptors ( & font_data) . unwrap ( ) ;
676
+
677
+ unsafe {
678
+ for descriptor_ptr in descriptors. get_all_values ( ) . into_iter ( ) {
679
+ let descriptor = CTFontDescriptor :: wrap_under_get_rule ( CTFontDescriptorRef :: from_void_ptr ( descriptor_ptr) ) ;
680
+
681
+ // when create ttc/otc fonts from descriptor, all font variations are the same
682
+ let font = new_from_descriptor ( & descriptor, 12. ) ;
683
+ println ! ( "font name= {:?}, desc.name= {:?}" , font. face_name( ) , descriptor. font_name( ) ) ;
684
+
685
+ let sym = font. symbolic_traits ( ) ;
686
+ assert_eq ! ( false , sym. is_italic( ) ) ;
687
+ assert_eq ! ( false , sym. is_bold( ) ) ;
688
+ assert_eq ! ( false , sym. is_expanded( ) ) ;
689
+ assert_eq ! ( false , sym. is_condensed( ) ) ;
690
+ assert_eq ! ( false , sym. is_monospace( ) ) ;
691
+
692
+ let all_traits = font. all_traits ( ) ;
693
+ assert_eq ! ( 0. , all_traits. normalized_weight( ) ) ;
694
+ assert_eq ! ( 0. , all_traits. normalized_width( ) ) ;
695
+
696
+ // we have to create them from font name
697
+ let font = new_from_name ( & descriptor. font_name ( ) , 12. ) . unwrap ( ) ;
698
+ debug_font_traits ( & font) ;
699
+ }
700
+ }
701
+ }
702
+
649
703
#[ test]
650
704
fn copy_font ( ) {
651
705
use std:: io:: Read ;
@@ -741,4 +795,4 @@ fn copy_system_font() {
741
795
assert ! ( matching. attributes( ) . find( CFString :: from_static_string( "NSFontSizeAttribute" ) ) . is_none( ) ) ;
742
796
743
797
assert_eq ! ( small. postscript_name( ) , cgfont. postscript_name( ) ) ;
744
- }
798
+ }
0 commit comments