% Copyright (C) 1992, 1996 Aladdin Enterprises. All rights reserved. % % This software is provided AS-IS with no warranty, either express or % implied. % % This software is distributed under license and may not be copied, % modified or distributed except as expressly authorized under the terms % of the license contained in the file LICENSE in this distribution. % % For more information about licensing, please refer to % http://www.ghostscript.com/licensing/. For information on % commercial licensing, go to http://www.artifex.com/licensing/ or % contact Artifex Software, Inc., 101 Lucas Valley Road #110, % San Rafael, CA 94903, U.S.A., +1(415)492-9861. % $Id: impath.ps,v 1.5 2002/02/21 21:49:28 giles Exp $ % impath.ps % Reverse-rasterize a bitmap to produce a Type 1 outline. % (This was formerly a Ghostscript operator implemented in C.) % % type1imagepath % Converts an image (bitmap) description of a character into % a scalable description in Adobe Type 1 format. The % current transformation matrix should be the same as the % FontMatrix of the font in which this character will be % used: this establishes the scaling relationship between % image pixels (the image is assumed to be 1 unit high in % user space) and the character coordinate system used in % the scalable description. wx and wy are the character % width, and ox and oy are the character origin relative % to the lower left corner of the bitmap, in *pixels*. % The image is assumed to be stored in left-to-right, % top-to-bottom order. Note that this is not consistent % with the `image' operator's interpretation of the CTM. % All coordinates in the scalable description are rounded to % integers, so the coefficients in the FontMatrix should % be on the order of 1/N for some value of N that is % either a multiple of the height/width or is large % compared to the width and height. (There is a % convention, which some PostScript programs rely on, that % N=1000.) % Note that the encoded description has *not* been subjected % to CharString encryption, which is necessary before the % description can be given to type1addpath: to do this, % follow the type1imagepath with % 4330 exch dup .type1encrypt exch pop % If the description is too complex to fit into the supplied % string, a limitcheck error results. A good rule of % thumb is that the size of the string should be about 6 % times the number of 1-bits in the image that are not % completely surrounded by other 1-bits. % Import the Type 1 opcodes. (type1ops.ps) runlibfile 100 dict dup /type1imagepath_dict exch def begin /rc { round cvi } bind def /moving [/rmoveto /hmoveto /vmoveto] def /drawing [/rlineto /hlineto /vlineto] def % Convert the current path to a Type 1 token array. /putxy % x y ops -> cs_elements { 3 -1 roll dup x sub rc exch /x exch def 3 -1 roll dup y sub rc exch /y exch def % stack: ops dx dy dup 0 eq { % dy = 0, use hmoveto/lineto pop exch 1 get } { 1 index 0 eq { % dx = 0, use vmoveto/lineto exch pop exch 2 get } { % use rmoveto/rlineto 3 -1 roll 0 get } ifelse } ifelse } bind def /pathtotype1 % -> charstack { 3 dict begin /x 0 def /y 0 def mark { moving putxy } { drawing putxy } { % Convert curve to relative form x y 3 { exch neg 7 index add rc exch neg 6 index add rc 8 -2 roll } repeat /y exch def /x exch def 1 index 0 eq 5 index 0 eq and % dy1=dx3=0, hv { 5 -1 roll pop exch pop /hvcurveto } { dup 0 eq 6 index 0 eq and % dx1=dy3=0, vh { 6 -1 roll pop pop /vhcurveto } { /rrcurveto % none of the above } ifelse } ifelse } { /closepath } pathforall end } bind def end % type1imagepath_dict % The main program /type1imagepath % image width height wx wy ox oy string -> % substring { type1imagepath_dict begin /tsave save def /ostring exch def /oy exch def /ox exch def /wy exch def /wx exch def /height exch def /width exch def /data exch def /ofilter ostring /NullEncode filter def /raster width 7 add 8 idiv def % Construct the coordinate transformation. height dup scale matrix currentmatrix matrix invertmatrix setmatrix % Determine the left side bearing. /lsbx width 0 1 width 1 sub { dup dup 8 idiv 0 exch raster raster height mul 1 sub { data exch get or } for exch 8 mod bitshift 128 and 0 ne { exch pop exit } if pop } for def % Compute and encode the origin, width, and side bearing. mark ox oy dtransform rc /opty exch def rc /optx exch def wx wy dtransform rc /iwy exch def rc /iwx exch def lsbx ox sub 0 dtransform rc /ilsby exch def rc /ilsbx exch def ilsbx iwy 0 ne ilsby 0 ne or { ilsby iwx iwy /sbw } { iwx /hsbw } ifelse ofilter charstack_write % Flip over the Y axis, because the image is stored top-to-bottom. [1 0 0 -1 0 height] concat % Account for the character origin. lsbx oy translate % Trace the outline. newpath width height data .imagepath gsave matrix setmatrix pathtotype1 grestore ofilter charstack_write % Terminate the output mark /endchar ofilter charstack_write ofilter .fileposition ofilter closefile % flush buffers ostring 0 3 -1 roll getinterval tsave restore end } bind def