TextViews.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. extension BackendFeatures {
  2. /// Backend methods for text rendering.
  3. ///
  4. /// These are used by ``Text``, and occasionally other features as well.
  5. @MainActor
  6. public protocol TextViews: Core {
  7. /// Resolves the given text style to concrete font properties.
  8. ///
  9. /// This method doesn't take ``EnvironmentValues`` because its result
  10. /// should be consistent when given the same text style twice. Font
  11. /// modifiers take effect later in the font resolution process.
  12. ///
  13. /// A default implementation is provided. It uses the backend's reported
  14. /// device class and looks up the text style in a lookup table derived
  15. /// from Apple's typography guidelines.
  16. ///
  17. /// - SeeAlso: ``Font/TextStyle/resolve(for:)``
  18. ///
  19. /// - Parameter textStyle: The text style to resolve.
  20. /// - Returns: The resolved text style.
  21. func resolveTextStyle(_ textStyle: Font.TextStyle) -> Font.TextStyle.Resolved
  22. /// Gets the size that the given text would have if it were laid out while
  23. /// attempting to stay within the proposed frame.
  24. ///
  25. /// The size returned by this function will be upheld by the layout system;
  26. /// child views always get the final say on their own size, parents just
  27. /// choose how the children get laid out. The given text should be
  28. /// truncated/ellipsized to fit within the proposal if possible.
  29. ///
  30. /// SwiftCrossUI will never supply zero as the proposed width or height,
  31. /// because some UI frameworks handle that in special ways.
  32. ///
  33. /// Most backends only use the proposed width and ignore the proposed height.
  34. ///
  35. /// Used by both ``Text`` and ``TextEditor``.
  36. ///
  37. /// - Parameters:
  38. /// - text: The text to get the size of.
  39. /// - widget: The target widget. Some backends (such as GTK) require a
  40. /// reference to the target widget to get a text layout context.
  41. /// - proposedWidth: The proposed width of the text. If `nil`, the text
  42. /// should take up as much height as necessary to respect the proposed
  43. /// width without getting ellipsized.
  44. /// - proposedHeight: The proposed height of the text.
  45. /// - environment: The current environment.
  46. /// - Returns: The size of `text` if it were laid out while attempting to
  47. /// stay within `proposedFrame`.
  48. func size(
  49. of text: String,
  50. whenDisplayedIn widget: Widget,
  51. proposedWidth: Int?,
  52. proposedHeight: Int?,
  53. environment: EnvironmentValues
  54. ) -> SIMD2<Int>
  55. /// Creates a non-editable text view with optional text wrapping.
  56. ///
  57. /// Predominantly used by ``Text``.
  58. ///
  59. /// The returned widget should truncate and ellipsize its content when
  60. /// given a size which isn't big enough to fit the full content, as per
  61. /// ``size(of:whenDisplayedIn:proposedWidth:proposedHeight:environment:)``.
  62. ///
  63. /// - Returns: A text view.
  64. func createTextView() -> Widget
  65. /// Sets the content and wrapping mode of a non-editable text view.
  66. ///
  67. /// - Parameters:
  68. /// - textView: The text view.
  69. /// - content: The text view's content.
  70. /// - environment: The current environment.
  71. func updateTextView(
  72. _ textView: Widget,
  73. content: String,
  74. environment: EnvironmentValues
  75. )
  76. }
  77. }
  78. // MARK: Default Implementations
  79. extension BackendFeatures.TextViews {
  80. public func resolveTextStyle(
  81. _ textStyle: Font.TextStyle
  82. ) -> Font.TextStyle.Resolved {
  83. textStyle.resolve(for: deviceClass)
  84. }
  85. }