antoine-source/appleworksgs/Pict/Src/region.aii

1 line
15 KiB
Plaintext
Executable File

LOAD 'Macros.dump'
INCLUDE 'Pict.equ'
INCLUDE 'Driver.equ'
IMPORT Q_ChangePictSize
IMPORT Q_Copy2
IMPORT Q_JustRect
IMPORT D_NeedHandle
IMPORT Q_Nop
IMPORT D_ZeroBlock
IMPORT Q_addbytes
IMPORT Q_center
IMPORT count
IMPORT Q_half
IMPORT newptr
IMPORT oldptr
IMPORT Q_pictSCB
IMPORT Q_picterr
IMPORT Q_printsquare
IMPORT Q_square
import temp
IMPORT thepoint
IMPORT what
ENTRY Q_FlipHRgn
ENTRY Q_FlipVRgn
ENTRY MangleRgn
ENTRY Q_RotLRgn
ENTRY Q_RotRRgn
ENTRY Q_flipdx
ENTRY flipdy
****************************************************************
* ;
* Q_Region flipping and rotating routines ;
*______________________________________________________________*
* ;
* Q_MangleRegion(rgn:l,what:w,prerec:l):newrgn:l ;
*______________________________________________________________*
* ;
* NOTE! The Apple Q_Region data structure is proprietary, ;
* and as such, this code may legally belong to Apple, if ;
* they ask for it. ;
* ;
****************************************************************
*--------------------------------------------------------------*
* Copy a Q_Region picture opcode and mangle its data ;
*--------------------------------------------------------------*
Q_Region PROC EXPORT
;Using Q_PictData
EXPORT Q_JustRgn
jsl Q_Nop ; copy the opcode
Q_JustRgn ;
cmpw [<oldptr],#10
jeq nomore
spacelong ; get a handle for the Q_Region
pushword #0 ; high word of size
pushword [<oldptr]
pushword #$8000 ; X_Locked!
jsl D_NeedHandle
sta Q_picterr
pulllong <thepoint
jcs abort
movelong [<thepoint],<temp
pushlong <oldptr ; copy the Q_Region data into the handle
pushlong <temp
pushword #0
pushword [<oldptr]
_BlockMove
moveword [<oldptr],<count
addwl <count,<oldptr
cmpw <what,#Q_rotr
blt doit
lda Q_pictSCB
beq doit
pushlong <thepoint
pushlong #Q_square
pushlong #Q_half
_MapRgn
doit spacelong
pushlong <thepoint ; mangle the Q_Region!
jtl MangleRgn,<what
sta Q_picterr
pushlong <thepoint ; out with the old
_DisposeHandle
pulllong <thepoint ; ...in with the D_New
cmpw Q_picterr,#1
jcs abort
cmpw <what,#Q_rotr
blt didit
lda Q_pictSCB
beq didit
pushlong <thepoint
pushlong #Q_half
pushlong #Q_square
_MapRgn
didit pushlong <thepoint
_Hlock
movelong [<thepoint],<temp
cmpw [<temp],<count ; did the Q_Region size change?
beq samesize
stz Q_addbytes+2
subword [<temp],<count,Q_addbytes
bpl changeit
dec Q_addbytes+2
changeit jsl Q_ChangePictSize ; if so, make room in the pict
bcs abort
movelong [<thepoint],<temp ; (restore temp)
moveword [<temp],<count
samesize pushlong <temp ; copy the D_New Q_Region into the pict
pushlong <newptr
pushword #0
pushword <count
_BlockMove
addwl <count,<newptr
pushlong <thepoint
_DisposeHandle
bra exit
nomore jsl Q_Copy2 ; copy the size
jsl Q_JustRect ; mangle the bounds
exit clc
abort rtl
ENDP
****************************************************************
*
* Q_MangleRegion(rgn:l,what:w,prrec:l):newrgn:l -- mangle a Q_Region
*
****************************************************************
Q_MangleRegion PROC EXPORT
;Using Q_PictData
EXPORT MangleRgn
input oldrgn:l,how:w,prrec:l
output newrgn:l
local rptr:l,prptr:l
begin +b
cmpw how,#2
blt norot1
movelong [prrec],prptr
movelong [prptr]:#4,Q_printsquare+4
pushlong oldrgn
pushlong #Q_printsquare
pushlong #Q_square
_MapRgn
norot1 pushlong oldrgn
_Hlock
movelong [oldrgn],rptr
addword [rptr]:#2,[rptr]:#6,Q_center ; get the 'Q_center' of
addword [rptr]:#4,[rptr]:#8,Q_center+2 ; the old Q_Region
norot spacelong
pushlong oldrgn
jtl MangleRgn,how
sta Q_picterr
pulllong newrgn
pushlong oldrgn
_HunLock
cmpw how,#2
blt exit
pushlong newrgn
pushlong #Q_square
pushlong #Q_printsquare
_MapRgn
exit return Q_picterr
MangleRgn ;
DC.L Q_FlipHRgn
DC.L Q_FlipVRgn
DC.L Q_RotRRgn
DC.L Q_RotLRgn
ENDP
****************************************************************
*
* Q_FlipHRgn -- flip a Q_Region horizontally about 'Q_center'
*
****************************************************************
Q_FlipHRgn PROC EXPORT
;Using Q_PictData
input oldrgn:l
output newrgn:l
local oldrptr:l,newrptr:l
local roff1:w,roff2:w,xoff:w,doff:w
begin
pushlong oldrgn
_Hlock
movelong [oldrgn],oldrptr
spacelong
pushword #0
pushword [oldrptr]
pushword #$8000
jsl D_NeedHandle
sta Q_picterr
pulllong newrgn
jcs exit
movelong [newrgn],newrptr
movelong [oldrptr],[newrptr]
moveword [oldrptr]:#6,[newrptr]:#6
subword Q_center+2,[oldrptr]:#4,[newrptr]:#8
subword Q_center+2,[oldrptr]:#8,[newrptr]:#4
cmpw [oldrptr],#10 ; rectangular Q_Region?
jeq exit ; if so, I'm done!
ldy #10
lda [oldrptr],y
*--------------------------------------------------------------*
* Loop through the rows of the Q_Region ;
*--------------------------------------------------------------*
rloop sta [newrptr],y ; copy y coord
sty roff1 ; y = offset to beginning of row
sty doff
lda #$3fff
endloop iny
iny
cmp [oldrptr],y
bne endloop
sty roff2 ; y = offset to the end of the row
sty xoff
sta [newrptr],y ; copy end marker
xloop dec xoff
dec xoff
cmpw xoff,roff1
beq xdone
inc doff
inc doff
subword Q_center+2,[oldrptr]:xoff,[newrptr]:doff
dec xoff
dec xoff
inc doff
inc doff
subword Q_center+2,[oldrptr]:xoff,[newrptr]:doff
bra xloop
xdone ldy roff2
iny
iny
lda [oldrptr],y
cmp #$3fff ; end of the Q_Region?
bne rloop
sta [newrptr],y ; copy last end marker
pushlong newrgn ; D_Ignore errors
_HunLock
exit pushlong oldrgn ; that's all!
_HunLock
return Q_picterr
ENDP
****************************************************************
*
* Q_FlipVRgn -- flip a Q_Region vertically about 'Q_center'
*
****************************************************************
Q_FlipVRgn PROC EXPORT
;Using Q_PictData
input oldrgn:l
output newrgn:l
local oldrptr:l,newrptr:l
local roff:w,noff:w,xoff:w
begin
pushlong oldrgn
_Hlock
movelong [oldrgn],oldrptr
spacelong
pushword #0
pushword [oldrptr]
pushword #$8000
jsl D_NeedHandle
sta Q_picterr
pulllong newrgn
jcs exit
movelong [newrgn],newrptr
moveword [oldrptr],[newrptr]
moveword [oldrptr]:#4,[newrptr]:#4
moveword [oldrptr]:#8,[newrptr]:#8
subword Q_center,[oldrptr]:#2,[newrptr]:#6
subword Q_center,[oldrptr]:#6,[newrptr]:#2
cmpw [oldrptr],#10 ; rectangular Q_Region?
jeq exit ; if so, I'm done!
moveword #8,noff
lda [oldrptr] ; start at the end of the old
sec
sbc #4 ; (skip last two end markers)
tay
*--------------------------------------------------------------*
* Loop through the rows of the Q_Region ;
*--------------------------------------------------------------*
rloop dey
dey
cpy #8
beq gotit
cmpw [oldrptr]:y,#$3fff
bne rloop
gotit sty roff ; y = end of previous row (if any)
iny
iny
sty xoff
inc noff
inc noff
subword Q_center,[oldrptr]:xoff,[newrptr]:noff ; fix y coord
xloop inc xoff
inc xoff
inc noff
inc noff
moveword [oldrptr]:xoff,[newrptr]:noff
cmp #$3fff ; stop after copying end marker
beq xdone
inc xoff
inc xoff
inc noff
inc noff
moveword [oldrptr]:xoff,[newrptr]:noff
bra xloop
xdone ldy roff
cpy #8
bne rloop
inc noff ; put in the end of Q_Region marker
inc noff
moveword #$3fff,[newrptr]:noff
pushlong newrgn
_HunLock
exit pushlong oldrgn ; That's it!
_HunLock
return Q_picterr
ENDP
****************************************************************
*
* Q_FlipDRgn -- flip a Q_Region diagonally -- used by RotXRgn
*
****************************************************************
Q_FlipDRgn PROC EXPORT
;Using Q_PictData
EXPORT flipdy
EXPORT Q_flipdx
input oldrgn:l
output newrgn:l
local oldrptr:l,newrptr:l,offset:w
local tabhnd:l,tabptr:l,taboff:w,tabstart:w
local tabsize:w,rgnsize:w,xcoord:w
begin
pushlong oldrgn
_Hlock
movelong [oldrgn],oldrptr
cmpw [oldrptr],#10 ; rectangular Q_Region?
bne notrect
moveword #10,rgnsize
jsr preprgn
pushlong newrgn
_HUnLock
brl exit
*--------------------------------------------------------------*
* Allocate and initialize the offset table ;
*--------------------------------------------------------------*
notrect moveword [oldrptr]:#4,tabstart
subword [oldrptr]:#8,tabstart,tabsize
inc tabsize
asl tabsize
spacelong
pushword #0
pushword tabsize
pushword #$8000
jsl D_NeedHandle
sta Q_picterr
pulllong tabhnd
jcs exit
movelong [tabhnd],tabptr
pushlong tabptr
pushword tabsize
jsl D_ZeroBlock
*--------------------------------------------------------------*
* Count the occurences of each x coordinate ;
*--------------------------------------------------------------*
ldy #8
crloop iny
iny
lda [oldrptr],y
cmp #$3fff ; end of the Q_Region?
beq gotcount
cxloop iny
iny
lda [oldrptr],y
cmp #$3fff ; end of the Q_Line?
beq crloop
tyx
sec
sbc tabstart ; adjust to 0
asl a ; double
tay
lda [tabptr],y ; increment the table entry
inc a
sta [tabptr],y
txy
bra cxloop
*--------------------------------------------------------------*
* Convert counts to offsets into the D_New Q_Region ;
*--------------------------------------------------------------*
gotcount ldy #0
moveword #10,offset ; (I want offsets to starts of rows)
convloop lda [tabptr],y
beq convnext ; (except zeros)
inc a ; add space for y-coord
inc a ; add space for end marker
asl a ; convert to words
clc
adc offset
tax ; wait....
lda offset
sta [tabptr],y ; store the old offset
stx offset ; and keep the D_New one
convnext iny
iny
cpy tabsize
blt convloop
addword offset,#2,rgnsize
*--------------------------------------------------------------*
* Allocate the Q_Region and do some preliminary mangling ;
*--------------------------------------------------------------*
jsr preprgn
jcs exit2
*--------------------------------------------------------------*
* D_Write out y coordinates and endmarkers ;
*--------------------------------------------------------------*
stz taboff
ldy #10
bra wstart
wloop ldy taboff ; is this a row?
lda [tabptr],y
beq wnext
tay
dey
dey
lda #$3fff ; D_Write the preceding end marker
sta [newrptr],y
iny
iny
wstart lda taboff ; D_Write the y-coordinate
lsr a ; convert from words
clc
adc tabstart
jsr Q_flipdx
sta [newrptr],y ; (y = offset to row beginning)
wnext inc taboff
inc taboff
cmpw taboff,tabsize
bne wloop
ldy rgnsize
lda #$3fff ; D_Write last end markers
dey
dey
sta [newrptr],y
dey
dey
sta [newrptr],y
*--------------------------------------------------------------*
* Loop through the Q_Region, mangling y-coords into D_New x-coords ;
*--------------------------------------------------------------*
ldy #8
mrloop iny
iny
lda [oldrptr],y
cmp #$3fff ; end of the Q_Region?
beq done
jsr flipdy
sta xcoord
mxloop iny
iny
lda [oldrptr],y
cmp #$3fff ; end of the Q_Line?
beq mrloop
sty offset
sec
sbc tabstart ; adjust to 0
asl a
tay
lda [tabptr],y ; get offset from table
inc a ; increment it
inc a
sta [tabptr],y
tay
lda xcoord
sta [newrptr],y ; store x coord in D_New Q_Region
ldy offset
bra mxloop
*--------------------------------------------------------------*
* Clean up and go home ;
*--------------------------------------------------------------*
done pushlong newrgn ; D_Ignore errors
_HunLock
exit2 pushlong tabhnd
_DisposeHandle
exit pushlong oldrgn ; That's it!
_HunLock
return Q_picterr
*--------------------------------------------------------------*
* Q_Point flipping routines. ;
*--------------------------------------------------------------*
flipdy ;
sta Q_Point
lda Q_center+2 ; R-rotate the Q_Point around Q_center
and #1 ; <adjust for creep>
clc
adc Q_center+2 ; pt.x <= pt.y - Q_center.y + Q_center.x
sec
sbc Q_center
sta temp ; (divide by 2, preserving
asl temp ; the sign)
ror a ;
clc
adc Q_Point
rts
Q_flipdx ;
sta Q_Point
lda Q_center ; pt.y <= pt.x - Q_center.x + Q_center.y
and #1 ; <adjust for creep>
clc
adc Q_center
sec
sbc Q_center+2
sta temp ; (divide by 2, preserving
asl temp ; the sign)
ror a ;
clc
adc Q_Point
rts
*--------------------------------------------------------------*
preprgn spacelong
pushword #0
pushword rgnsize
pushword #$8000
jsl D_NeedHandle
sta Q_picterr
pulllong newrgn
jcs prepped
movelong [newrgn],newrptr
moveword rgnsize,[newrptr] ; copy the size
ldy #2 ; mangle the bounding Q_Rect
lda [oldrptr],y
jsr flipdy
ldy #4
sta [newrptr],y
ldy #4
lda [oldrptr],y
jsr Q_flipdx
ldy #2
sta [newrptr],y
ldy #6
lda [oldrptr],y
jsr flipdy
ldy #8
sta [newrptr],y
ldy #8
lda [oldrptr],y
jsr Q_flipdx
ldy #6
sta [newrptr],y
clc ; SIGH
prepped rts
Q_Point DS.B 2
temp DS.B 2
ENDP
****************************************************************
*
* Q_RotRRgn -- rotate a Q_Region clockwise
*
****************************************************************
Q_RotRRgn PROC EXPORT
;Using Q_PictData
input oldrgn:l
output newrgn:l
local tmprgn:l
begin
spacelong
pushlong oldrgn
jsl Q_FlipDRgn
sta Q_picterr
pulllong tmpRgn
bcs notmp
spacelong
pushlong tmprgn
jsl Q_FlipHRgn
sta Q_picterr
pulllong newrgn
pushlong tmprgn
_DisposeHandle
notmp return Q_picterr
ENDP
****************************************************************
*
* Q_RotLRgn -- rotate a Q_Region anticlockwise
*
****************************************************************
Q_RotLRgn PROC EXPORT
;Using Q_PictData
input oldrgn:l
output newrgn:l
local tmprgn:l
begin
spacelong
pushlong oldrgn
jsl Q_FlipHRgn
sta Q_picterr
pulllong tmpRgn
bcs notmp
spacelong
pushlong tmprgn
jsl Q_FlipDRgn
sta Q_picterr
pulllong newrgn
pushlong tmprgn
_DisposeHandle
notmp return Q_picterr
ENDP
END