%!PS % Auto precision bitmap exploration % =================================== % by Don Lancaster %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Enter filenames and info into the DATA section near the end! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright c 2003 by Don Lancaster & Synergetics, Box 809, Thatcher, AZ, 85552 % (928) 428-4073 Email: don@tinaja.com Website: http://www.tinaja.com % Consulting services available http://www.tinaja.com/info01.html % All commercial rights and all electronic media rights ~fully~ reserved. % Linking usually welcome. Reposting expressly forbidden. Version 1.1 % Auto precision bitmap initial exploration % ========= % IMPORTANT NOTE: Don Lancaster's file gonzo.ps is recommended but not % required for this program. % After obvious location mods, uncomment ONE of the following two lines: % (C:\\Documents and Settings\\don\\Desktop\\gonzo\\gonzo.ps) run % use internal % (A:\\gonzo.ps) run % use external gonzo % NOTE THAT ALL PS FILENAME STRINGS !!!DEMAND!!! DOUBLE REVERSE SLASHES. % GONZO20A Guru Gonzo PostScript power tools (Interim release) % Includes gonzo justification and layout utilities. % Copyright c 1990, 1996, 2001 by Don Lancaster and Synergetics, Box 809, % Thatcher Arizona, 5552 (928) 428-4073 don@tinaja.com support % via http://www.tinaja.com All commercial rights and all electronic % media rights **FULLY** reserved. Reposting is expressly forbidden. % ======== /guru { gonzo begin ps.util.1 begin printerror nuisance begin} def % guru % activate gonzo utilities % ========= % gonzo excerpts /mt {moveto} store /black {0 setgray} store % timing utilities. use stopwatchon and stopwatchoff for simple % one shot timing. For multiple time totals, use resettimer % starttimer stoptimer ... starttimer stoptimer reporttimer /stopwatchoff {stoptimer reporttimer} def % for single shots /stopwatchon {resettimer starttimer} def % for single shots /reporttimer {mytime 1000 div (\rElapsed time: ) print 20 string cvs print ( seconds.\r) print flush} def % to host /resettimer {/mytime 0 def} def % reset timer /starttimer {usertime /mytimenow exch def} def % add to time so far /stoptimer {usertime mytimenow sub /mytime exch mytime add def} def % for multiple timing intervals %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % FONT CHARACTER AND ARRAY CREATION ROUTINES % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % /setfontfamily allows more than one root font per session. the /fontcount % counter is used to keep track of generated font libraries. Gonzo fonts % not appropriate here. At present, each font family should only be used ONCE. /setfontfamily {/fontcount where % is this the first font? {pop /fontcount fontcount % no, increment fountcount 1 add store} {/fontcount 0 store} ifelse % yes, initialize counter findfont 100 scalefont setfont % 100 points hard coded } store % /setbmsize initializes a font pattern library for a given size and font. % If reused, it selects an older font pattern library. A font pattern library % has a name of form /fxwyhz where x is the fontcount, y is the requested % bitmap height and z is the requested width of the letter "A" in the bitmap. /setbmsize { /yy exch store % save global pixel height /xx exch store % save global pixel width (f) fontcount 20 string cvs mergestr % create name for fpl array (w) xx 20 string cvs mergestr mergestr % (h) yy 20 string cvs mergestr mergestr cvn dup /cfpln exch store % save name of current fpl array where not { % does this fpl name exist? cfpln mark 256 {null} repeat % create new array ] store cfpln load /cfpl exch store % define current fpl } if definechara % define (A) character } store % /findcharboundaries slides bounding box in till an infill hit is found. % Note: space must be excluded. currently using a quarter pixel scan. % this can be increased if response time is too slow. Note that character is at 100,100 /findcharboundaries { /reallyexit false store % begin left boundary 90 0.25 rpos 100 add { /clb exch store % scnning to right 0 1 200 {/yy1 exch store % check all vertical pixels clb yy1 infill {/reallyexit true store exit} if % till ink is found } for reallyexit {exit} if } for /clb clb 0.25 sub store % adjust to no ink /reallyexit false store % begin right boundaryrpos 0.25 rpos 100 add -0.25 90 { /crb exch store % scnning left 0 1 200 {/yy2 exch store % check all vertical pixels crb yy2 infill {/reallyexit true store exit} if % till ink is found } for reallyexit {exit} if } for /crb crb 0.25 add store % adjust to no ink /reallyexit false store % begin top boundary 200 -0.25 100 {/ctb exch store % scanning down -90 1 rpos 100 add {/xx1 exch store % check all horizontal pixels xx1 ctb infill {/reallyexit true store exit} if % till ink is found } for reallyexit {exit} if } for /ctb ctb 0.25 add store % adjust to no ink /reallyexit false store % begin bottom boundary 0 0.25 200 {/cbb exch store % scanning up 90 1 rpos 100 add {/xx2 exch store % check all horizontal pixels xx2 cbb infill {/reallyexit true store exit} if % till ink is found } for reallyexit {exit} if } for /cbb cbb 0.25 sub store % adjust to no ink adjustcharboundaries % reduce bounding box for curvies } store % /adjustcharboundaries shrinks the bounding box to put the curvies on the outside % value of /shrinkfactor is presently internal. /adjustcharboundaries { /clb clb crb clb sub shrinkfactor mul add store % and adjust /crb crb crb clb sub shrinkfactor mul sub store crb clb sub /cwide exch store % find character width /ctb ctb ctb cbb sub shrinkfactor mul sub store % and adjust /cbb cbb ctb cbb sub shrinkfactor mul add store ctb cbb sub /chigh exch store % find character height } store % /definechara initially defines character (A) and allows saving of % global h and v default sizes... /definechara { gsave newpath % make scratch space /char (A) store char stringwidth pop % find character width and save /rpos exch store findcharboundaryvalues % find values of clb crb ctb cbb /gcwide cwide store % save global width of A reference /gchigh chigh store % save global height of A reference /gctb ctb store % save global top of A reference (A) makeorgetfontarray % make or get the font array for "A" pop % do not need actual array this time createspacechar % create space character chrs32 grestore } store % /findcharboundaryvalues finds clb crb ctb cbb cwide and chigh for the selected character. /findcharboundaryvalues { newpath % make scratch space 100 100 mt % position inside possible clip space gsave black char show grestore char stringwidth pop % find character width and save /rpos exch store char false charpath % get path for character findcharboundaries % find values of clb crb ctb cbb false { % use for debug gsave newpath 0.5 0.5 0 setrgbcolor line1 % temp draw cropped bounding box clb cbb mt 0 ctb cbb sub rlineto crb clb sub 0 rlineto 0 cbb ctb sub rlineto clb crb sub 0 rlineto stroke grestore } if } store % /makeorgetfontarray sees if the character has been generated, generates it if % needed, and retrives it as an array. /makeorgetfontarray {dup 0 get /chrs exch store % save char position /char exch store % save char string cfpl chrs get type /nulltype % has character been built? eq {addnewchar} if % no, build it cfpl chrs get % now get it } store % /addnewchar unconditionally adds a new character to the current cfpl bitmap array % have variables % gcwide gchigh gctb % clb crb ctb cbb % xx yy /addnewchar { char print flush findcharboundaryvalues % find edge values for new character gctb ctb sub % top position versus "A"? gchigh div % fraction of "A" character height? yy mul % times "A" character vertical pixels round cvi % gchigh mul gchigh div round cvi % should be zero for caps /sss exch store % save suppression sss crb clb sub gcwide div % width versus "A"? xx mul round cvi % should equal A for most caps /xxx exch store % pixel width needed ctb cbb sub gchigh div % height versus "A"? yy mul round cvi % should equal A for most caps /yyy exch store % pixel height needed ctb cbb sub yyy div % find whole pixel y increment dup /bigyinc exch store % and save linsamps div /lilyinc exch store % and sample y increment crb clb sub xxx div % find whole pixel x increment dup /bigxinc exch store % and save linsamps div /lilxinc exch store % and sample x increment reallyaddnewchar % add char with size known } store % /reallyaddnewchar uses {xxx yyy sss bigyinc lilyinc bigxinc lilxinc to create the % font character and store it in cfpl /reallyaddnewchar { /sss sss 2 add store % lc "h" possible padding sss 0 le {/sss 0 store} if % adjust minimum width mark % start array sss { mark xxx { 1 } repeat ] } % create suppression lines repeat yyy 1 sub -1 0 {bigyinc mul cbb add % add to shrunk top /curvv exch store % go downhill mark 0 1 xxx 1 sub {bigxinc mul clb add % add to shrunk left /curhh exch store averagepixels % average the pixels } for % each row of pixels ] } for % needed number of rows ] cfpl exch chrs exch put % place in array % showpage % used in debug } store % /averagepixels uses infill to sample a pixel linesamps squared times to come % up with its average brightness. base of character is curhh and curvv... /averagepixels { 0 % initial something to add to 0 1 linsamps 1 sub { % start double loop /intypos exch store 0 1 linsamps 1 sub { /intxpos exch store curhh lilxinc 2 div add % calculate x position lilxinc intxpos mul add % move to start curvv lilyinc 2 div add % calculate y position lilyinc intypos mul add false { % make true to show sample dots gsave 1 0 0 setrgbcolor 2 copy moveto gsave 2.5 dup scale dot grestore grestore } if infill {0}{1} ifelse add } for % for each h sample } for % for each row of samples linsamps dup mul div % calculate average } bind store % temp % /createspacechar initially creates the space character /createspacechar { xxx spacecharwidth mul round % adjust space width cvi /spacewide exch store mark yyy { % 1 = white or use old [ spacewide {1} repeat ] } repeat ] cfpl exch 32 exch put } store %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % BITMAP TYPEWRITER ROUTINES % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [yourarray] makestring converts an array to a string... /makestring {dup length string dup % new string of right size /NullEncode filter % make a file out of string 3 -1 roll {1 index exch write} forall pop } def % mergestr merges the two top stack strings into one top stack string /mergestr {2 copy length exch length add string dup dup 4 3 roll 4 index length exch putinterval 3 1 roll exch 0 exch putinterval} def % /makeclonebitmap sets up a black array of bitmap row strings. The LOWEST number % is at the BOTTOM of the .BMP bitmap. This can be sped up by reading % the generated array as a file. Note that BLUE goes first in the BMP data quads. /makeclonebitmaps { /xbstring mark 120 hbits 1 sub {dup} repeat ] makestring store % a string of "x" values /redmap mark vbits {xbstring dup length string cvs} repeat ] store /greenmap mark vbits {xbstring dup length string cvs} repeat ] store /bluemap mark vbits {xbstring dup length string cvs} repeat ] store } def % /setbackA through /setbackD places background colors in the clone bitmap. % /setbackA is the bottom quarter, presently hardwired to 400x400. /setbackA {0 setback} store % bottom 0-99 /setbackB {100 setback} store % lower quardant 100-199 /setbackC {200 setback} store % upper quardant 200-299 /setbackD {300 setback} store % top 300-399 /setback { /posnstart exch store % save initial position /redval curcolor 0 get store % grab current colors /greenval curcolor 1 get store /blueval curcolor 2 get store (\n\n\ncurcolor is ) print flush curcolor == /redline mark 1400 {redval} repeat ] % make color string for red line makestring store /greenline mark 1400 {greenval} repeat ] % make color string for green line makestring store /blueline mark 1400 {blueval} repeat ] % make color string for blue line makestring store posnstart 1 posnstart 99 add % start loading loop {/curpos exch store redmap curpos redline 1400 string cvs put greenmap curpos greenline 1400 string cvs put bluemap curpos blueline 1400 string cvs put } for } store % /writebitmap creates the actual bitmap from the clone string arrays /writebitmap { (\nWriting final bitmp to disk...) print flush stopwatchon /targetbmpfilename targetfilenameprefix targetfilename mergestr def targetbmpfilename (w+) file /writefile exch def % make a .BMP file to write writeheader % write defined .BMP header writebitmapx % write BGRX bitmap writefile closefile % close & complete file stopwatchoff } def % /writeheader creates the header in standard .BMP format The format can be found at % http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html and elsewhere on the web. /writeheader { (BM) ws % ASCI BM identifier /filesize hbits vbits mul 3 mul 54 add cvi def % calculate file length filesize 256 mod 256 mod dup strx exch 0 exch put strx ws % LSB filesize exch sub 256 mod strx exch 0 exch put strx ws % next lsb filesize 65536 idiv strx exch 0 exch put strx ws % next ldb writenull % msb writenull writenull % reserved 2 bytes writenull writenull % reserved 2 bytes 54 strx exch 0 exch put strx ws % offset lsb writenull writenull writenull % high offset bytes 40 strx exch 0 exch put strx ws % begin infoheader (size) writenull writenull writenull hbits 256 mod strx exch 0 exch put strx ws % horizontal bytes lsb hbits 256 idiv strx exch 0 exch put strx ws % horizontal bytes lsb writenull writenull % high offset bytes vbits 256 mod strx exch 0 exch put strx ws % vertical bytes lsb vbits 256 idiv strx exch 0 exch put strx ws % vertical bytes lsb writenull writenull % high offset bytes 1 strx exch 0 exch put strx ws % planes = 1 writenull % and msb 24 strx exch 0 exch put strx ws % bits per pixel = 24 writenull % and msb writenull writenull writenull writenull % no compression writenull writenull writenull writenull % 0 size if no compression 0 strx exch 0 exch put strx ws writenull writenull writenull % writenull % 0 h display pixels per meter 0 strx exch 0 exch put strx ws writenull writenull writenull % writenull % 0 v display pixels per meter writenull writenull writenull writenull % BiBitCount for color count writenull writenull writenull writenull % All colors are important } def % /writebitmap writes the bitmap portion to the .BMP file /writebitmapx { 0 1 vbits 1 sub {/vv exch store % working backwards from bottom /curred redmap vv get store % get current red row array /curgreen greenmap vv get store % get current green row array /curblue bluemap vv get store % get current blue row array 0 1 hbits 1 sub {/hh exch store % save pixel position curblue hh 1 getinterval ws % grab three pixels BLUE first curgreen hh 1 getinterval ws % grab three pixels then GREEN curred hh 1 getinterval ws % grab three pixels then RED } for } for } def % /ws is a housekeeping utility... /ws {writefile exch writestring} def % file writing utility /strx (X) def /writenull {0 strx exch 0 exch put strx ws } def % /setgraystring places a string of true antialiased characters onto the bitmap... % All characters build from TOP DOWN to handle descenders. /setgraystring {/str exch store % save the string repositioncheck % 0 0 = do not reposition /ypos1 exch store % save the yposition /xpos1 exch store % save the xposition /xpos xpos1 store % set initial LEFT position /ypos ypos1 store % set initial TOP position 0 1 str length 1 sub % for each character in string {/kk exch store str kk 1 getinterval % get the current character /curchar1 exch store % and save adjustlocalkerning % is local kerning needed? {curchar1 makeorgetfontarray % get or build char array setgraychar } if % map character into cfpl } for } def % /repositioncheck looks for a 0 0 positioning, and uses the old xpos and y pos % instead. /repositioncheck {2 copy mul 0 eq % use old currentpoint if 0 0 {pop pop xpos ypos} if} store % /adjustlocalkerning looks for kern+char or kern-char characters, then adjusts % position, returning false if kerned, true otherwise /adjustlocalkerning { true curchar1 0 get kern+char % rightkern? eq {/xpos xpos 1 % move one pixel to right add store pop false} if % no real character needed curchar1 0 get kern-char % rightkern? eq {/xpos xpos 1 % move one pixel to right sub store pop false} if % no real character needed } store % /setgraychar accepts xpos ypos (x) and places the character into the bitmap string. % Or else adjusts for a carriage return and linefeed /setgraychar { curchar1 0 get dup % test for LF or CR 10 eq exch 13 eq or {pop docr} % do LF or CR, dump array {setgraychar1} ifelse % otherwise set character } def % /setgraychar1 sets the actual character matrix into the cfpl array after % local kerning and crlf have been dealt with. Enters with char matrix on stack % Note that blue goes first in the bitmap. /setgraychar1 {/curmat1 exch store % save current character matrix curmat1 length /jj exch store % save pixels high curmat1 0 get length /ii % save pixels wide exch store 0 1 jj 1 sub {/jjj exch store % save y pixel offset 0 1 ii 1 sub {/iii exch store % save x pixel offset % blue first bluemap ypos jjj sub get % find old blue pixel xpos iii add get dup curcolor 2 get % find full new blue pixel sub % find difference curmat1 jjj get iii get 1 sub % find alpha fraction mul add % calculate new blue pixel round cvi bluemap ypos jjj sub get % and replace exch xpos iii add exch put % then green greenmap ypos jjj sub get % find old green pixel xpos iii add get dup curcolor 1 get % find full new blue pixel sub % find difference curmat1 jjj get iii get 1 sub % find alpha fraction mul add % calculate new green pixel round cvi greenmap ypos jjj sub get % and replace exch xpos iii add exch put % red last redmap ypos jjj sub get % find old blue pixel xpos iii add get dup curcolor 0 get % find full new red pixel sub % find difference curmat1 jjj get iii get 1 sub % find alpha fraction mul add % calculate new red pixel round cvi redmap ypos jjj sub get % and replace exch xpos iii add exch put } for % for each glyph h pixel } for % for eabh glyph row findnextcharacterstart % calculate next start position } store % temp % /findnextcharacterstart readjusts xpos and ypos, checking for line overflow /findnextcharacterstart {/xpos xpos ii add % move to next character start globalkern add store xpos 1400 ii 2 mul sub gt % is enough room left for {/xpos 3 store % one double width character? /ypos ypos yinc % no, move down a line sub store} if ypos 0 lt % force error message {ypos_below_bitmap} if } store % /docr uses above routine to force a linefeed or carriage return /docr {/xpos 9999 store findnextcharacterstart} % force too far to the right store % then do lfcr %%% DEFAULTS %%%%% /MyriadPro-Bold setfontfamily /Helvetica-Bold setfontfamily /shrinkfactor 0 store % set internal shrink factor .04 for small /linsamps 6 store % samples per pixel 6=36 8=64 /spacecharwidth 0.67 store % width of space character compared to "A" /kern+char (~) 0 get def % define positive kerning character /kern-char (`)0 get def % define negative kerning character /xpos 3 store % default x starting position /ypos 390 store % defualt y starting position /yinc 18 store % default y increment %% initial setup /hbits 1400 def % horizontal bits in BMP bitmap /vbits 1400 def % vertical bits in BMP bitmap makeclonebitmaps % create data array that matches bitmap %% matching color pallettes /teklight {/curcolor [161 171 163 ] store} store % for Tektronix TM501 /tekdark {/curcolor [ 83 89 74 ] store} store % zzzzzzzzzzzzz search marker %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%% DEMO - Remove or alter before reuse %%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % this is for the Motorola 68HC integrated circuits /targetfilename (curlets.bmp) def % short name of file to be generated -- no need to change /targetfilenameprefix % full filename prefix to be appended (C:\\Documents and Settings\\don 2\\Desktop\\Aleisha Projects\\image postproc\\tools\\bm typewriter\\) store % Font choice goes here. MyriadPro-Bold is usually best Last one without % gets used % /Helvetica-Bold setfontfamily % /Helvetica setfontfamily % /Symbol setfontfamily /MyriadPro-Bold setfontfamily % colors are entered as [ red blue green ] with values 0= black and 254 = safe white, 255 = pure white % colors are VERY specific to project and can be found using PAINT EDIT COLORS --> DEFINE CUSTOM COLORS %% Alternate safecolor speed lettering (see %%%%%% < http://www.tinaja.com/glib/webcolor.pdf > ).... % Limited to 216 colors % setwebtint accepts a color number 0 to 215 and then % sets the PostScript color generator for later use... % tintmat is a self-generating list of 216 triple color values /webtintmat256 [ 0 1 5 { /a exch store 0 1 5 { /b exch store 0 1 5 { 5 div 256 mul cvi b 5 div 256 mul cvi a 5 div 256 mul cvi }for } for } for ] def /set210color { abs cvi 216 cvi mod % restrict range webtintmat256 exch 3 mul 3 getinterval % get values from table /curcolor exch store} def % and set them /backwhite {/curcolor [210 240 255 ] store} store /backblack {/curcolor [34 34 32 ] store} store /bluelet {/curcolor [ 100 150 191 ] store} store /whitelet {/curcolor [ 192 195 194 ] store} store /ltblueback {/curcolor [ 212 241 235 ] store} store /blacklet {/curcolor [ 40 40 40 ] store} store % this sets the background as four blocks. Block D is highest. Blocks may share same color % MUST match one or more of the above color selections. % try the new way 43 set210color setbackD setbackC % pick background color setbackB setbackA % set backgrounds A is bottom quarter /yinc 26 store % sets line spacing % this is just a format reminder. % lines get ignored % 8 8 setbmsize % 3 385 ( Midnight Engineering Conference Denver, CO March 27 - 30 , 2008 ) setgraystring % 3 is how far to left, 385 is how many pixels baseline up from bottom. Use 0 0 to continue % Rotations must be done with Imageview32 or with custom code -- ask %%%%%%%%%%%%%%%%%%%%% /globalkern 4 store % sets the minimum spacing between letters. Use 1 for small % whitelet 172 set210color 27 32 setbmsize % sets font size pixels wide by pixels high /yinc 35 store 3 385 (MC68HC 908GT16CFB 1L61G CTKW0406 908GP32CFB 0L96S CTVPOS549) setgraystring %%%%%%%%%%%%%%%%%%%%%%% % To use, run Acrodist-F from the command line, drag and drop writebitmap % this does it % showpage % EOF