I needed to build a series of regular bitmaps such as a row of 10 4x4 squares and a 10x10 grid of 4x4 squares. I could have used a bitmap editor but it would be labor-intensive and I preferred to generate the bitmap programmatically. A single proc is used to convert strings of 1's and 0's into bitmaps.
The width of the bitmap is defined by the length of the first argument. Successive lines are filled with zeros if necessary to match the length.
proc gen_bitmap { args } { set height [ llength $args ] set width [ string length [ lindex $args 0 ]] set setbx "#define bullet_width $width\n#define bullet_height $height \n" append setbx "static char bullet_bits = \{\n" foreach arg $args { if { [ regexp {L([0-9]+)} $arg dummy argnum ] } { set arg [ lindex $args $argnum-1 ] } puts "$arg" set i 0 set res 0 append arg [ string repeat 0 [ expr $width - [ string length $arg ]]] append arg "0000000" foreach ch [ split $arg "" ] { if { $ch } { incr res [ expr 1 << $i % 8 ] # puts "ch $ch $i $res" } incr i if { ! ( $i % 8 ) } { lappend bits [ format "0x%02x" $res ] set res 0 } } } append setbx [ join $bits ", " ] append setbx "\}" return $setbx }
catch { destroy .bitmaps } toplevel .bitmaps wm title .bitmaps Bitmaps canvas .bitmaps.c -width 400 -height 300 -bg white pack .bitmaps.c set C .bitmaps.c set bm_1k_s [ gen_bitmap \ 00111111111111111111111111111111111111111111111111100 \ 01111111111111111111111111111111111111111111111111110 \ 11111111111111111111111111111111111111111111111111111 \ 11111111111111111111111111111111111111111111111111111 \ 11111111111111111111111111111111111111111111111111111 \ 11111111111000011111100000001111000000001111111111111 \ 11111111110000011111110000011111100000011111111111111 \ 11111111100000011111111000011111111000011111111111111 \ 11111111000000011111111000011111110000111111111111111 \ 11111111111000011111111000011111100001111111111111111 \ 11111111111000011111111000011111000011111111111111111 \ 11111111111000011111111000011110000111111111111111111 \ 11111111111000011111111000011100001111111111111111111 \ 11111111111000011111111000011000011111111111111111111 \ 11111111111000011111111000000001111111111111111111111 \ 11111111111000011111111000000001111111111111111111111 \ 11111111111000011111111000011000011111111111111111111 \ 11111111111000011111111000011100001111111111111111111 \ 11111111111000011111111000011110000111111111111111111 \ 11111111111000011111111000011111000011111111111111111 \ 11111111111000011111111000011111100001111111111111111 \ 11111111111000011111111000011111110000111111111111111 \ 11111111110000001111111000011111111000001111111111111 \ 11111111100000001111111000011111100000001111111111111 \ 11111111000000000111110000000111100000000011111111111 \ 11111111111111111111111111111111111111111111111111111 \ 11111111111111111111111111111111111111111111111111111 \ 11111111111111111111111111111111111111111111111111111 \ 01111111111111111111111111111111111111111111111111110 \ 00111111111111111111111111111111111111111111111111100 \ ] image create bitmap bm_1k_red -data $bm_1k_s -fore red $C create image 50 25 -image bm_1k_red image create bitmap bm_1k_blue -data $bm_1k_s -fore blue $C create image 150 25 -image bm_1k_blue # This generates 10 rows of 10 diamonds set pat1 "00100" set pat2 "01110" set pat3 "11111" set line1 [ string repeat $pat1 10 ] set line2 [ string repeat $pat2 10 ] set line3 [ string repeat $pat3 10 ] # L1 is replaced by the 1st arg, L2 by the second arg, etc. set bm_diamonds [ gen_bitmap \ $line1 $line2 $line3 $line2 $line1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 ] image create bitmap diamonds_blue -data $bm_diamonds -fore blue $C create image 50 100 -anchor n -image diamonds_blue $C create image 150 150 -anchor n -image diamonds_blue # 4 rows of 10 diamonds set bm_diamonds [ gen_bitmap \ $line1 $line2 $line3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 \ L1 L2 L3 L2 L1 ] image create bitmap diamonds_red -data $bm_diamonds -fore red $C create image 150 100 -anchor n -image diamonds_red $C create image 50 150 -anchor n -image diamonds_red # 24 bitmaps - each a row of 1 to 24 4x4 squares set curbase 24 for { set i 1 } { $i <= $curbase } { incr i } { set bmi [ string repeat "11110" $i ] set zri [ string repeat "00000" $i ] set bmdata [ gen_bitmap $bmi $bmi $bmi $bmi $zri ] image create bitmap blocks$i -data $bmdata -fore blue } for { set i 1 } { $i <= $curbase } { incr i } { $C create image 200 [ expr $i * 10 + 10 ] -anchor w -image blocks$i }