@@ -810,4 +810,112 @@ fn out_of_range_variations() {
810
810
let var_attrs = var_attrs. unwrap ( ) . downcast :: < CFDictionary > ( ) . unwrap ( ) ;
811
811
assert ! ( var_attrs. is_empty( ) ) ;
812
812
}
813
- }
813
+ }
814
+
815
+ #[ test]
816
+ fn equal_descriptor_different_font ( ) {
817
+ use crate :: * ;
818
+
819
+ let variation_attribute = unsafe { CFString :: wrap_under_get_rule ( font_descriptor:: kCTFontVariationAttribute) } ;
820
+ let size_attribute = unsafe { CFString :: wrap_under_get_rule ( font_descriptor:: kCTFontSizeAttribute) } ;
821
+
822
+ let sys_font = unsafe {
823
+ CTFont :: wrap_under_create_rule (
824
+ CTFontCreateUIFontForLanguage ( kCTFontSystemDetailFontType, 120. , std:: ptr:: null ( ) )
825
+ )
826
+ } ;
827
+
828
+
829
+ // but we can still construct the CGFont by name
830
+ let create_vars = |desc| {
831
+ let mut vals: Vec < ( CFNumber , CFNumber ) > = Vec :: new ( ) ;
832
+ vals. push ( ( CFNumber :: from ( 0x6f70737a ) , CFNumber :: from ( 17. ) ) ) ;
833
+ let vals_dict = CFDictionary :: from_CFType_pairs ( & vals) ;
834
+ let attrs_dict = CFDictionary :: from_CFType_pairs ( & [ ( variation_attribute. clone ( ) , vals_dict) ] ) ;
835
+ let size_attrs_dict = CFDictionary :: from_CFType_pairs ( & [ ( size_attribute. clone ( ) , CFNumber :: from ( 120. ) ) ] ) ;
836
+ dbg ! ( & desc) ;
837
+ let from_font_desc = new_from_descriptor ( & desc, 120. ) . copy_descriptor ( ) ;
838
+ let resized_font_desc = desc. create_copy_with_attributes ( size_attrs_dict. to_untyped ( ) ) . unwrap ( ) ;
839
+ if macos_version ( ) >= ( 11 , 0 , 0 ) {
840
+ assert_eq ! ( from_font_desc, resized_font_desc) ;
841
+ } else {
842
+ // we won't have a name if we're using system font desc
843
+ if from_font_desc. attributes ( ) . find ( unsafe { font_descriptor:: kCTFontNameAttribute } ) . is_none ( ) {
844
+ // it's surprising that desc's are the not equal but the attributes are
845
+ assert_ne ! ( from_font_desc, resized_font_desc) ;
846
+ assert_eq ! ( from_font_desc. attributes( ) . to_untyped( ) , resized_font_desc. attributes( ) . to_untyped( ) ) ;
847
+ } else {
848
+ if macos_version ( ) >= ( 10 , 13 , 0 ) {
849
+ // this is unsurprising
850
+ assert_ne ! ( from_font_desc, resized_font_desc) ;
851
+ assert_ne ! ( from_font_desc. attributes( ) . to_untyped( ) , resized_font_desc. attributes( ) . to_untyped( ) ) ;
852
+ } else {
853
+ assert_ne ! ( from_font_desc, resized_font_desc) ;
854
+ assert_eq ! ( from_font_desc. attributes( ) . to_untyped( ) , resized_font_desc. attributes( ) . to_untyped( ) ) ;
855
+ }
856
+ }
857
+ }
858
+
859
+ let from_font_desc = from_font_desc. create_copy_with_attributes ( attrs_dict. to_untyped ( ) ) . unwrap ( ) ;
860
+ let resized_font_desc = resized_font_desc. create_copy_with_attributes ( attrs_dict. to_untyped ( ) ) . unwrap ( ) ;
861
+ ( from_font_desc, resized_font_desc)
862
+ } ;
863
+
864
+ // setting the variation works properly if we use system font desc
865
+ let ( from_font_desc, resized_font_desc) = create_vars ( sys_font. copy_descriptor ( ) ) ;
866
+ assert_eq ! ( from_font_desc, resized_font_desc) ;
867
+ assert ! ( resized_font_desc. attributes( ) . find( variation_attribute. clone( ) ) . is_some( ) ) ;
868
+
869
+ // but doesn't if we refer to it by name
870
+ let ps = sys_font. postscript_name ( ) ;
871
+ let cgfont = CGFont :: from_name ( & CFString :: new ( & ps) ) . unwrap ( ) ;
872
+ let ctfont = new_from_CGFont ( & cgfont, 0. ) ;
873
+
874
+ let ( from_font_desc, resized_font_desc) = create_vars ( ctfont. copy_descriptor ( ) ) ;
875
+ if macos_version ( ) >= ( 10 , 15 , 0 ) {
876
+ assert_ne ! ( from_font_desc, resized_font_desc) ;
877
+ }
878
+
879
+ if macos_version ( ) >= ( 10 , 13 , 0 ) {
880
+ assert ! ( from_font_desc. attributes( ) . find( variation_attribute. clone( ) ) . is_some( ) ) ;
881
+ if macos_version ( ) >= ( 11 , 0 , 0 ) {
882
+ assert ! ( resized_font_desc. attributes( ) . find( variation_attribute) . is_none( ) ) ;
883
+ } else {
884
+ assert ! ( resized_font_desc. attributes( ) . find( variation_attribute) . is_some( ) ) ;
885
+ } ;
886
+ }
887
+ }
888
+
889
+ #[ test]
890
+ fn system_font_variation ( ) {
891
+ use crate :: * ;
892
+
893
+ let small = unsafe {
894
+ CTFont :: wrap_under_create_rule (
895
+ CTFontCreateUIFontForLanguage ( kCTFontSystemDetailFontType, 17. , std:: ptr:: null ( ) )
896
+ )
897
+ } ;
898
+
899
+ // but we can still construct the CGFont by name
900
+ let ps = small. postscript_name ( ) ;
901
+ let cgfont = CGFont :: from_name ( & CFString :: new ( & ps) ) . unwrap ( ) ;
902
+ let cgfont = new_from_CGFont ( & cgfont, 0. ) ;
903
+ let desc = cgfont. copy_descriptor ( ) ;
904
+
905
+ let mut vals: Vec < ( CFNumber , CFNumber ) > = Vec :: new ( ) ;
906
+ vals. push ( ( CFNumber :: from ( 0x6f70737a /* opsz */ ) , CFNumber :: from ( 17. ) ) ) ;
907
+ let vals_dict = CFDictionary :: from_CFType_pairs ( & vals) ;
908
+ let variation_attribute = unsafe { CFString :: wrap_under_get_rule ( font_descriptor:: kCTFontVariationAttribute) } ;
909
+ let attrs_dict = CFDictionary :: from_CFType_pairs ( & [ ( variation_attribute, vals_dict) ] ) ;
910
+ let ct_var_font_desc = desc. create_copy_with_attributes ( attrs_dict. to_untyped ( ) ) . unwrap ( ) ;
911
+ let attrs = ct_var_font_desc. attributes ( ) ;
912
+ let var_attr = attrs. find ( CFString :: from_static_string ( "NSCTFontVariationAttribute" ) ) ;
913
+ if macos_version ( ) >= ( 11 , 0 , 0 ) {
914
+ // the variation goes away
915
+ assert ! ( var_attr. is_none( ) ) ;
916
+ } else {
917
+ assert ! ( var_attr. is_some( ) ) ;
918
+ }
919
+
920
+ dbg ! ( ct_var_font_desc) ;
921
+ }
0 commit comments