Richard Suchenwirth 2001-11-12 - XPM (X Pixmap) is a text file format in X11 to specify color images like icons with one or more characters per pixel, which are resolved in a color map at beginning of file. Here's some old code of mine which scans an XPM file into a photo image - might need some tuning before it joins the strimj - string image routines family, but as it was requested on c.l.t., here you go...
proc image:fromXpm {fn} { set f [open $fn r] set stage 0; # 0:dimensions 1:colors 2:data set ncol 0; set y 0 set bg white ;# or whatever while {![eof $f]} { gets $f line if {[regexp {\"([^\"]+)\"} $line -> cont]} { switch $stage { 0 { foreach {w h ncols nbytes} $cont break set im [image create photo] $im put #FFF -to 0 0 $w $h $im configure -width $w -height $h ;# store read width & height, [MSW] incr stage; continue } 1 { set c [string range $cont 0 [expr $nbytes-1]] regexp "\[ \t\]c (.+)" $cont -> col if {[regexp {[Nn]one} $col]} {set col $bg} if [catch {winfo rgb . $col}] { set col [lindex $col 0] } set color($c) $col incr ncol if {$ncol>=$ncols} {incr stage} continue } 2 { set t {} foreach i [string:split $cont $nbytes] { lappend t $color($i) } catch { $im put [list $t] -to 0 $y [expr $w] [expr $y+1] } incr y } } } } close $f return $im }
The following should rather be called "string:stride"... it breaks a string into substrings of length n
proc string:split {s n} { if {$n==1} { return [split $s ""] } elseif {$n==2} { set t {} foreach {i j} [split $s ""] {lappend t $i$j} return $t } else {error "string:split -- bad splitter $n (must be 1 or 2)"} }