Skip to content

Commit

Permalink
Refactor extra line fragment handling in NSTextLayoutManager and NSTe…
Browse files Browse the repository at this point in the history
…xtLineFragment

This commit refines the handling of extra line fragments. The method
`extraTextLineFragment` is replaced by `extraLineTextLayoutFragment` and
`extraLineTextLineFragment`, enhancing clarity. The new properties and
methods improve the identification of extra line fragments within the
text layout system. The related `isExtraLineFragment` property has also
been added to both `NSTextLayoutFragment` and `NSTextLineFragment`,
providing a consistent way to determine when a line fragment is extra.
  • Loading branch information
krzyzanowskim committed Sep 28, 2024
1 parent fc1dd89 commit 34e80fd
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 58 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ func attributedString(in range: NSTextRange?) -> NSAttributedString?
func textLineFragment(at location: NSTextLocation) -> NSTextLineFragment?
func textLineFragment(at point: CGPoint) -> NSTextLineFragment?

func extraTextLineFragment() -> NSTextLineFragment?
func extraLineTextLayoutFragment() -> NSTextLayoutFragment?
func extraLineTextLineFragment() -> NSTextLineFragment?

func location(interactingAt point: CGPoint, inContainerAt containerLocation: NSTextLocation) -> NSTextLocation?

Expand All @@ -59,6 +60,8 @@ var insertionPointSelections: [NSTextSelection]
### NSTextLayoutFragment Additions

```swift
var isExtraLineFragment: Bool

func textLineFragment(at location: NSTextLocation, in textContentManager: NSTextContentManager? = nil) -> NSTextLineFragment?
func textLineFragment(at location: CGPoint, in textContentManager: NSTextContentManager? = nil) -> NSTextLineFragment?
```
Expand Down
9 changes: 8 additions & 1 deletion Sources/STTextKitPlus/NSTextLayoutFragment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ import UIKit
#endif

extension NSTextLayoutFragment {


/// Whether the layout fragment is for the extra line fragment at the end of a document.
///
/// The layout manager uses the extra line fragment when the last character in a document causes a line or paragraph break. This extra line fragment has no corresponding glyph.
public var isExtraLineFragment: Bool {
textLineFragments.contains(where: \.isExtraLineFragment)
}

public func textLineFragment(at location: NSTextLocation, in textContentManager: NSTextContentManager? = nil) -> NSTextLineFragment? {
guard let textContentManager = textContentManager ?? textLayoutManager?.textContentManager else {
assertionFailure()
Expand Down
31 changes: 22 additions & 9 deletions Sources/STTextKitPlus/NSTextLayoutManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,35 @@ import UIKit

extension NSTextLayoutManager {

/// Extra line fragment.
/// Extra line layout fragment.
///
/// Only valid when ``state`` greater than NSTextLayoutFragment.State.estimatedUsageBounds
@nonobjc public func extraTextLineFragment() -> NSTextLineFragment? {
var extraLineFragment: NSTextLineFragment?
enumerateTextLayoutFragments(from: textContentManager?.documentRange.endLocation, options: .reverse) { textLayoutFragment in
let textLineFragments = textLayoutFragment.textLineFragments
@nonobjc public func extraLineTextLayoutFragment() -> NSTextLayoutFragment? {
var extraTextLayoutFragment: NSTextLayoutFragment?
enumerateTextLayoutFragments(from: nil, options: .reverse) { textLayoutFragment in
if textLayoutFragment.state.rawValue > NSTextLayoutFragment.State.estimatedUsageBounds.rawValue,
textLineFragments.count > 1, let lastTextLineFragment = textLineFragments.last,
lastTextLineFragment.characterRange.location == 0
textLayoutFragment.isExtraLineFragment
{
extraLineFragment = lastTextLineFragment
extraTextLayoutFragment = textLayoutFragment
}
return false
}
return extraLineFragment
return extraTextLayoutFragment
}

/// Extra line fragment.
///
/// Only valid when ``state`` greater than NSTextLayoutFragment.State.estimatedUsageBounds
@nonobjc public func extraLineTextLineFragment() -> NSTextLineFragment? {
if let textLayoutFragment = extraLineTextLayoutFragment() {
let textLineFragments = textLayoutFragment.textLineFragments
if textLineFragments.count > 1, let lastTextLineFragment = textLineFragments.last,
lastTextLineFragment.isExtraLineFragment
{
return lastTextLineFragment
}
}
return nil
}

}
Expand Down
47 changes: 0 additions & 47 deletions Sources/STTextKitPlus/NSTextLineFragment+ExtraLineFragment.swift

This file was deleted.

8 changes: 8 additions & 0 deletions Sources/STTextKitPlus/NSTextLineFragment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ import UIKit

extension NSTextLineFragment {

/// Whether the line fragment is for the extra line fragment at the end of a document.
///
/// The layout manager uses the extra line fragment when the last character in a document causes a line or paragraph break. This extra line fragment has no corresponding glyph.
public var isExtraLineFragment: Bool {
// textLineFragment.characterRange.isEmpty the extra line fragment at the end of a document.
characterRange.isEmpty
}

/// Returns a text range inside privided textLayoutFragment.
///
/// Returned range is relative to the document range origin.
Expand Down

0 comments on commit 34e80fd

Please sign in to comment.