* Render the terminal buffer to canvas
(
buffer: IRenderable,
forceAll: boolean = false,
viewportY: number = 0,
scrollbackProvider?: IScrollbackProvider,
scrollbarOpacity: number = 1
)
| 265 | * Render the terminal buffer to canvas |
| 266 | */ |
| 267 | public render( |
| 268 | buffer: IRenderable, |
| 269 | forceAll: boolean = false, |
| 270 | viewportY: number = 0, |
| 271 | scrollbackProvider?: IScrollbackProvider, |
| 272 | scrollbarOpacity: number = 1 |
| 273 | ): void { |
| 274 | // Store buffer reference for grapheme lookups in renderCell |
| 275 | this.currentBuffer = buffer; |
| 276 | |
| 277 | // getCursor() calls update() internally to ensure fresh state. |
| 278 | // Multiple update() calls are safe - dirty state persists until clearDirty(). |
| 279 | const cursor = buffer.getCursor(); |
| 280 | const dims = buffer.getDimensions(); |
| 281 | const scrollbackLength = scrollbackProvider ? scrollbackProvider.getScrollbackLength() : 0; |
| 282 | |
| 283 | // Check if buffer needs full redraw (e.g., screen change between normal/alternate) |
| 284 | if (buffer.needsFullRedraw?.()) { |
| 285 | forceAll = true; |
| 286 | } |
| 287 | |
| 288 | // Resize canvas if dimensions changed |
| 289 | const needsResize = |
| 290 | this.canvas.width !== dims.cols * this.metrics.width * this.devicePixelRatio || |
| 291 | this.canvas.height !== dims.rows * this.metrics.height * this.devicePixelRatio; |
| 292 | |
| 293 | if (needsResize) { |
| 294 | this.resize(dims.cols, dims.rows); |
| 295 | forceAll = true; // Force full render after resize |
| 296 | } |
| 297 | |
| 298 | // Force re-render when viewport changes (scrolling) |
| 299 | if (viewportY !== this.lastViewportY) { |
| 300 | forceAll = true; |
| 301 | this.lastViewportY = viewportY; |
| 302 | } |
| 303 | |
| 304 | // Check if cursor position changed or if blinking (need to redraw cursor line) |
| 305 | const cursorMoved = |
| 306 | cursor.x !== this.lastCursorPosition.x || cursor.y !== this.lastCursorPosition.y; |
| 307 | if (cursorMoved || this.cursorBlink) { |
| 308 | // Mark cursor lines as needing redraw |
| 309 | if (!forceAll && !buffer.isRowDirty(cursor.y)) { |
| 310 | // Need to redraw cursor line |
| 311 | const line = buffer.getLine(cursor.y); |
| 312 | if (line) { |
| 313 | this.renderLine(line, cursor.y, dims.cols); |
| 314 | } |
| 315 | } |
| 316 | if (cursorMoved && this.lastCursorPosition.y !== cursor.y) { |
| 317 | // Also redraw old cursor line if cursor moved to different line |
| 318 | if (!forceAll && !buffer.isRowDirty(this.lastCursorPosition.y)) { |
| 319 | const line = buffer.getLine(this.lastCursorPosition.y); |
| 320 | if (line) { |
| 321 | this.renderLine(line, this.lastCursorPosition.y, dims.cols); |
| 322 | } |
| 323 | } |
| 324 | } |
no test coverage detected