2025-06-03 21:53:21 +02:00
const std = @import ( " std " ) ;
const Canvas = @import ( " canvas.zig " ) . Canvas ;
const value = @import ( " value.zig " ) ;
const Value = value . Value ;
const Vm = @import ( " vm.zig " ) ;
fn notAScribble ( vm : * Vm , val : Value ) Vm . Error {
return vm . throw (
" the brush returned a {s}, which cannot be drawn. return a scribble (e.g. fill, stroke, list) instead " ,
. { val . typeName ( ) } ,
) ;
}
fn renderRec ( vm : * Vm , canvas : * Canvas , val : Value , depth : usize , max_depth : usize ) ! void {
if ( depth > max_depth ) {
return vm . throw (
" the brush returned a scribble that's nested too deep ({} levels). try generating lists that aren't as deep using the (map (range min max) f) idiom, or flatten your lists using the flatten function " ,
. { max_depth } ,
) ;
}
if ( val ! = . ref ) return notAScribble ( vm , val ) ;
switch ( val . ref . * ) {
. scribble = > {
try canvas . begin ( ) ;
switch ( val . ref . scribble . shape ) {
. point = > | point | try canvas . line ( point , point ) ,
. line = > | line | try canvas . line ( line . start , line . end ) ,
. rect = > | rect | try canvas . rect ( rect . top_left , rect . size ) ,
. circle = > | circle | try canvas . circle ( circle . center , circle . radius ) ,
}
switch ( val . ref . scribble . action ) {
. stroke = > | stroke | try canvas . stroke ( value . rgbaTo8 ( stroke . color ) , stroke . thickness ) ,
. fill = > | fill | try canvas . fill ( value . rgbaTo8 ( fill . color ) ) ,
}
} ,
. list = > {
for ( val . ref . list ) | nested | {
try vm . consumeFuel ( & vm . fuel , 1 ) ;
try renderRec ( vm , canvas , nested , depth + 1 , max_depth ) ;
}
} ,
. shape = > {
return vm . throw ( " the brush returned a bare shape, which cannot be drawn. try wrapping your shape in a fill or a stroke: (fill #000 <shape>) " , . { } ) ;
} ,
else = > return notAScribble ( vm , val ) ,
}
}
pub fn render ( vm : * Vm , canvas : * Canvas , max_depth : usize ) ! void {
2025-06-04 00:28:21 +02:00
const val = vm . stack [ vm . stack_top - 1 ] ;
2025-06-03 21:53:21 +02:00
try renderRec ( vm , canvas , val , 0 , max_depth ) ;
}