@@ -50,16 +50,21 @@ void main() {
5050 outColor = v_color;
5151}` ;
5252
53- interface IVertices {
54- attributes : Float32Array ;
55- count : number ;
56- }
57-
5853const INDICES_PER_RECTANGLE = 8 ;
5954const BYTES_PER_RECTANGLE = INDICES_PER_RECTANGLE * Float32Array . BYTES_PER_ELEMENT ;
6055
6156const INITIAL_BUFFER_RECTANGLE_CAPACITY = 20 * INDICES_PER_RECTANGLE ;
6257
58+ class Vertices {
59+ attributes : Float32Array ;
60+ count : number ;
61+
62+ constructor ( ) {
63+ this . attributes = new Float32Array ( INITIAL_BUFFER_RECTANGLE_CAPACITY ) ;
64+ this . count = 0 ;
65+ }
66+ }
67+
6368// Work variables to avoid garbage collection
6469let $rgba = 0 ;
6570let $isDefault = false ;
@@ -77,11 +82,10 @@ export class RectangleRenderer extends Disposable {
7782 private _attributesBuffer : WebGLBuffer ;
7883 private _projectionLocation : WebGLUniformLocation ;
7984 private _bgFloat ! : Float32Array ;
85+ private _cursorFloat ! : Float32Array ;
8086
81- private _vertices : IVertices = {
82- count : 0 ,
83- attributes : new Float32Array ( INITIAL_BUFFER_RECTANGLE_CAPACITY )
84- } ;
87+ private _vertices : Vertices = new Vertices ( ) ;
88+ private _verticesCursor : Vertices = new Vertices ( ) ;
8589
8690 constructor (
8791 private _terminal : Terminal ,
@@ -142,7 +146,15 @@ export class RectangleRenderer extends Disposable {
142146 } ) ) ;
143147 }
144148
145- public render ( ) : void {
149+ public renderBackgrounds ( ) : void {
150+ this . _renderVertices ( this . _vertices ) ;
151+ }
152+
153+ public renderCursor ( ) : void {
154+ this . _renderVertices ( this . _verticesCursor ) ;
155+ }
156+
157+ private _renderVertices ( vertices : Vertices ) : void {
146158 const gl = this . _gl ;
147159
148160 gl . useProgram ( this . _program ) ;
@@ -153,8 +165,8 @@ export class RectangleRenderer extends Disposable {
153165
154166 // Bind attributes buffer and draw
155167 gl . bindBuffer ( gl . ARRAY_BUFFER , this . _attributesBuffer ) ;
156- gl . bufferData ( gl . ARRAY_BUFFER , this . _vertices . attributes , gl . DYNAMIC_DRAW ) ;
157- gl . drawElementsInstanced ( this . _gl . TRIANGLE_STRIP , 4 , gl . UNSIGNED_BYTE , 0 , this . _vertices . count ) ;
168+ gl . bufferData ( gl . ARRAY_BUFFER , vertices . attributes , gl . DYNAMIC_DRAW ) ;
169+ gl . drawElementsInstanced ( this . _gl . TRIANGLE_STRIP , 4 , gl . UNSIGNED_BYTE , 0 , vertices . count ) ;
158170 }
159171
160172 public handleResize ( ) : void {
@@ -167,6 +179,7 @@ export class RectangleRenderer extends Disposable {
167179
168180 private _updateCachedColors ( colors : ReadonlyColorSet ) : void {
169181 this . _bgFloat = this . _colorToFloat32Array ( colors . background ) ;
182+ this . _cursorFloat = this . _colorToFloat32Array ( colors . cursor ) ;
170183 }
171184
172185 private _updateViewportRectangle ( ) : void {
@@ -229,9 +242,76 @@ export class RectangleRenderer extends Disposable {
229242 }
230243 }
231244 vertices . count = rectangleCount ;
245+
246+ this . _updateCursor ( model ) ;
247+ }
248+
249+ private _updateCursor ( model : IRenderModel ) : void {
250+ const vertices = this . _verticesCursor ;
251+ const cursor = model . cursor ;
252+ if ( ! cursor || cursor . style === 'block' ) {
253+ vertices . count = 0 ;
254+ return ;
255+ }
256+
257+ let offset : number ;
258+ let rectangleCount = 0 ;
259+
260+ if ( cursor . style === 'bar' || cursor . style === 'blur' ) {
261+ // Left edge
262+ offset = rectangleCount ++ * INDICES_PER_RECTANGLE ;
263+ this . _addRectangleFloat (
264+ vertices . attributes ,
265+ offset ,
266+ cursor . x * this . _dimensions . device . cell . width ,
267+ cursor . y * this . _dimensions . device . cell . height ,
268+ cursor . style === 'bar' ? cursor . dpr * cursor . cursorWidth : cursor . dpr ,
269+ this . _dimensions . device . cell . height ,
270+ this . _cursorFloat
271+ ) ;
272+ }
273+ if ( cursor . style === 'underline' || cursor . style === 'blur' ) {
274+ // Bottom edge
275+ offset = rectangleCount ++ * INDICES_PER_RECTANGLE ;
276+ this . _addRectangleFloat (
277+ vertices . attributes ,
278+ offset ,
279+ cursor . x * this . _dimensions . device . cell . width ,
280+ ( cursor . y + 1 ) * this . _dimensions . device . cell . height - cursor . dpr ,
281+ cursor . width * this . _dimensions . device . cell . width ,
282+ cursor . dpr ,
283+ this . _cursorFloat
284+ ) ;
285+ }
286+ if ( cursor . style === 'blur' ) {
287+ // Top edge
288+ offset = rectangleCount ++ * INDICES_PER_RECTANGLE ;
289+ this . _addRectangleFloat (
290+ vertices . attributes ,
291+ offset ,
292+ cursor . x * this . _dimensions . device . cell . width ,
293+ cursor . y * this . _dimensions . device . cell . height ,
294+ cursor . width * this . _dimensions . device . cell . width ,
295+ cursor . dpr ,
296+ this . _cursorFloat
297+ ) ;
298+ // Right edge
299+ offset = rectangleCount ++ * INDICES_PER_RECTANGLE ;
300+ this . _addRectangleFloat (
301+ vertices . attributes ,
302+ offset ,
303+ ( cursor . x + cursor . width ) * this . _dimensions . device . cell . width - cursor . dpr ,
304+ cursor . y * this . _dimensions . device . cell . height ,
305+ cursor . dpr ,
306+ this . _dimensions . device . cell . height ,
307+ this . _cursorFloat
308+ ) ;
309+ }
310+
311+ vertices . count = rectangleCount ;
232312 }
233313
234- private _updateRectangle ( vertices : IVertices , offset : number , fg : number , bg : number , startX : number , endX : number , y : number ) : void {
314+ private _updateRectangle ( vertices : Vertices , offset : number , fg : number , bg : number , startX : number , endX : number , y : number ) : void {
235315 $isDefault = false ;
236316 if ( fg & FgFlags . INVERSE ) {
237317 switch ( fg & Attributes . CM_MASK ) {
0 commit comments