-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathPackRgn.a
executable file
·159 lines (130 loc) · 6.47 KB
/
PackRgn.a
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
.INCLUDE GRAFTYPES.TEXT
.PROC PACKRGN,3
.REF SETSIZE
;-----------------------------------------------------------------
;
; PROCEDURE PackRgn(srcHandle: Handle; nPoints: INTEGER; dstRgn: RgnHandle);
;
; Converts a sorted array of inversion points into a region.
; Calls storage allocator to make more room and trim result to minimum size.
;
; OUTPUT IS IN THE FOLLOWING FORM:
;
; RGNSIZE
; RGNBBOX
; V H .. H 32767
; V H .. H 32767
; V=32767
;
; A6 OFFSETS OF PARAMETERS AFTER LINK:
;
PARAMSIZE .EQU 10 ;TOTAL BYTES OF PARAMS
SRCHANDLE .EQU PARAMSIZE+8-4 ;LONG
NPOINTS .EQU SRCHANDLE-2 ;INTEGER
DSTRGN .EQU NPOINTS-4 ;LONG, HANDLE
;-------------------------------------------------------
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
BBOX .EQU -8 ;RECTANGLE
VARSIZE .EQU BBOX ;SIZE OF LOCAL VARIABLES
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS
MOVE.L SRCHANDLE(A6),A4 ;GET SRC HANDLE
MOVE.L DSTRGN(A6),A3 ;GET DST RGNHANDLE
MOVE NPOINTS(A6),D6 ;GET NUMBER OF POINTS
MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN
MOVE RGNSIZE(A1),D5 ;GET CURRENT RGNSIZE
MOVE.L (A4),A0 ;DE-REFERENCE SRCHANDLE
;------------------------------------------------------------------------
;
; CHECK NPOINTS TO SPECIAL CASE EMPTY AND RECTANGULAR REGIONS.
;
MOVEQ #10,D7 ;INIT RGNSIZE TO EMPTY RGN SIZE
CLR.L BBOX+TOPLEFT(A6) ;INIT BOUNDING BOX TO EMPTY
CLR.L BBOX+BOTRIGHT(A6)
CMP #4,D6 ;HOW MANY POINTS IN SOURCE ?
BGT.S NOTRECT ;MORE THAN 4, NOT RECTANGULAR
BLT.S DONE ;LESS THAN 4, EMPTY REGION
MOVE.L 0(A0),BBOX+TOPLEFT(A6) ;GET TOPLEFT OF BOUNDING BOX
MOVE.L 12(A0),BBOX+BOTRIGHT(A6) ;GET BOTRIGHT OF BOUNDING BOX
BRA.S DONE ;INSTALL RGNSIZE AND BBOX AND QUIT
;------------------------------------------------------------------------
;
; MORE THAN FOUR POINTS, NON-RECTANGULAR. SCAN FOR BBOX LEFT AND RIGHT.
;
NOTRECT MOVE V(A0),BBOX+TOP(A6) ;BBOX TOP:=FIRST POINT.V
MOVE H(A0),D1 ;INIT MINH TO FIRST HORIZ
MOVE D1,D2 ;INIT MAXH TO FIRST HORIZ ALSO
MOVE D6,D3 ;GET NUMPER OF POINTS IN SRC
SCAN SUB #1,D3 ;ANY POINTS LEFT ?
BLT.S ENDSCAN ;NO, QUIT SCANNING
MOVE.L (A0)+,D0 ;YES, GET NEXT POINT
CMP.W D1,D0 ;IS PT.H < MINH ?
BGE.S LEFTOK ;NO, CONTINUE
MOVE D0,D1 ;YES, MINH:=PT.H
BRA SCAN ;LOOP FOR MORE
LEFTOK CMP.W D2,D0 ;IS PT.H > MAXH ?
BLE SCAN ;NO, GO FOR NEXT
MOVE D0,D2 ;YES, MAXH:=PT.H
BRA SCAN ;GO FOR NEXT
ENDSCAN MOVE D1,BBOX+LEFT(A6) ;BBOX LEFT:=MINH
MOVE D2,BBOX+RIGHT(A6) ;BBOX RIGHT:=MAXH
MOVE -4+V(A0),BBOX+BOTTOM(A6) ;BBOX BOTTOM:=LAST POINT.V
;----------------------------------------------------------------
;
; EXPAND DSTRGN TO HOLD WORST CASE = 12 + 4*NPOINTS bytes.
;
MOVEQ #3,D5
ADD D6,D5 ;GET NPOINTS + 3
LSL #2,D5 ;TIMES 4
MOVE.L A3,-(SP) ;PUSH DSTRGN
MOVE D5,-(SP) ;PUSH NEW BYTECOUNT
JSR SetSize ;MAKE IT THAT BIG
;----------------------------------------------------
;
; NEWLY DE-REFERENCE SRC AND DST HANDLES
;
MOVE.L (A4),A0 ;DE-REFERENCE SRC HANDLE
MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN HANDLE
ADD D7,A1 ;SKIP OVER RGNSIZE & BBOX
SUB #1,D6 ;DBRA COUNT = NPOINTS - 1
MOVE (A0)+,D0 ;GET FIRST VERT COORD
MOVE #32767,D1
BRA.S START ;GO TO LOOP START
NEXTPT CMP (A0)+,D0 ;SAME VERT COORD ?
BEQ.S VSAME ;YES, CONTINUE
MOVE D1,(A1)+ ;PUT END OF ROW MARKER
MOVE -2(A0),D0 ;GET NEW VERT COORD
START MOVE D0,(A1)+ ;PUT VERT COORD
VSAME MOVE (A0)+,(A1)+ ;PUT HORIZ COORD
DBRA D6,NEXTPT ;LOOP FOR ALL POINTS
MOVE D1,(A1)+ ;PUT END OF ROW MARKER
MOVE D1,(A1)+ ;PUT FINAL VERT = 32767
MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE
SUB.L A0,A1 ;SUBTRACT FROM DSTPTR
MOVE.W A1,D7 ;TO COMPUTE RGNSIZE
;--------------------------------------------------------
;
; INSTALL RGNSIZE AND RGNBBOX.
;
DONE MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE
MOVE D7,(A0)+ ;INSTALL RGNSIZE
MOVE.L BBOX+TOPLEFT(A6),(A0)+ ;INSTALL BOUNDING BOX TOPLEFT
MOVE.L BBOX+BOTRIGHT(A6),(A0)+ ;AND BOTRIGHT
;--------------------------------------------------------
;
; TRIM DSTRGN TO EXACT SIZE IF IT ISN'T ALREADY.
;
CMP D7,D5 ;IS IT ALREADY THE RIGHT SIZE ?
BEQ.S SIZEOK ;YES, SKIP
MOVE.L A3,-(SP) ;PUSH DSTRGN HANDLE
MOVE D7,-(SP) ;PUSH NEW SIZE
JSR SETSIZE
;------------------------------------------------------
;
; CLEAN UP THE STACK AND GO HOME.
;
SIZEOK MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'PACKRGN '
.END