@@ -2,17 +2,11 @@ use std::{
22 fmt:: { self , Formatter } ,
33 mem,
44 ops:: RangeInclusive ,
5- sync:: atomic:: AtomicBool ,
65} ;
76
87use line_drawing:: { Bresenham , BresenhamCircle } ;
98use parking_lot:: Mutex ;
10- use tracing:: { debug, info, trace} ;
11-
12- use crate :: {
13- SIM_APP , SimEvent ,
14- display:: { SimDisplay , SimDisplayWindow } ,
15- } ;
9+ use tracing:: trace;
1610
1711pub const WIDTH : u32 = 480 ;
1812pub const HEIGHT : u32 = 272 ;
@@ -26,13 +20,13 @@ pub const HEADER_COLOR: u32 = 0x00_99_CC;
2620/// The canvas instance used by user code.
2721pub static CANVAS : Mutex < Canvas > = Mutex :: new ( Canvas :: new ( ) ) ;
2822
29- /// Indicates whether the render thread should automatically render the [user canvas](CANVAS).
30- pub static AUTORENDER : AtomicBool = AtomicBool :: new ( true ) ;
31-
3223#[ derive( Debug , Clone , Copy ) ]
3324pub struct CanvasState {
3425 pub fg_color : u32 ,
3526 pub bg_color : u32 ,
27+ // This doesn't seem to affect any operations, but we store it so we can return it from
28+ // `vexDisplayPenSizeGet`.
29+ pub pen_size : u32 ,
3630 clip_region : Rect ,
3731}
3832
@@ -45,6 +39,10 @@ impl CanvasState {
4539 region. clip_to ( & Rect :: FULL_CLIP ) ;
4640 self . clip_region = region;
4741 }
42+
43+ pub fn clip_region ( & self ) -> Rect {
44+ self . clip_region
45+ }
4846}
4947
5048pub struct Canvas {
@@ -59,6 +57,7 @@ impl Canvas {
5957 fg_color : DEFAULT_FG_COLOR ,
6058 bg_color : DEFAULT_BG_COLOR ,
6159 clip_region : Rect :: FULL_CLIP ,
60+ pen_size : 1 ,
6261 } ;
6362
6463 Self {
@@ -96,7 +95,7 @@ impl Canvas {
9695 let clip = self . state . clip_region ;
9796
9897 // Is the line above or below the clip region?
99- if !( clip. 0 . y ..= clip. 1 . y ) . contains ( & y) {
98+ if !( clip. 0 . y ..clip. 1 . y ) . contains ( & y) {
10099 return ;
101100 }
102101
@@ -117,7 +116,7 @@ impl Canvas {
117116 let clip = self . state . clip_region ;
118117
119118 // Is the line left or right of the clip region?
120- if !( clip. 0 . x ..= clip. 1 . x ) . contains ( & x) {
119+ if !( clip. 0 . x ..clip. 1 . x ) . contains ( & x) {
121120 return ;
122121 }
123122
@@ -132,6 +131,14 @@ impl Canvas {
132131 }
133132 }
134133
134+ pub fn draw_line ( & mut self , start : Point , end : Point ) {
135+ trace ! ( ?start, ?end, "line" ) ;
136+
137+ for ( x, y) in Bresenham :: new ( ( start. x , start. y ) , ( end. x , end. y ) ) {
138+ self . set_pixel ( Point { x, y } ) ;
139+ }
140+ }
141+
135142 pub fn fill_rect ( & mut self , mut bounds : Rect ) {
136143 trace ! ( color = %Hex ( self . state. fg_color) , ?bounds, "fill rect" ) ;
137144
@@ -174,7 +181,7 @@ impl Canvas {
174181 let mut lines = vec ! [ ( center. x, center. x) ; num_lines as usize ] ;
175182
176183 for ( dx, i) in BresenhamCircle :: new ( 0 , radius as i32 , radius as i32 ) {
177- let x = center. x as i32 + dx;
184+ let x = center. x + dx;
178185
179186 // The tops and bottoms of circles have several points on the same line, so only record
180187 // the leftmost or rightmost point for our horizontal line.
@@ -205,13 +212,27 @@ impl Canvas {
205212
206213 let clip = self . state . clip_region ;
207214
208- for ( x, y) in BresenhamCircle :: new ( center. x as i32 , center. y as i32 , radius as i32 ) {
215+ for ( x, y) in BresenhamCircle :: new ( center. x , center. y , radius as i32 ) {
209216 if ( Point { x, y } ) . is_inside ( & clip) {
210217 self . write_pixel ( Point { x, y } , self . state . fg_color ) ;
211218 }
212219 }
213220 }
214221
222+ pub unsafe fn copy_rect ( & mut self , mut bounds : Rect , source : * const u32 , stride : usize ) {
223+ trace ! ( ?bounds, ?source, ?stride, "copy rect" ) ;
224+ bounds. clip_to ( & self . state . clip_region ) ;
225+
226+ for ( row_idx, row) in ( bounds. 0 . y ..bounds. 1 . y ) . enumerate ( ) {
227+ for ( col_idx, col) in ( bounds. 0 . x ..bounds. 1 . x ) . enumerate ( ) {
228+ let dest_idx = row * WIDTH as i32 + col;
229+ let source_idx = row_idx * stride + col_idx;
230+ let pixel = unsafe { source. add ( source_idx) . read ( ) } ;
231+ self . buffer [ dest_idx as usize ] = pixel;
232+ }
233+ }
234+ }
235+
215236 pub fn draw_header ( & mut self ) {
216237 self . state . fg_color = HEADER_COLOR ;
217238 self . fill_rect ( Rect :: HEADER_CLIP ) ;
@@ -247,8 +268,8 @@ pub struct Rect(pub Point, pub Point);
247268
248269impl Rect {
249270 pub const FULL_CLIP : Self = Rect :: new ( 0 , 0 , WIDTH as i32 , HEIGHT as i32 ) ;
250- pub const USER_CLIP : Self = Rect :: new ( 0 , HEADER_HEIGHT as i32 , WIDTH as i32 , HEIGHT as i32 ) ;
251- pub const HEADER_CLIP : Self = Rect :: new ( 0 , 0 , WIDTH as i32 , HEADER_HEIGHT as i32 ) ;
271+ pub const USER_CLIP : Self = Rect :: new ( 0 , HEADER_HEIGHT , WIDTH as i32 , HEIGHT as i32 ) ;
272+ pub const HEADER_CLIP : Self = Rect :: new ( 0 , 0 , WIDTH as i32 , HEADER_HEIGHT ) ;
252273
253274 pub const fn new ( mut x0 : i32 , mut y0 : i32 , mut x1 : i32 , mut y1 : i32 ) -> Self {
254275 if x0 > x1 {
0 commit comments