Skip to content

Commit

Permalink
Better approach at rendering the bottom exposed region of the buffer,…
Browse files Browse the repository at this point in the history
… and in the

process, I cleaned up some historical baggage and a nice upgrade.

The nice upgrade is that I am using the exposed region as intended for the Mac,
over time, the code regressed and was redrawing the whole buffer, now it does
what it is supposed to do.

The parameter "offset" to "drawTerminalContents" was deprecated when I moved to
the UIScrollView backing for the iOS terminal, so I have eliminated it.

Rather than computing "remains" at the start, we compute at the end, and rather
than the float->int->float conversions, we use:

bounds.height.truncatingRemainder(dividingBy: cellHeight)

Additionally, given that there is a font change redraw issue not addressed here,
I am keeping the old clearing code (and I have fixed it now), but I have also
implemented the alterantive which should draw a lot less, so as soon as I
fix the font change issue, I can remove the code from the caller of
"drawTerminalContents".
  • Loading branch information
migueldeicaza committed Apr 18, 2023
1 parent 98d1440 commit eefa5d1
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 18 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@ slow-unit-*
timeout-*
slow-unit-*
fuzz-*.log
xcuserdata
crash-*
DerivedData
.deriveddata
.build
.DS_Store
44 changes: 29 additions & 15 deletions Sources/SwiftTerm/Apple/AppleTerminalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -529,30 +529,28 @@ extension TerminalView {


// TODO: this should not render any lines outside the dirtyRect
func drawTerminalContents (dirtyRect: TTRect, context: CGContext, offset: CGFloat, bufferOffset: Int)
func drawTerminalContents (dirtyRect: TTRect, context: CGContext, bufferOffset: Int)
{
let lineDescent = CTFontGetDescent(fontSet.normal)
let lineLeading = CTFontGetLeading(fontSet.normal)
let yOffset = ceil(lineDescent+lineLeading)

func calcLineOffset (forRow: Int) -> CGFloat {
cellDimension.height * CGFloat (forRow-bufferOffset+1) + offset
cellDimension.height * CGFloat (forRow-bufferOffset+1)
}

// draw lines

#if os(iOS)
// On iOS, we are drawing the exposed region
let cellHeight = cellDimension.height
let firstRow = Int (dirtyRect.minY/cellHeight)
let lastRow = Int(dirtyRect.maxY/cellHeight)
let remains = CGFloat (lastRow) * cellHeight
#else
// On Mac, we are drawing the terminal buffer
let cellHeight = cellDimension.height
let remains = trunc (dirtyRect.height/cellHeight) * cellHeight
let firstRow = terminal.buffer.yDisp
let lastRow = terminal.rows + terminal.buffer.yDisp
let boundsMaxY = bounds.maxY
let firstRow = terminal.buffer.yDisp+Int ((boundsMaxY-dirtyRect.maxY)/cellHeight)
let lastRow = terminal.buffer.yDisp+Int((boundsMaxY-dirtyRect.minY)/cellHeight)
#endif

for row in firstRow...lastRow {
Expand Down Expand Up @@ -618,7 +616,7 @@ extension TerminalView {
let line = terminal.buffer.lines [row]
let lineInfo = buildAttributedString(row: row, line: line, cols: terminal.cols)
let ctline = CTLineCreateWithAttributedString(lineInfo.attrStr)

var col = 0
for run in CTLineGetGlyphRuns(ctline) as? [CTRun] ?? [] {
let runGlyphsCount = CTRunGetGlyphCount(run)
Expand Down Expand Up @@ -663,21 +661,21 @@ extension TerminalView {
origin.y -= missing
}
#endif

if col + runGlyphsCount >= terminal.cols {
size.width += frame.width - size.width
}

let rect = CGRect (origin: origin, size: size)

#if os(macOS)
rect.applying(transform).fill(using: .destinationOver)
#else
context.fill(rect.applying(transform))
#endif
context.restoreGState()
}

nativeForegroundColor.set()

if runAttributes.keys.contains(.foregroundColor) {
Expand All @@ -696,6 +694,7 @@ extension TerminalView {

col += runGlyphsCount
}

// Render any sixel content last
if let images = lineInfo.images {
let rowBase = frame.height - (CGFloat(row) * cellDimension.height)
Expand All @@ -712,7 +711,6 @@ extension TerminalView {
image.image.draw (in: rect)
}
}

switch renderMode {
case .single:
break
Expand All @@ -724,11 +722,28 @@ extension TerminalView {
context.restoreGState()
}
}
let box = CGRect (x: 0, y: 0, width: bounds.width, height: bounds.height-remains)

#if os(macOS)
// Fills gaps at the end with the default terminal background
let box = CGRect (x: 0, y: 0, width: bounds.width, height: bounds.height.truncatingRemainder(dividingBy: cellHeight))
if dirtyRect.intersects(box) {
nativeBackgroundColor.setFill()
context.fill ([box])
}
#elseif false
// Currently the caller on iOS is clearing the entire dirty region due to the ordering of
// font change sizes, but once we fix that, we should remove the clearing of the dirty
// region in the calling code, and enable this code instead.
let lineOffset = calcLineOffset(forRow: lastRow)
let lineOrigin = CGPoint(x: 0, y: frame.height - lineOffset)

let inter = dirtyRect.intersection(CGRect (x: 0, y: lineOrigin.y, width: bounds.width, height: cellHeight))
if !inter.isEmpty {
nativeBackgroundColor.setFill()
context.fill ([inter])
}
#endif

#if os(iOS)
if selection.active {
let start, end: Position
Expand Down Expand Up @@ -811,7 +826,6 @@ extension TerminalView {
region = CGRect (x: 0, y: 0, width: frame.width, height: oh + oy)
}
setNeedsDisplay(region)
setNeedsDisplay(bounds)
#else
// TODO iOS: need to update the code above, but will do that when I get some real
// life data being fed into it.
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftTerm/Mac/MacTerminalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ open class TerminalView: NSView, NSTextInputClient, NSUserInterfaceValidations,
guard let currentContext = getCurrentGraphicsContext() else {
return
}
drawTerminalContents (dirtyRect: dirtyRect, context: currentContext, offset: 0, bufferOffset: terminal.buffer.yDisp)
drawTerminalContents (dirtyRect: dirtyRect, context: currentContext, bufferOffset: terminal.buffer.yDisp)
}

public override func cursorUpdate(with event: NSEvent)
Expand Down
6 changes: 4 additions & 2 deletions Sources/SwiftTerm/iOS/iOSTerminalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -963,14 +963,16 @@ open class TerminalView: UIScrollView, UITextInputTraits, UIKeyInput, UIScrollVi
}

// Without these two lines, on font changes, some junk is being displayed
// Once we test the font change, we could disable these two lines, and
// enable the #if false in drawterminalContents that should be coping with this now
nativeBackgroundColor.set ()
context.clear(dirtyRect)
context.fill ([dirtyRect])

// drawTerminalContents and CoreText expect the AppKit coordinate system
context.scaleBy (x: 1, y: -1)
context.translateBy(x: 0, y: -frame.height)

drawTerminalContents (dirtyRect: dirtyRect, context: context, offset: 0, bufferOffset: 0)
drawTerminalContents (dirtyRect: dirtyRect, context: context, bufferOffset: 0)
}

open override var bounds: CGRect {
Expand Down

0 comments on commit eefa5d1

Please sign in to comment.