Skip to content

Commit 722a4a8

Browse files
committed
renmatrix: Use bitmask and direction lookup table for path tracing
1 parent bc91aca commit 722a4a8

File tree

1 file changed

+107
-38
lines changed

1 file changed

+107
-38
lines changed

src/renmatrix.ps.src

Lines changed: 107 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,88 @@ begin
5252
/forward dup /backward dup /upward dup /downward dup
5353
>> readonly def
5454

55+
/renmatrix.left 1 def
56+
/renmatrix.right 2 def
57+
/renmatrix.up 4 def
58+
/renmatrix.down 8 def
59+
60+
%
61+
% Direction lookup table indexed by 2x2 neighbourhood:
62+
%
63+
% +---+---+
64+
% |A=8|B=4|
65+
% +---*---+
66+
% |C=2|D=1|
67+
% +---+---+
68+
%
69+
/renmatrix.tracestep [
70+
71+
% 0 0
72+
null % ?
73+
% 0 0
74+
75+
% 0 0
76+
{right} % +>
77+
% 0|1
78+
79+
% 0 0
80+
{down} % -+
81+
% 1v0
82+
83+
% 0 0
84+
{right} % -->
85+
% 1 1
86+
87+
% 0^1
88+
{up} % +-
89+
% 0 0
90+
91+
% 0^1
92+
{up} % |
93+
% 0|1
94+
95+
% 0 1 0^1
96+
{dir //renmatrix.right eq {down} {up} ifelse} bind % -+ or +-
97+
% 1v0 1 0
98+
99+
% 0^1
100+
{up} % -+
101+
% 1 1
102+
103+
% 1|0
104+
{left} % <+
105+
% 0 0
106+
107+
% 1|0 1 0
108+
{dir //renmatrix.down eq {left} {right} ifelse} bind % <+ or +>
109+
% 0 1 0|1
110+
111+
% 1|0
112+
{down} % |
113+
% 1v0
114+
115+
% 1|0
116+
{right} % +>
117+
% 1 1
118+
119+
% 1 1
120+
{left} % <--
121+
% 0 0
122+
123+
% 1 1
124+
{left} % <+
125+
% 0|1
126+
127+
% 1 1
128+
{down} % +-
129+
% 1v0
130+
131+
% 1 1
132+
null % ?
133+
% 1 1
134+
135+
] readonly def
136+
55137
/renmatrix {
56138

57139
128 dict begin
@@ -155,54 +237,40 @@ begin
155237
/bwipp.renmatrixBadTextsize (extratextsize must be greater than zero and less that 25) //raiseerror exec
156238
} if
157239

158-
/xyget { pixx mul add pixs exch get} def
159-
/cget { pixx mul add cache exch get and} def
240+
/xyget { pixx mul add pixs exch get } def
241+
/cget { pixx mul add cache exch get and } def
160242
/cput { % Optimise by only storing "stem" corners
161-
dup 4 mod 0 eq { % dir is up or left
243+
dup dup //renmatrix.up eq exch //renmatrix.left eq or { % dir is up or left
162244
3 1 roll pixx mul add cache exch 2 copy get 4 -1 roll or put
163245
} {
164246
pop pop pop
165247
} ifelse
166248
} def
167249

168250
/abcd {
169-
4 string 0 [
170-
5 -2 roll
171-
pixx mul add dup
172-
pixs exch 2 getinterval aload pop 3 -1 roll % A B
173-
pixs exch pixx add 2 getinterval aload pop % C D
174-
] {3 copy 48 add put pop 1 add} forall pop
251+
pixx mul add dup 1 add % A B
252+
1 index pixx add dup 1 add % C D
253+
pixs exch get
254+
exch pixs exch get 2 mul add
255+
exch pixs exch get 4 mul add
256+
exch pixs exch get 8 mul add
175257
} def
176258

177-
/right {dir 1 ne {x y dir cput [x y]} if /x x 1 add def /dir 1 def} def
178-
/down {dir 2 ne {x y dir cput [x y]} if /y y 1 add def /dir 2 def} def
179-
/left {dir 4 ne {x y dir cput [x y]} if /x x 1 sub def /dir 4 def} def
180-
/up {dir 8 ne {x y dir cput [x y]} if /y y 1 sub def /dir 8 def} def
259+
/left {dir //renmatrix.left ne {x y dir cput [x y]} if /x x 1 sub def /dir //renmatrix.left def} def
260+
/right {dir //renmatrix.right ne {x y dir cput [x y]} if /x x 1 add def /dir //renmatrix.right def} def
261+
/up {dir //renmatrix.up ne {x y dir cput [x y]} if /y y 1 sub def /dir //renmatrix.up def} def
262+
/down {dir //renmatrix.down ne {x y dir cput [x y]} if /y y 1 add def /dir //renmatrix.down def} def
181263

182264
%
183265
% Walk the outline of a region emitting edge coordinates of the path
184266
%
185267
/trace {
186268
/y exch def /x exch def
187-
% dir 1:right 2:down 4:left 8:up
188-
/dir x 1 add y 1 add xyget 1 eq {8} {4} ifelse def
269+
/dir x 1 add y 1 add xyget 1 eq {//renmatrix.up} {//renmatrix.left} ifelse def
189270
/sx x def /sy y def /sdir dir def
190271

191-
% A B
192-
% C D
193272
mark {
194-
x y abcd
195-
1 { % Common exit
196-
dup dup (0001) eq exch dup (0011) eq exch (1011) eq or or {pop right exit} if
197-
dup dup (0010) eq exch dup (1010) eq exch (1110) eq or or {pop down exit} if
198-
dup dup (1000) eq exch dup (1100) eq exch (1101) eq or or {pop left exit} if
199-
dup dup (0100) eq exch dup (0101) eq exch (0111) eq or or {pop up exit} if
200-
dup (1001) eq {
201-
dir 2 eq {pop left exit} {pop right exit} ifelse
202-
} { % 0110
203-
dir 1 eq {pop down exit} {pop up exit} ifelse
204-
} ifelse
205-
} repeat
273+
//renmatrix.tracestep x y abcd get exec
206274
x sx eq y sy eq and dir sdir eq and {exit} if
207275
} loop
208276
counttomark array astore exch pop
@@ -284,16 +352,17 @@ begin
284352
0 1 pixx 2 sub {
285353
/i exch def
286354
/k i j abcd def
287-
k (0001) eq k (1001) eq or { % Black region stem corners
288-
8 i j cget 0 eq {
289-
i j trace
290-
} if
291-
} if
292-
k (1110) eq { % White region stem corner
293-
4 i j cget 0 eq {
294-
i j trace
295-
} if
355+
k 2#0001 eq % Black region stem corners:
356+
k 2#1001 eq or { %
357+
//renmatrix.up i j cget 0 eq { % 0 0 1 0
358+
i j trace % * and *
359+
} if % 0 1 0 1
296360
} if
361+
k 2#1110 eq { % White region stem corner:
362+
//renmatrix.left i j cget 0 eq { %
363+
i j trace % 1 1
364+
} if % *
365+
} if % 1 0
297366
} for
298367
} for
299368
] def

0 commit comments

Comments
 (0)