@@ -34,7 +34,14 @@ extension AttributeScopes {
34
34
35
35
@available ( macOS 13 , iOS 16 , tvOS 16 , watchOS 9 , * )
36
36
public let durationField : DurationFieldAttribute
37
-
37
+
38
+ /// The base writing direction of a paragraph.
39
+ #if FOUNDATION_FRAMEWORK
40
+ @_spi ( AttributedStringWritingDirection)
41
+ #endif
42
+ @available ( FoundationPreview 6 . 2 , * )
43
+ public let writingDirection : WritingDirectionAttribute
44
+
38
45
#if FOUNDATION_FRAMEWORK
39
46
@available ( FoundationPreview 0 . 1 , * )
40
47
public let agreementConcept : AgreementConceptAttribute
@@ -507,7 +514,21 @@ extension AttributeScopes.FoundationAttributes {
507
514
case nanoseconds
508
515
}
509
516
}
510
-
517
+
518
+ /// The attribute key for the base writing direction of a paragraph.
519
+ #if FOUNDATION_FRAMEWORK
520
+ @_spi ( AttributedStringWritingDirection)
521
+ #endif
522
+ @available ( FoundationPreview 6 . 2 , * )
523
+ @frozen
524
+ public enum WritingDirectionAttribute : CodableAttributedStringKey {
525
+ public typealias Value = AttributedString . WritingDirection
526
+ public static let name : String = " Foundation.WritingDirectionAttribute "
527
+
528
+ public static let runBoundaries : AttributedString . AttributeRunBoundaries ? = . paragraph
529
+ public static let inheritedByAddedText = false
530
+ }
531
+
511
532
#if FOUNDATION_FRAMEWORK
512
533
@available ( macOS 13 , iOS 16 , tvOS 16 , watchOS 9 , * )
513
534
public struct LocalizedStringArgumentAttributes {
@@ -647,6 +668,9 @@ extension AttributeScopes.FoundationAttributes.ByteCountAttribute : Sendable {}
647
668
@available ( * , unavailable)
648
669
extension AttributeScopes . FoundationAttributes . DurationFieldAttribute : Sendable { }
649
670
671
+ @available ( * , unavailable)
672
+ extension AttributeScopes . FoundationAttributes . WritingDirectionAttribute : Sendable { }
673
+
650
674
#if FOUNDATION_FRAMEWORK
651
675
652
676
@available ( macOS, unavailable, introduced: 14.0 )
@@ -819,3 +843,72 @@ extension AttributeScopes.FoundationAttributes.LocalizedNumberFormatAttribute.Va
819
843
}
820
844
821
845
#endif // FOUNDATION_FRAMEWORK
846
+
847
+ extension AttributedString {
848
+ /// The writing direction of a piece of text.
849
+ ///
850
+ /// Writing direction defines the base direction in which bidirectional text
851
+ /// lays out its directional runs. A directional run is a contigous sequence
852
+ /// of characters that all have the same effective directionality, which can
853
+ /// be determined using the Unicode BiDi algorithm. The ``leftToRight``
854
+ /// writing direction puts the directional run that is placed first in the
855
+ /// storage leftmost, and places subsequent directional runs towards the
856
+ /// right. The ``rightToLeft`` writing direction puts the directional run
857
+ /// that is placed first in the storage rightmost, and places subsequent
858
+ /// directional runs towards the left.
859
+ ///
860
+ /// Note that writing direction is a property separate from a text's
861
+ /// alignment, its line layout direction, or its character direction.
862
+ /// However, it is often used to determine the default alignment of a
863
+ /// paragraph. E.g. English (a language with
864
+ /// ``Locale/LanguageDirection-swift.enum/leftToRight``
865
+ /// ``Locale/Language-swift.struct/characterDirection``) is usually aligned
866
+ /// to the left, but may be centered or aligned to the right for special
867
+ /// effect, or to be visually more appealing in a user interface.
868
+ ///
869
+ /// For bidirectional text to be perceived as laid out correctly, make sure
870
+ /// that the writing direction is set to the value equivalent to the
871
+ /// ``Locale/Language-swift.struct/characterDirection`` of the primary
872
+ /// language in the text. E.g. an English sentence that contains some
873
+ /// Arabic (a language with
874
+ /// ``Locale/LanguageDirection-swift.enum/rightToLeft``
875
+ /// ``Locale/Language-swift.struct/characterDirection``) words, should use
876
+ /// a ``leftToRight`` writing direction. An Arabic sentence that contains
877
+ /// some English words, should use a ``rightToLeft`` writing direction.
878
+ ///
879
+ /// Writing direction is always orthogonoal to the line layout direction
880
+ /// chosen to display a certain text. The line layout direction is the
881
+ /// direction in which a sequence of lines is placed in. E.g. English text
882
+ /// is usually displayed with a line layout direction of
883
+ /// ``Locale/LanguageDirection-swift.enum/topToBottom``. While languages do
884
+ /// have an associated line language direction (see
885
+ /// ``Locale/Language-swift.struct/lineLayoutDirection``), not all displays
886
+ /// of text follow the line layout direction of the text's primary language.
887
+ ///
888
+ /// Horizontal script is script with a line layout direction of either
889
+ /// ``Locale/LanguageDirection-swift.enum/topToBottom`` or
890
+ /// ``Locale/LanguageDirection-swift.enum/bottomToTop``. Vertical script
891
+ /// has a ``Locale/LanguageDirection-swift.enum/leftToRight`` or
892
+ /// ``Locale/LanguageDirection-swift.enum/rightToLeft`` line layout
893
+ /// direction. In vertical scripts, a writing direction of ``leftToRight``
894
+ /// is interpreted as top-to-bottom and a writing direction of
895
+ /// ``rightToLeft`` is interpreted as bottom-to-top.
896
+ #if FOUNDATION_FRAMEWORK
897
+ @_spi ( AttributedStringWritingDirection)
898
+ #endif
899
+ @available ( FoundationPreview 6 . 2 , * )
900
+ @frozen
901
+ public enum WritingDirection : Codable , Hashable , CaseIterable , Sendable {
902
+ /// A left-to-right writing direction in horizontal script.
903
+ ///
904
+ /// - Note: In vertical scripts, this equivalent to a top-to-bottom
905
+ /// writing direction.
906
+ case leftToRight
907
+
908
+ /// A right-to-left writing direction in horizontal script.
909
+ ///
910
+ /// - Note: In vertical scripts, this equivalent to a bottom-to-top
911
+ /// writing direction.
912
+ case rightToLeft
913
+ }
914
+ }
0 commit comments