Skip to content

Commit

Permalink
textLayoutRangeView: Fix layout calculation and image drawing
Browse files Browse the repository at this point in the history
Calculate the frame of the text range more accurately, taking into account
the padding and margins of each text layout fragment.

Simplify the image() function to call stImage() directly.

When drawing, calculate the origin for each text line fragment based on the
layout fragment frame origin, rather than always starting at .zero.
  • Loading branch information
krzyzanowskim committed Dec 22, 2024
1 parent 486e6bf commit aa2b1e9
Showing 1 changed file with 6 additions and 15 deletions.
21 changes: 6 additions & 15 deletions Sources/STTextViewAppKit/STTextLayoutRangeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ open class STTextLayoutRangeView: NSView {
var frame: CGRect = textLayoutManager.textSegmentFrame(in: self.textRange, type: .standard)!
textLayoutManager.enumerateTextLayoutFragments(in: self.textRange) { textLayoutFragment in
frame = CGRect(
x: min(frame.origin.x, textLayoutFragment.layoutFragmentFrame.origin.x),
y: frame.origin.y,
width: max(frame.size.width, textLayoutFragment.renderingSurfaceBounds.width),
height: max(frame.size.height, textLayoutFragment.renderingSurfaceBounds.height)
x: min(frame.origin.x, textLayoutFragment.layoutFragmentFrame.minX),
y: min(frame.origin.y, textLayoutFragment.layoutFragmentFrame.minY),
width: max(frame.size.width, textLayoutFragment.layoutFragmentFrame.maxX + textLayoutFragment.leadingPadding + textLayoutFragment.trailingPadding),
height: max(frame.size.height, textLayoutFragment.layoutFragmentFrame.maxY + textLayoutFragment.topMargin + textLayoutFragment.bottomMargin)
)
return true
}
Expand All @@ -47,26 +47,17 @@ open class STTextLayoutRangeView: NSView {
}

open func image() -> NSImage? {
guard let imageRep = bitmapImageRepForCachingDisplay(in: bounds) else {
return nil
}
cacheDisplay(in: bounds, to: imageRep)

guard let cgImage = imageRep.cgImage else {
return nil
}

return NSImage(cgImage: cgImage, size: bounds.size)
stImage()
}

open override func draw(_ dirtyRect: NSRect) {
guard let ctx = NSGraphicsContext.current?.cgContext else { return }

var origin: CGPoint = .zero
textLayoutManager.enumerateTextLayoutFragments(in: textRange) { textLayoutFragment in
// at what location start draw the line. the first character is at textRange.location
// I want to draw just a part of the line fragment, however I can only draw the whole line
// so remove/delete unnecessary part of the line
var origin = textLayoutFragment.layoutFragmentFrame.origin
for textLineFragment in textLayoutFragment.textLineFragments {
guard let textLineFragmentRange = textLineFragment.textRange(in: textLayoutFragment) else {
continue
Expand Down

0 comments on commit aa2b1e9

Please sign in to comment.