summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/lib/impath.ps
blob: 07aa3128054ab797098816f81650ac73afd856fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
%    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 6300 2005-12-28 19:56:24Z giles $
% 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