--- /dev/null
+;-----------------------------------------------------------\r
+;\r
+; MXCR.ASM - Clip functions\r
+; Copyright (c) 1993,1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN PRO\r
+NOWARN RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC mxSetSysClipRegion\r
+PUBLIC mxGetClipRegion\r
+PUBLIC mxSetClipRegion\r
+PUBLIC mxSetClip\r
+PUBLIC mxGetClip\r
+\r
+PUBLIC subClipBox\r
+PUBLIC subClipImage\r
+\r
+PUBLIC mx_ClipX1\r
+PUBLIC mx_ClipY1\r
+PUBLIC mx_ClipX2\r
+PUBLIC mx_ClipY2\r
+\r
+MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
+ ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN mx_CodeSegment : WORD\r
+\r
+mx_ClipX1 DW ? ; Clip coordinates\r
+mx_ClipY1 DW ?\r
+mx_ClipX2 DW ?\r
+mx_ClipY2 DW ?\r
+\r
+mx_SysClipX1 DW ? ; System clip coordinates\r
+mx_SysClipY1 DW ? ; (active when mx_ClipStatus is FALSE)\r
+mx_SysClipX2 DW ?\r
+mx_SysClipY2 DW ?\r
+\r
+mx_UserClipX1 DW ? ; User clip coordinates\r
+mx_UserClipY1 DW ? ; (active when mx_ClipStatus is TRUE)\r
+mx_UserClipX2 DW ?\r
+mx_UserClipY2 DW ?\r
+\r
+mx_ClipStatus DB ?\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Toggles clipping between user and system regions.\r
+;\r
+; Input:\r
+; ClipStatus = TRUE (FALSE) to enable (disable) clipping\r
+; Output:\r
+; AX = old clip status\r
+;\r
+mxSetClip PROC FAR\r
+ ARG ClipStatus:BYTE:2 = ARG_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter 0\r
+ .push ds\r
+ mov ds, [mx_CodeSegment]\r
+ ASSUME ds:MX_TEXT\r
+\r
+ mov ax, [mx_UserClipX1]\r
+ mov bx, [mx_UserClipY1]\r
+ mov cx, [mx_UserClipX2]\r
+ mov dx, [mx_UserClipY2]\r
+ cmp [ClipStatus], TRUE\r
+ je @@Done\r
+ mov ax, [mx_SysClipX1]\r
+ mov bx, [mx_SysClipY1]\r
+ mov cx, [mx_SysClipX2]\r
+ mov dx, [mx_SysClipY2]\r
+@@Done:\r
+ mov [mx_ClipX1], ax\r
+ mov [mx_ClipY1], bx\r
+ mov [mx_ClipX2], cx\r
+ mov [mx_ClipY2], dx\r
+\r
+ mov al, [ClipStatus]\r
+ xchg al, [mx_ClipStatus]\r
+ xor ah, ah\r
+\r
+ .pop ds\r
+ .leave ARG_SIZE\r
+mxSetClip ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Returns the current clipping status.\r
+;\r
+; Input:\r
+; none\r
+; Output:\r
+; TRUE (FALSE) if clipping enabled (disabled)\r
+;\r
+mxGetClip PROC FAR\r
+ ASSUME ds:NOTHING\r
+ mov al, [mx_ClipStatus]\r
+ xor ah, ah\r
+ ret\r
+mxGetClip ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the system clip region and disables user clipping.\r
+;\r
+; Input:\r
+; Width = width in pixels of clip region\r
+; Height = height in pixels of clip region\r
+; Output:\r
+; old clip status.\r
+;\r
+mxSetSysClipRegion PROC FAR\r
+ ARG Height:WORD, \\r
+ Width:WORD = ARG_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter 0\r
+ .push ds\r
+ mov ds, [mx_CodeSegment]\r
+ ASSUME ds:MX_TEXT\r
+\r
+ xor ax, ax ; Sys clip region always starts at (0,0)\r
+ mov [mx_SysClipX1], ax\r
+ mov [mx_SysClipY1], ax\r
+ mov ax, [Width]\r
+ dec ax\r
+ mov [mx_SysClipX2], ax\r
+ mov ax, [Height]\r
+ dec ax\r
+ mov [mx_SysClipY2], ax\r
+\r
+ IF USE286 EQ TRUE\r
+ push FALSE\r
+ ELSE\r
+ mov ax, FALSE\r
+ push ax\r
+ ENDIF\r
+ call mxSetClip\r
+\r
+ .pop ds\r
+ .leave ARG_SIZE\r
+mxSetSysClipRegion ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the clip region.\r
+;\r
+; Input:\r
+; X, Y = coordinates of top left corner of clip region\r
+; Width = width in pixels of clip region\r
+; Height = height in pixels of clip region\r
+; Output:\r
+; none (no checking on parameters)\r
+;\r
+mxSetClipRegion PROC FAR\r
+ ARG Height:WORD, \\r
+ Width:WORD, \\r
+ Y:WORD, \\r
+ X:WORD = ARG_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter 0\r
+ .push ds\r
+ mov ds, [mx_CodeSegment]\r
+ ASSUME ds:MX_TEXT\r
+\r
+ mov ax, [X]\r
+ mov [mx_UserClipX1], ax\r
+ mov ax, [Y]\r
+ mov [mx_UserClipY1], ax\r
+ mov ax, [Width]\r
+ add ax, [X]\r
+ dec ax\r
+ mov [mx_UserClipX2], ax\r
+ mov ax, [Height]\r
+ add ax, [Y]\r
+ dec ax\r
+ mov [mx_UserClipY2], ax\r
+\r
+ mov al, [mx_ClipStatus]\r
+ cmp al, TRUE\r
+ jne @@Exit\r
+ push ax\r
+ call mxSetClip\r
+\r
+@@Exit:\r
+ xor ax, ax\r
+ .pop ds\r
+ .leave ARG_SIZE\r
+mxSetClipRegion ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Returns the current user clip region.\r
+;\r
+; Input:\r
+; X, Y = pointers to integer coordinates of top left corner\r
+; Width = pointer to word width of clip region\r
+; Height = pointer to word height of clip region\r
+; Output:\r
+; AX = current clip status\r
+;\r
+mxGetClipRegion PROC FAR\r
+ ARG Height:DWORD, \\r
+ Width:DWORD, \\r
+ Y:DWORD, \\r
+ X:DWORD = ARG_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter 0\r
+ .push es, di\r
+\r
+ mov ax, [mx_UserClipX1]\r
+ les di, [X]\r
+ mov es:[di], ax\r
+ mov ax, [mx_UserClipY1]\r
+ les di, [Y]\r
+ mov es:[di], ax\r
+\r
+ mov ax, [mx_UserClipX2]\r
+ sub ax, [mx_UserClipX1]\r
+ inc ax\r
+ les di, [Width]\r
+ mov es:[di], ax\r
+ mov ax, [mx_UserClipY2]\r
+ sub ax, [mx_UserClipY1]\r
+ inc ax\r
+ les di, [Height]\r
+ mov es:[di], ax\r
+\r
+ mov al, [mx_ClipStatus]\r
+ xor ah, ah\r
+ .pop es, di\r
+ .leave ARG_SIZE\r
+mxGetClipRegion ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Internal use: checks the coordinates of a rectangle against\r
+; the active clip region.\r
+; This function assumes that a "raw" image has to be clipped,\r
+; so it returns in SI the number of "raw" bytes to skip if\r
+; X, Y were clipped.\r
+;\r
+; Input:\r
+; BX, AX = X, Y coordinates of rectangle (signed)\r
+; CX = box width\r
+; DX = box height\r
+; Output:\r
+; CF = set if rectangle is full clipped\r
+; BX, AX = new X, Y coordinates of rectangle\r
+; CX, DX = clipped width and height\r
+; SI = number of bytes to skip before copying a buffer\r
+; DI destroyed\r
+;\r
+subClipImage PROC NEAR\r
+ ASSUME ds:NOTHING\r
+ xor si, si\r
+\r
+; Check clip height\r
+ mov di, [mx_ClipY1]\r
+ cmp ax, di\r
+ jge @@CheckBottom\r
+ sub di, ax ; Number of lines to clip\r
+ sub dx, di ; New box height\r
+ jle @@Exit\r
+ mov ax, di\r
+ mov di, dx ; Save box height into DI\r
+ mul cx ; DX:AX = number of bytes to skip\r
+ mov si, ax\r
+ mov dx, di ; Restore box height\r
+ mov ax, [mx_ClipY1]\r
+@@CheckBottom:\r
+ mov di, [mx_ClipY2]\r
+ cmp ax, di\r
+ jg @@Exit\r
+ inc di\r
+ sub di, dx\r
+ sub di, ax\r
+ jge @@DoneHeight ; None, continue\r
+ add dx, di ; Clip lines\r
+@@DoneHeight:\r
+\r
+; Check clip width\r
+@@CheckLeft:\r
+ mov di, [mx_ClipX1]\r
+ cmp bx, di\r
+ jge @@CheckRight\r
+ sub di, bx ; Number of columns to clip left\r
+ sub cx, di\r
+ jle @@Exit\r
+ add si, di ; Update skip count\r
+ mov bx, [mx_ClipX1]\r
+@@CheckRight:\r
+ mov di, [mx_ClipX2]\r
+ cmp bx, di\r
+ jg @@Exit\r
+ inc di\r
+ sub di, bx\r
+ sub di, cx\r
+ jge @@DoneWidth ; None, exit\r
+ add cx, di ; New box width\r
+@@DoneWidth:\r
+\r
+; Set return flag and exit\r
+@@Done:\r
+ clc\r
+ ret\r
+@@Exit:\r
+ stc\r
+ ret\r
+subClipImage ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Internal use: checks the coordinates of a rectangle against\r
+; the active clip region.\r
+;\r
+; Input:\r
+; BX, AX = X, Y coordinates of rectangle (signed)\r
+; CX = box width\r
+; DX = box height\r
+; Output:\r
+; CF = set if rectangle is full clipped\r
+; BX, AX = new X, Y coordinates of rectangle\r
+; CX, DX = clipped width and height\r
+; DI destroyed\r
+;\r
+subClipBox PROC NEAR\r
+ ASSUME ds:NOTHING\r
+\r
+; Check clip height\r
+ mov di, [mx_ClipY1]\r
+ cmp ax, di\r
+ jge @@CheckBottom\r
+ sub di, ax ; Number of lines to clip\r
+ sub dx, di ; New box height\r
+ jle @@Exit\r
+ mov ax, [mx_ClipY1]\r
+@@CheckBottom:\r
+ mov di, [mx_ClipY2]\r
+ cmp ax, di\r
+ jg @@Exit\r
+ inc di\r
+ sub di, dx\r
+ sub di, ax ; Clipped some point?\r
+ jge @@DoneHeight ; No, continue\r
+ add dx, di ; Clip lines (DI is negative)\r
+@@DoneHeight:\r
+\r
+; Check clip width\r
+@@CheckLeft:\r
+ mov di, [mx_ClipX1]\r
+ cmp bx, di\r
+ jge @@CheckRight\r
+ sub di, bx ; Number of columns to clip left\r
+ sub cx, di\r
+ jle @@Exit\r
+ mov bx, [mx_ClipX1]\r
+@@CheckRight:\r
+ mov di, [mx_ClipX2]\r
+ cmp bx, di\r
+ jg @@Exit\r
+ inc di\r
+ sub di, bx\r
+ sub di, cx ; Clipped some point?\r
+ jge @@DoneWidth ; No, exit\r
+ add cx, di ; New box width (DI is negative)\r
+@@DoneWidth:\r
+\r
+; Set return flag and exit\r
+@@Done:\r
+ clc\r
+ ret\r
+@@Exit:\r
+ stc\r
+ ret\r
+subClipBox ENDP\r
+\r
+MX_TEXT ENDS\r
+END\r