@@ -23,15 +23,15 @@ module.exports = term;
23
23
function term ( opts ) {
24
24
if ( ! opts ) opts = { } ;
25
25
var stream = opts . stream || process . stdout ;
26
- var pixel = opts . pixel || ' ' ;
27
- var pixelHeight = 1 ;
28
- var pixelWidth = pixel . length ;
26
+ var small = ! ! opts . small ;
27
+ var pixelHeight = small ? 0.5 : 1 ;
28
+ var pixelWidth = small ? 1 : 2 ;
29
29
30
30
// create <canvas> instance
31
31
var canvas = new Canvas ( stream . columns / pixelWidth , stream . rows / pixelHeight ) ;
32
32
canvas . render = render ;
33
33
canvas . stream = stream ;
34
- canvas . pixel = pixel ;
34
+ canvas . small = small ;
35
35
36
36
// cached "context"
37
37
canvas . renderCtx = canvas . getContext ( '2d' ) ;
@@ -54,6 +54,9 @@ function term (opts) {
54
54
function render ( ) {
55
55
var cursor = ansi ( this . stream ) ;
56
56
57
+ // retain calls in memory until `flush()` call
58
+ cursor . buffer ( ) ;
59
+
57
60
// erase everything on the screen
58
61
cursor . eraseData ( 2 ) ;
59
62
@@ -62,32 +65,90 @@ function render () {
62
65
63
66
// render the current <canvas> contents to the TTY
64
67
var ctx = this . renderCtx ;
68
+ var small = this . small ;
65
69
var w = this . width ;
66
70
var h = this . height ;
67
71
var alphaThreshold = 0 ;
68
- var pixel = this . pixel ;
69
72
70
73
var data = ctx . getImageData ( 0 , 0 , w , h ) . data ;
71
-
72
- for ( var i = 0 , l = data . length ; i < l ; i += 4 ) {
73
-
74
- if ( ( i / 4 | 0 ) % w === 0 ) {
75
- // beginning of the row
76
- cursor . bg . reset ( ) ;
77
- cursor . write ( '\n' ) ;
74
+ var r , g , b , alpha ;
75
+ var topBlank , bottomBlank ;
76
+ var i = 0 ;
77
+
78
+ for ( var y = 0 ; y < h ; y ++ ) {
79
+
80
+ // beginning of the row
81
+ cursor . bg . reset ( ) ;
82
+ cursor . write ( '\n' ) ;
83
+
84
+ for ( var x = 0 ; x < w ; x ++ ) {
85
+
86
+ // in `small` mode, we have to render 2 rows at a time, where the top row
87
+ // is the background color, and the bottom row is the foreground color
88
+ i = ( ( y * w ) + x ) * 4 ;
89
+
90
+ // top row
91
+ r = data [ i ] ;
92
+ g = data [ i + 1 ] ;
93
+ b = data [ i + 2 ] ;
94
+ alpha = data [ i + 3 ] ;
95
+
96
+ if ( alpha > alphaThreshold ) {
97
+ cursor . bg . rgb ( r , g , b ) ;
98
+ topBlank = false ;
99
+ } else {
100
+ cursor . bg . reset ( ) ;
101
+ topBlank = true ;
102
+ }
103
+
104
+ if ( small ) {
105
+ // bottom row
106
+
107
+ // go to the next row
108
+ i = ( ( ( y + 1 ) * w ) + x ) * 4 ;
109
+
110
+ r = data [ i ] ;
111
+ g = data [ i + 1 ] ;
112
+ b = data [ i + 2 ] ;
113
+ alpha = data [ i + 3 ] ;
114
+
115
+ if ( alpha > alphaThreshold ) {
116
+ cursor . fg . rgb ( r , g , b ) ;
117
+ bottomBlank = false ;
118
+ } else {
119
+ cursor . fg . reset ( ) ;
120
+ bottomBlank = true ;
121
+ }
122
+ }
123
+
124
+ if ( small && bottomBlank && ! topBlank ) {
125
+ // swapping fg and bg for this pixel since we're gonna use a "top
126
+ // half" instead of the usual "bottom half"
127
+ i = ( ( y * w ) + x ) * 4 ;
128
+
129
+ // top row
130
+ r = data [ i ] ;
131
+ g = data [ i + 1 ] ;
132
+ b = data [ i + 2 ] ;
133
+
134
+ cursor . bg . reset ( ) ;
135
+ cursor . fg . rgb ( r , g , b ) ;
136
+ }
137
+
138
+ // write the pixel
139
+ if ( ! small ) {
140
+ cursor . write ( ' ' ) ;
141
+ } else if ( topBlank && bottomBlank ) {
142
+ cursor . write ( ' ' ) ;
143
+ } else if ( bottomBlank ) {
144
+ cursor . write ( '▀' ) ;
145
+ } else {
146
+ cursor . write ( '▄' ) ;
147
+ }
78
148
}
79
149
80
- var r = data [ i ] ;
81
- var g = data [ i + 1 ] ;
82
- var b = data [ i + 2 ] ;
83
- var alpha = data [ i + 3 ] ;
84
-
85
- if ( alpha > alphaThreshold ) {
86
- cursor . bg . rgb ( r , g , b ) ;
87
- } else {
88
- cursor . bg . reset ( ) ;
89
- }
90
-
91
- cursor . write ( pixel ) ;
150
+ if ( small ) y ++ ;
92
151
}
152
+
153
+ cursor . flush ( ) ;
93
154
}
0 commit comments