% render.ps - write font bitmaps and metric information to standard output. % Version 1.10. % Copyright (c) 1994 Paul Vojta. All rights reserved. % % Redistribution and use in source and binary forms, with or without % modification, are permitted provided that the following conditions % are met: % 1. Redistributions of source code must retain the above copyright % notice, this list of conditions and the following disclaimer. % 2. Redistributions in binary form must reproduce the above copyright % notice, this list of conditions and the following disclaimer in the % documentation and/or other materials provided with the distribution. % % THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE % ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE % FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL % DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS % OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT % LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY % OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF % SUCH DAMAGE. %%% % Usage: gs -DNODISPLAY -q -- render.ps fontname dlstring specinfo dpi % Then, it will read standard input to get: % pointsize % charset % Example: % % gs -DNODISPLAY -q -- render.ps Helvetica "(phvr.gsf) run" \ % > ".5 ExtendFont" 300 % GS> 10 % GS> 97 98 99 %% % % Standard file definitions /.stdin where { pop } { /.stdin (%stdin) (r) file def } ifelse /.stdout where { pop } { /.stdout (%stdout) (w) file def } ifelse /.stderr where { pop } { /.stderr (%stderr) (w) file def } ifelse %% % % Define some routines first % (string) fatal - % Print string to stderr and quit. /fatal { (render.ps: ) exch concatstrings .stderr exch writestring .stderr flushfile 1 .quit } bind def % (string) brun - % Load a font in .pfb format. /brun { (r) file false /PFBDecode filter cvx exec } bind def % (exec) getbbox - % Get bounding box of the executable object and save it in char-urx, % char-ury, etc. /getbbox { gsave nulldevice erasepage newpath exec pathbbox % returns llx lly urx ury /char-ury exch ceiling cvi def /char-urx exch ceiling cvi def /char-lly exch floor cvi def /char-llx exch floor cvi def grestore } bind def % - drawfontbbox - % Draw the font's bbox. /drawfontbbox { currentfont /FontBBox get dup dup 0 get exch 1 get currentfont /FontMatrix get transform moveto dup dup 0 get exch 3 get currentfont /FontMatrix get transform lineto dup dup 2 get exch 1 get currentfont /FontMatrix get transform lineto dup 2 get exch 3 get currentfont /FontMatrix get transform lineto } bind def % (exec) mkbboxdev - % Get bounding box of the executable object and make a device a few % pixels larger on each side. If pathbbox fails for the object, % then use the font's bbox. /mkbboxdev { getbbox char-llx char-urx sub round 0 eq char-lly char-ury sub round 0 eq or { {drawfontbbox} getbbox } if matrix char-urx char-llx sub 4 add % width dup /width exch def char-ury char-lly sub 4 add % height dup /height exch def makeimagedevice setdevice 2 char-llx sub 2 char-lly sub translate } bind def %% % % These may be called by the "specinfo" string. /usefontbbox false def % These do things to a transformation array; called by entries in psfonts.map. % /ObliqueSlant { dup sin exch cos div neg } bind def /SlantFont { font-size mul add } def /ExtendFont { 3 -1 roll mul exch } def /ReEncodeFont { TargetFont dup length dict /newdict exch def {1 index /FID ne {newdict 3 1 roll put} {pop pop} ifelse} forall newdict exch /Encoding exch put /OurFont newdict definefont /TargetFont exch def} def % Define writeppmfile, if it's not provided. systemdict /writeppmfile known not { /writeppmfile { pop % always use currentdevice dup (P4\n) writestring dup width =string cvs writestring dup ( ) writestring dup height =string cvs writestring dup (\n) writestring width 7 add 8 div cvi string 0 1 height 1 sub { currentdevice exch 2 index copyscanlines 2 index exch writestring } for pop % discard string pop % discard file } def } if %% % % Main program begins now. Just interpret it. % Get arguments. shellarguments not { (You must provide arguments to the shell!\n) fatal } if /dpi exch cvr def /specinfo exch def /dlstring exch def /fontname exch def % Open the font. dlstring () ne { dlstring cvx exec Fontmap fontname cvn known FontDirectory fontname cvn known or } { Fontmap fontname cvn known } ifelse not { (font ) fontname concatstrings ( is not defined.\n) concatstrings fatal } if % Get arguments from stdin. Just leave the character list on the stack. /font-size .stdin 20 string readline pop cvr % get pointsize 72.27 div dpi mul % let's work in (TeX) points def [ .stdin 1024 string readline pop cvx exec ] % character list % Define the font, and make it current. /TargetFont fontname cvlit findfont def [ font-size 0 specinfo cvx exec 0 exch font-size 0 0 ] TargetFont exch makefont setfont % If the font's bounding box is zero, then do not use it. usefontbbox { currentfont /FontBBox get true exch {0 eq and} forall {/usefontbbox false def}if } if % If we are to use the font's bounding box, then get it and transform it. usefontbbox { {drawfontbbox} mkbboxdev } if % Begin loop over characters. { /charno exch def /charstring 1 string dup 0 charno put def /charwidth charstring stringwidth pop def % Get the character's bounding box. This also makes the device. usefontbbox not { { 0 0 moveto charstring true charpath } mkbboxdev } if % Print the metric info. (#^ ) print charno =string cvs print ( ) print char-llx =string cvs print ( ) print char-lly =string cvs print ( ) print char-urx =string cvs print ( ) print char-ury =string cvs print ( ) print charwidth =string cvs print (\n) print % Now write the bitmap. erasepage 0 0 moveto charstring show .stdout currentdevice writeppmfile } forall