M EQU Byte Ptr 0[BX] TITLE 'POLYGON' DGROUP GROUP DATA ; **************************************************************************** ; * * ; * DOFILLC : Generate Polygon Fill and Outlines * ; * * ; **************************************************************************** ; * ; Revision : Nov. 09, 1983 File "DOFILLC.A86" Version 1.0 * ; ; ;***** MODE NOTES : ********************************************************* ; * ; 1) LINE STYLE SUPPORT VARIABLES IN PUBLIC : * ; LINE ENDPOINTS - X0, Y0, XN, YN, SPECIL * ; FILTER Y AND SET BIT FLAGS - ABOVE, INSIDE, ZONED * ; Apr-26-83 rhk * ; Optimize Bar Fill, X intersection points = XPmin, XPmax * ; May-04-83 rhk * ; Add Writing mode support and Outline the Polygon after Interior Fill * ; May-27-83 rhk * ; Change Disk File Access to support 64k Records * ; May-31-83 rhk * ; Seperate Hatch and Pattern Fill styles * ; Nov-07-84 rhk * ; Color Support, Call ZSETCOR with FIll Color Index * ; Nov-09-84 rhk * ; Hollow Fill with BLANKS * ;***** MODE NOTES : ********************************************************* ; ; ; Calls : * ; * ; GETXY - Get the x,y coordinates of the next point in OBJLST (4 Bytes) * ; getrec - get the record no. of the requested byte if it is out on disk * ; DRAWIT - Raster convert vector to pixel values, maps pixel * ; to bitmap address and 'sets' the bit * ; * ; GETPT : Get pt. coord. from PTSIN array (2 bytes) * ; PUTPT : Put pt. coord. into OBJLST buffer (2 bytes) * ; PUTBYT : Put 1 byte into OBJLST buffer * ; GETBYT : Get 1 byte from OBJLST buffer * ; GETMIN : Returns in the smaller of , values * ; GETMAX : Retruns in the larger of Values in and * ; * ;***************************************************************************** PUBLIC DOFILL, dobar EXTRN GETXY:near, GETNXT:near, GETBYT:near, RSTAT:byte EXTRN DRAWIT:near, DRAWXY:near, FILTER:near, GETXY1:near extrn getrec:near, ZSETCOR:near dseg EXTRN BNEXT:word, NDLNTY:byte, NDFITY:byte, NDINTY:byte extrn patmask:word, BYTNDX:word, barcode:byte, ndlnco:byte extrn rflgf:byte, bmaskf:byte, ritflg:byte, bitmask:byte EXTRN NDFICO:byte, LSTYLE:word, SPECIL:word, ABOVE:byte EXTRN TOPY:word, BOTY:word, BOTTY:word EXTRN X1:word, Y1:word, X2:word, Y2:word EXTRN X0:word, Y0:word, XN:word, YN:word extrn recndx:word, BLANKS:word SCRATCH RW 1 scrat2 rw 100 ; maximum x intersections on a raster line NPT RW 1 ;No. of points XPMIN RW 1 ;Polygon Min/Max Extents YPMIN RW 1 XPMAX RW 1 YPMAX RW 1 COUNT RW 1 LNTY RS 1 SAVPTR RW 1 NXTPTR RW 1 savndx rw 1 nxtndx rw 1 SAVLTY RW 1 savlco rw 1 F1 RW 1 PMIN RW 1 ; larger of ypmin and boty PMAX RW 1 ; smaller of ypmax and topy VX1 RW 1 VY1 RW 1 VX2 RW 1 VY2 RW 1 JINT RW 1 IX RW 1 JX RW 1 J RW 1 I RW 1 maskptr rw 1 W_1 EQU word ptr 0 W_2 EQU word ptr 2 cseg ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Polygon (Fill Area) + ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DOFILL: ; Clear Bar Code Flag, 0 = Do normal polygon fill mov barcode, 0 dobar: ; Bar Code Flag Already Set by DOGDP routine, 1 = Do Bar Fill ;----------------------------------------------------------------------------+ ; Take care of Attributes - Linestyle, color + ; Save Current polyline linetype, linecolor + ; Set linestyle to SOLID, color to Current Fill area color + ;----------------------------------------------------------------------------+ MOV AL,Byte Ptr NDLNTY MOV Byte Ptr LNTY,AL MOV Byte Ptr NDLNTY,0 mov al, Byte Ptr ndlnco mov Byte Ptr savlco, al ; save the polyline color mov bl, Byte Ptr ndfico mov Byte Ptr ndlnco, bl ; Use polygon fill color Call ZSETCOR ;----------------------------------------------------------------------------+ ; Save NPT + ;----------------------------------------------------------------------------+ CALL GETNXT MOV Byte Ptr NPT,AL inc al MOV BX, Word Ptr BNEXT ; Save the Object List Buffer Byte MOV Word Ptr SAVPTR, BX ; Index to the Polygon Vertices mov bx, word ptr recndx mov word ptr savndx, bx ; find the byte pointer to the polygon min., max. extent mov ah, 0 add ax, ax add ax, ax ; no. of bytes in the polygon = npt x 4 mov bx, ax call getrec ; update the record index and byte address ; according to the no. of bytes to offset ;----------------------------------------------------------------------------+ ; Get Polygon Minimum/Maximum extents + ;----------------------------------------------------------------------------+ CALL GETXY ;Get Minimum polygon extent xpmin, ypmin ;Returns = xpmin, = ypmin, MOV Word Ptr XPMIN,DX mov word ptr scratch, dx ; Ist X intersection point for Bar MOV Word Ptr YPMIN,CX ;Get Maximum polygon extent from OBJLST CALL GETXY ;Returns = xpmax, = ypmax, MOV Word Ptr XPMAX,DX mov word ptr scrat2, dx ; 2nd X intersection point for bar MOV Word Ptr YPMAX,CX MOV AX, BNEXT ; BNEXT points to next entry in OBJLST MOV NXTPTR, AX ; Save it in NXTPTR mov ax, recndx ; recndx is the corresponding record index mov nxtndx, ax ; save it in nxtndx ;----------------------------------------------------------------------------+ ; Polygon outside of current Plot Strip ? Trivial Reject + ;----------------------------------------------------------------------------+ ; Trivial Rejects if : ypmin > topy or ypmax < boty FILJ01: MOV AX, YPMAX CMP AX, BOTY JGe FILJ02 JMP FILJ99 FILJ02: MOV AX, YPMIN CMP AX, TOPY JLe FILJ03 JMP FILJ99 ;----------------------------------------------------------------------------+ ; Determine No. of fill lines in Polygon Extent + ;----------------------------------------------------------------------------+ filj03: MOV AX, LSTYLE ; Save Current Line Style Pattern MOV SAVLTY, AX inc Byte Ptr ndlnty ; Make Sure Line Style Is not Set to Solid ; for pattern fill mov al, Byte Ptr rflgf ; Logical Set Bit operation flag mov ritflg, al ; based on color and writing mode mov al, Byte Ptr bmaskf mov bitmask, al ; Check Fill interior Style, if hollow - Use Blanks to fill CMP Byte Ptr ndfity, 0 jne FILJ04 ; Not Hollow fill Mov Bx, Offset BLANKS ; use BLANKS as fill pattern JMP filj11 filj04: MOV BX, 0 ; solid fill mask Index cmp ndfity, 1 ; Solid fill ? je filj10 mov bx, word ptr NDINTY ; Get Fill Interior Style Index cmp Byte Ptr ndfity, 3 ; Hatch or Pattern Fill ? je filj10 ; Hatch Fill = 3 add bx, 6 ; Offset to Pattern Fill Masks filj10: mov cl, 3 shl bx, cl ; bx x 8 = Offset to Appropriate Pattern Mask add bx, offset PATmask ; Pattern Mask Pointer filj11: mov maskptr, bx ; save MASK Pointer MOV AX, BOTY MOV PMIN, AX ; Initialize Fill Extent to Current Plot Strip MOV AX, TOPY MOV PMAX, AX MOV AX, YPMIN ; Adjust Fill Area to With in the Strip CMP AX, PMIN JNG FILJ20 MOV PMIN, AX FILJ20: MOV AX, YPMAX CMP AX, PMAX JNL FILJ21 MOV PMAX, AX ; No. of fill lines, Count = PMAX - PMIN FILJ21: MOV AX, PMIN MOV F1, AX MOV BX, PMAX SUB BX, AX INC BX MOV COUNT, BX ;----------------------------------------------------------------------------+ ; Find the Intersection points for each raster line F1 + ;----------------------------------------------------------------------------+ BIGLP: ; Check Bar Fill or Polygon Fill ? mov al, barcode cmp al, 0 je bigfil ; mov jint, 2 ; 2 intersection points for bar fill mov i, 1 ; 1 intersection pair for Bar fill jmp bigbar bigfil: MOV JINT, 0 ; initialize no. of intersection points MOV BX, NPT MOV J, BX ; j = no. of vertices in polygon MOV AX, SAVPTR MOV BNEXT, AX ; BNEXT now points to byte address of x1 mov ax, savndx mov recndx, ax ; restore the corresponding record index ; Get x1, y1 CALL GETXY1 ; = X1, = Y1 MOV VX1, DX MOV VY1, CX ; For j = npt to 1 by -1 FILLPJ: CALL GETXY1 ; = X2, = Y2 MOV BX, F1 ; Y SUB BX, CX ; Y - Y2 MOV AX, F1 ; Y SUB AX, VY1 ; Y - Y1 MOV AL, BH AND AX, 8080H ; ISOLATE THE SIGNS CMP AH, AL ; IF SIGN EQUAL, NO INTERSECTION JE NOINT ; Current Raster line (y) intersects line segment y1,y2 MOV SI, VY1 ; Compute y1 - y2 SUB SI, CX ; SI = Y1 - Y2 JZ NOINT ; horizontal line = nop MOV AX, VX1 SUB AX, DX ; AX = X1 - X2 PUSH DX ; stack X2 SHL AX, 1 ; half round off IMUL BX ; (X1-X2) * (Y-Y2) IDIV SI ; / (Y1-Y2) INC AX ; Complete the round off SAR AX, 1 POP DX ; Unstack X2 ADD AX, DX ; + X2 = X intersection point MOV BX, JINT ; save intersection point in the scratch INC JINT ; Array ADD BX, BX MOV SCRATCH[BX], AX NOINT: MOV VX1, DX MOV VY1, CX DEC J JNZ FILLPJ FILDRW: ; Sort the Intersections and draw this ; raster line MOV AX, JINT ; JINT = no. of intersections found DEC AX MOV JINT, AX CMP AX, 1 ; Skip if no intersection point occured JGE SORTIT JMP NXTSEG ; No intersection SORTIT: ; do ix = jint to 1 by -1 MOV IX, AX SORTIX: MOV JX, 1 ; do jx = 1 to ix MOV BX, offset SCRATCH SORTJX: MOV AX, W_1[BX] ; Get scratch (JX), (JX+1) MOV DX, W_2[BX] CMP AX, DX JNG SORTNO MOV W_1[BX], DX ; Swap entry MOV W_2[BX], AX SORTNO: ADD BX, 2 ; Next entry in Scratch INC JX ; JX = JX + 1 MOV AX, JX CMP AX, IX ; end of loop ? JNG SORTJX DEC IX ; ix = ix - 1 JNZ SORTIX ; END OF SORT MOV AX, JINT INC AX SHR AX, 1 ; (JINT+1)/2 = no. of intersection pairs MOV I, AX ; Loop index bigbar: MOV BX, offset SCRATCH FILNXT: PUSH BX MOV DX, W_1[BX] MOV AX, W_2[BX] ; = X1, = X2 ; The following compare will not work for bars defined ; with upper corner (X1,Y1), and lower corner (X2, Y2) ; instead of lower corner and upper corner. ; CMP DX, AX ; Skip Fill if too close ; JG OUTSIDE MOV BX, F1 ; F1 = Raster line (Y) ;set up for line drawing routine MOV X0, DX MOV X1, DX MOV Y0, BX MOV Y1, BX MOV X2, AX MOV XN, AX MOV Y2, BX MOV YN, BX ; offset Pattern mask by F1 Raster Lines (Y) and bx, 7 ; Y mod 8 (Pattern is 8 by 8 matrix) neg bx add bx, 7 ; Make 7-0 add bx, maskptr ; Point to Appropriate row in pattern mov Byte Ptr al, Byte Ptr[bx] ; Get Pattern Byte for that ; Raster line mov ah, al ; AX = 16-bit mask ; rotate pattern mask by X to align pattern mask up mov cx, dx and cl, 0fh ; modulo 16, it't a 16-bit pattern rol ax, cl ; Align the Mask mov LSTYLE, ax ; Put it in LSTYLE for DRAW Line Routine mov specil, ax ; Put it in Pattern ; = Y, paranoia check ; CALL FILTER ; is line inside current plot strip ? ; ; BOTY < Y > TOPY : = 0 ; CMP CH, 0 ; JNE OUTSIDE ; Setup Line Direction Flag for Draw Line routine, Normally setup ; by CLIPIT routine, used by SWAPY routine MOV byte ptr ABOVE, 0 CALL DRAWXY ; DRAW LINE OUTSIDE: POP BX ADD BX, 4 ; index to next intersection pairs DEC I ; any more pairs ? JNZ FILNXT NXTSEG: INC F1 ; Next raster line to fill DEC COUNT ; Any more lines JZ FILJ90 JMP BIGLP ;----------------------------------------------------------------------------+ ; outline the polygon, Call Polyline routine + ;----------------------------------------------------------------------------+ filj90: mov al, rflgf mov ritflg, al mov al, bmaskf ; set up the logical operation flag mov bitmask, al ; and the bitmask mov ndlnty, 0 ; use solid linestyle for outline mov ax, savndx ; make the byte index point to npt mov recndx, ax mov ax, savptr mov bnext, ax mov ax, npt inc ax ; polyline npt = polygon npt + 1 CALL DRAWIT ;Returns Pointer to next entry in FILJ99: MOV AX, NXTPTR MOV BNEXT, AX ; Update OBJLST byte index pointer mov ax, nxtndx ; restore the byte index for the next object mov recndx, ax ; and the record index for the next object ;----------------------------------------------------------------------------+ ; Restore Line style and color + ;----------------------------------------------------------------------------+ filj0: MOV AL,Byte Ptr LNTY MOV Byte Ptr NDLNTY,AL ; line style index mov ax, savlty ; Line Style Pattern mov lstyle, ax mov ax, savlco mov byte ptr ndlnco, al ; line color RET END