plan9fox/sys/lib/ghostscript/impath.ps
2011-03-30 19:35:09 +03:00

180 lines
5.4 KiB
PostScript

% 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.)
% <image> <width> <height> <wx> <wy> <ox> <oy> <string>
% type1imagepath <substring>
% 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