Skip to content

Commit ed0e401

Browse files
committed
Adjust Gutter Drawing - Correct, Fix Y Position Again
1 parent 08eae14 commit ed0e401

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

Sources/CodeEditSourceEditor/Controller/TextViewController+LoadView.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,7 @@ extension TextViewController {
8686
minimapView.bottomAnchor.constraint(equalTo: scrollView.contentView.bottomAnchor),
8787
minimapXConstraint,
8888
maxWidthConstraint,
89-
relativeWidthConstraint,
90-
91-
gutterView.topAnchor.constraint(equalTo: scrollView.contentView.topAnchor),
92-
gutterView.leadingAnchor.constraint(equalTo: scrollView.contentView.leadingAnchor)
89+
relativeWidthConstraint
9390
])
9491
}
9592

@@ -123,11 +120,11 @@ extension TextViewController {
123120
object: textView,
124121
queue: .main
125122
) { [weak self] _ in
126-
self?.gutterView.frame.size.height = max(
127-
(self?.textView.frame.height ?? 0) + 10,
128-
(self?.scrollView.documentVisibleRect.height ?? 0.0) + (self?.scrollView.contentInsets.vertical ?? 0.0)
129-
)
123+
self?.gutterView.frame.size.height = (self?.textView.frame.height ?? 0) + 10
124+
self?.gutterView.frame.origin.y = (self?.textView.frame.origin.y ?? 0.0) - (self?.scrollView.contentInsets.top ?? 0)
125+
130126
self?.gutterView.needsDisplay = true
127+
self?.scrollView.needsLayout = true
131128
}
132129

133130
NotificationCenter.default.addObserver(
@@ -149,7 +146,7 @@ extension TextViewController {
149146

150147
// Reset content insets and gutter position when appearance changes
151148
self.styleScrollView()
152-
self.gutterView.frame.origin.y = -self.scrollView.contentInsets.top
149+
self.gutterView.frame.origin.y = self.textView.frame.origin.y - self.scrollView.contentInsets.top
153150
}
154151
}
155152
.store(in: &cancellables)

Sources/CodeEditSourceEditor/Controller/TextViewController+StyleViews.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ extension TextViewController {
102102

103103
findViewController?.topPadding = contentInsets?.top
104104

105-
gutterView.frame.origin.y = -scrollView.contentInsets.top
105+
gutterView.frame.origin.y = textView.frame.origin.y - scrollView.contentInsets.top
106106

107107
// Update scrollview tiling
108108
scrollView.reflectScrolledClipView(scrollView.contentView)

Sources/CodeEditSourceEditor/Gutter/GutterView.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ public class GutterView: NSView {
4545
var textColor: NSColor = .secondaryLabelColor
4646

4747
@Invalidating(.display)
48-
var font: NSFont = .systemFont(ofSize: 13)
48+
var font: NSFont = .systemFont(ofSize: 13) {
49+
didSet {
50+
updateFontLineHeight()
51+
}
52+
}
4953

5054
@Invalidating(.display)
5155
var edgeInsets: EdgeInsets = EdgeInsets(leading: 20, trailing: 12)
@@ -74,6 +78,19 @@ public class GutterView: NSView {
7478
/// The maximum number of digits found for a line number.
7579
private var maxLineLength: Int = 0
7680

81+
private var fontLineHeight = 1.0
82+
83+
private func updateFontLineHeight() {
84+
let string = NSAttributedString(string: "0", attributes: [.font: font])
85+
let typesetter = CTTypesetterCreateWithAttributedString(string)
86+
let ctLine = CTTypesetterCreateLine(typesetter, CFRangeMake(0, 1))
87+
var ascent: CGFloat = 0
88+
var descent: CGFloat = 0
89+
var leading: CGFloat = 0
90+
CTLineGetTypographicBounds(ctLine, &ascent, &descent, &leading)
91+
fontLineHeight = (ascent + descent + leading)
92+
}
93+
7794
override public var isFlipped: Bool {
7895
true
7996
}
@@ -181,7 +198,7 @@ public class GutterView: NSView {
181198
y: line.yPos,
182199
width: width,
183200
height: line.height
184-
)
201+
).pixelAligned
185202
)
186203
}
187204

@@ -217,12 +234,16 @@ public class GutterView: NSView {
217234
let fragment: LineFragment? = linePosition.data.lineFragments.first?.data
218235
var ascent: CGFloat = 0
219236
let lineNumberWidth = CTLineGetTypographicBounds(ctLine, &ascent, nil, nil)
237+
let fontHeightDifference = ((fragment?.height ?? 0) - fontLineHeight) / 4
220238

221-
let yPos = linePosition.yPos + ascent + (fragment?.heightDifference ?? 0)/2
239+
let yPos = linePosition.yPos + ascent + (fragment?.heightDifference ?? 0)/2 + fontHeightDifference
222240
// Leading padding + (width - linewidth)
223241
let xPos = edgeInsets.leading + (maxWidth - lineNumberWidth)
224242

225-
context.textPosition = CGPoint(x: xPos, y: yPos).pixelAligned
243+
ContextSetHiddenSmoothingStyle(context, 16)
244+
245+
context.textPosition = CGPoint(x: xPos, y: yPos)
246+
226247
CTLineDraw(ctLine, context)
227248
}
228249
context.restoreGState()

0 commit comments

Comments
 (0)