%!PS % POSTSCRIPT/ACROBAT .BMP GENERATOR AND SIMPLIFIED "BITMAP TYPEWRITER" V5.2 % ========================================================================== % Copyright c 2001, 2004 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.5 % This utility shows how to programatically generate a .BMP file from PostScript. % It also acts as a "bitmap typewriter" that lets you force ultrasmall but TOTALLY % CONTROLLED lettering onto a bitmap image. I have found this especially useful % in eBay image prep of oscilloscopes and similar test instruments. % A tutorial is found as http://www.tinaja.com/glib/bmfonts.pdf % Earlier alternate version is found as http://www.tinaja.com/psutils/imgwrds1.psl % The code has purposely been kept simple for easy mods. % To use, read and edit this file in a suitable ASCII editor or word processor. % Then distill the new file using Adobe Acrobat or GhostScript. Then pull up the % generated .BMP file in Paint or wherever, position and paste. % A "WARNING: No PDF File Produced" error message is normal and expected. % IMPORTANT NOTE: Don Lancaster's file gonzo.ps is reccomended to enhance this program. % After obvious location mods, uncomment ONE of the following two lines: % (C:\\windows\\desktop\\gonzo\\gonzo.ps) run % use internal gonzo % (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. %%%%%%%%%%%%%%%% CONTROL VARIABLES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /hbits 356 def % horizontal bits in BMP bitmap /vbits 256 def % vertical bits in BMP bitmap /bkgcolor [255 255 255 ] def % background color (best used WHITE} /color1 [67 67 97] def % chosen font or other color /color2 [0 255 0] def % chosen font or other color /color3 [0 0 255] def % chosen font or other color /color4 [250 150 250] def /color5 [0 255 255] def /curcolor color1 store % current color variable /targetfilename (test01.bmp) def % short name of file to be generated /targetfilenameprefix % full filename prefix to be appended (C:\\WINDOWS\\desktop\\psbits\\) def /autochar true store % automatic drop to next line? /yincr 14 def % vertical spacing between characters /zz (x) 0 get def % font marker lower case "x" for font color /usekernchars true def % allow kerning? /kern+char (~) 0 get def % define positive kerning character /kern-char (`) 0 get def % define negative kerning character %%%%%%%%%%%%%%%%% PROGRAM SUPPORT MODULES %%%%%%%%%%%%%%%%%%%%%%%%%% % 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 % [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 % /makeclonebitmap sets up an 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. /makeclonebitmap { /redmap mark vbits {mark bkgcolor 0 get hbits 1 sub {dup} repeat ] makestring } repeat ] def /greenmap mark vbits {mark bkgcolor 1 get hbits 1 sub {dup} repeat ] makestring} repeat ] def /bluemap mark vbits {mark bkgcolor 2 get hbits 1 sub {dup} repeat ] makestring } repeat ] def } def % /bitfill accepts xpos ypos width height and generates a color box. Unity (or low) % width boxes can be used for horizontal or vertical lines... /bitfill { /bhigh exch store /bwide exch store /ypos exch store /xpos exch store hbits xpos sub % h room on line bwide le {/bwide hbits xpos sub 1 sub store} if % limit to h edge vbits ypos sub % h room on line bhigh le {/bhigh vbits ypos sub 1 sub store} if % limit to h edge 0 1 bhigh 1 sub { /mm exch store mark (x) 0 get bwide 1 sub {dup} repeat ] makestring patterntobitmap % } for } def % /redden etc takes a character row (or other) string and replaces it with the % red color or background... /redden { /yy curcolor 0 get store /nn bkgcolor 0 get store mark exch % for postconverted array mark exch % for preconverted array {} forall ] % convert string to array {zz eq {yy}{nn} ifelse} forall % substitute colors ] makestring % return new string } def /greenen { /yy curcolor 1 get store /nn bkgcolor 1 get store mark exch % for postconverted array mark exch % for preconverted array {} forall ] % convert string to array {zz eq {yy}{nn} ifelse} forall % substitute colors ] makestring % return new string } def /blueen { /yy curcolor 2 get store /nn bkgcolor 2 get store mark exch % for postconverted array mark exch % for preconverted array {} forall ] % convert string to array {zz eq {yy}{nn} ifelse} forall % substitute colors ] makestring % return new string } def % /patterntobitmap is used by /bitfill to fill color backgrounds... /patterntobitmap {dup dup % copy for green and blue redden redmap ypos mm add get % place red pixels exch xpos exch putinterval greenen greenmap ypos mm add get % place green pixels exch xpos exch putinterval blueen bluemap ypos mm add get % place blue pixels exch xpos exch putinterval } def % /adjustbaseline shifts the character upwards by the height of the standard "8" /adjustbaseline { /ypos1 ypos1 curfont 48 get length add store} def % /checkoverflow prevents a character from being entered that will not fit /checkoverflow {dup 0 get curfont exch get % get glyph array 0 get length % width of char top xpos add 2 add hbits ge % true if overflow dup {autochar {docr pop exch pop exch pop xpos exch ypos exch % mess with stack false} if}if % ignore or autochar? } def /docr {/ypos ypos yincr sub store /xpos xpos1 store /advok false store} def %% /setgraychar accepts xpos ypos (x) and places the character into the bitmap string. /setgraychar { /realchar true store dup exch 0 get % test for positive kerning kern+char eq {/xpos xpos 1 add store /advok false store /realchar false store} if dup exch 0 get kern-char eq {/xpos % test for negative kerning xpos 1 sub store /advok false store /realchar false store} if realchar { % if not a kern command dup 0 get dup 10 eq exch 13 eq or % test for lfcr { pop pop pop docr }{setgraychar1 } ifelse } {pop pop pop} ifelse } def /grayonly true store /setgraychar1 { checkoverflow not { 0 get curfont exch get % get gray font glyph /curgrayglyph exch store /gypos exch store /gxpos exch store 0 1 curgrayglyph length 1 sub { /ss exch store curgrayglyph ss get /curgraygline exch store 0 1 curgraygline length 1 sub {/tt exch store curgraygline tt get % get gray character value grayonly { 256 mul floor cvi % convert to integer gray dup dup % copy gray for blue and green redmap gypos ss sub get % get current red line exch gxpos tt add exch put % and place bluemap gypos ss sub get % get current green line exch gxpos tt add exch put % and place greenmap gypos ss sub get % get current blue line exch gxpos tt add exch put % and place }{setgraywithalpha} ifelse } for % glyph line } for % entire glyph /advok true store /lastgraycharwidth curgrayglyph 0 get length store % remember width } {/lastgraycharwidth 0 store pop pop pop} % if no char to print ifelse } def % /setgraywithalpha does antialiased characters in color with optional alpha, % but is slower than grayonly. Activates on /grayonly false. /setgraywithalpha { 1 exch sub %%% why??? globalalpha mul /alphax exch store % gray value becomes alpha % (alpha is ) print alpha == redmap gypos ss sub get % get red map line gxpos tt add % get position 2 copy get % get current value dup curcolor 0 get % get new value sub alphax mul floor cvi sub % calculate fractional change put % and place greenmap gypos ss sub get % green map line gxpos tt add % get position 2 copy get % get current value dup curcolor 1 get % get new value sub alphax mul floor cvi sub % calculate fractional change put % and place bluemap gypos ss sub get % get blue map line gxpos tt add % get position 2 copy get % get current value dup curcolor 2 get % get new value sub alphax mul floor cvi sub % calculate fractional change put % and place } def % /setgraystring places a string of true antialiased characters onto the bitmap... /setgraystring {/str exch store /ypos1 exch store /xpos1 exch store /advok true store /globalalpha alpha store adjustbaseline % correct vertical position /xpos xpos1 store /ypos ypos1 store 0 1 str length 1 sub {/kk exch store xpos ypos str kk 1 getinterval setgraychar % put character on screen advok { /xpos xpos lastgraycharwidth add % adjust horizontal cursor globalkern add store } if } for } def %%%%%%%%%%%%% FILE WRITING UTILITIES %%%%%%%%%%%%%% % /ws is a housekeeping utility... /zzzz 0 def /ws {writefile exch %%%%dup zzzz 100 le { 0 get == /zzzz zzzz 1 add store }{pop} ifelse writestring} def % file writing utility /writenull {0 strx exch 0 exch put strx ws } def /strx (X) def % /writebmpbitmap creates the bitmap file on disk /writebmpbitmap { /targetbmpfilename targetfilenameprefix targetfilename mergestr def targetbmpfilename (w+) file /writefile exch def % make a .BMP file to write writeheader % write defined .BMP header writebitmap % write BGRX bitmap writefile closefile % close & complete file } 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 { % (writing bitmap header) == (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 % Use BiBitCount for color count writenull writenull writenull writenull % All colors are important } def % /writebitmap writes the bitmap portion to the .BMP file /writebitmap { 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 %%%%%%%%%%%%% DEMO -- REMOVE OR ALTER BEFORE REUSE %%%%%%%%%%%%%%%%%%% /useantialiasedfonts true store /grayonly false store /alpha 1.0 store /globalkern 2 store % run your desired fonts here - MUST match local font file positions! /fontprefix (C:\\windows\\desktop\\image_tools_copy\\reletter\\gfonts) store fontprefix (\\f404bg\\f404bg.txt) mergestr run fontprefix (\\f406bg\\f406bg.txt) mergestr run fontprefix (\\f405bg\\f405bg.txt) mergestr run fontprefix (\\f506bg\\f506bg.txt) mergestr run fontprefix (\\f507bg\\f507bg.txt) mergestr run fontprefix (\\f810bg\\f810bg.txt) mergestr run fontprefix (\\f812bg\\f812bg.txt) mergestr run fontprefix (\\f910bg\\f910bg.txt) mergestr run fontprefix (\\f1011bg\\f1011bg.txt) mergestr run fontprefix (\\f610bg\\f610bg.txt) mergestr run fontprefix (\\f608bg\\f608bg.txt) mergestr run fontprefix (\\f607bg\\f607bg.txt) mergestr run fontprefix (\\f709bg\\f709bg.txt) mergestr run fontprefix (\\f911bg\\f911bg.txt) mergestr run fontprefix (\\f1007bg\\f1007bg.txt) mergestr run fontprefix (\\f1410bg\\f1410bg.txt) mergestr run % set your desired color names here /hpdarkbkg [ 42 45 38 ] store % values for hp 3336A /hpwhiteletts [ 182 178 162] store /hplightbkg [ 162 161 143 ] store /hpbrown [ 41 40 32 ] store /hpbrownonlylighter [ 72 70 54 ] store /targetfilename (bmtype01.bmp) def % short name of file to be generated /targetfilenameprefix % full filename prefix to be appended (C:\\windows\\desktop\\image_tools_copy\\reletter\\bm_type\\)def % generate a color background bitmap ... /bkgcolor {hplightbkg } store % start with panel background makeclonebitmap % change color areas as needed... /curcolor hplightbkg store 0 0 350 150 bitfill /curcolor hpdarkbkg store 0 50 350 90 bitfill % place lettering as needed... /curfont f506bg store /curcolor hpwhiteletts store /globalkern 2 store 3 110 (3336A SYNTHESIZED LEVEL GENERATOR) setgraystring /curfont f405bg store 3 122 (HEWLETT - PACKARD) setgraystring /curfont f404bg store /globalkern 1 store 3 132 (LOCAL REMOTE SRQ TALK LISTEN EXT AM ON PM ON EXT REF AMP BLANK REAR 21 MHz) setgraystring 3 70 (HZ DEG DBM SEC ENTRY REAR 21 MHZ MHz) setgraystring /curfont f506bg store /globalkern 1 store /curcolor hpbrownonlylighter store 3 190 (SWEEP DATA MODIFY ENTRY OUTPUT) setgraystring /curfont f404bg store 3 220 (FREQUENCY AMPLITUDE PHASE ON OFF STDBY OFF POWER STORE RECALL CLEAR MHZ KHZ HZ DBM) setgraystring 3 247 (DBM DEG 7 DBM MAX OUTPUT 75O 10 HZ - 21 MHZ ALL 42V MAX FLOAT 150 600 10 KHZ 2.1 MHZ) setgraystring 3 235 (CONT START STOP SINGLE LOG TIME) setgraystring % then actually make the bitmap... writebmpbitmap % and write the actual bitmap intermediate transfer % EOF