⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regclip.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************/
/*                                                                       */
/*         Copyright (c) 1997 - 1999 Accelerated Technology, Inc.        */
/*                                                                       */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
/* subject matter of this material.  All manufacturing, reproduction,    */
/* use, and sales rights pertaining to this subject matter are governed  */
/* by the license agreement.  The recipient of this software implicitly  */
/* accepts the terms of the license.                                     */
/*                                                                       */
/*************************************************************************/

/*************************************************************************/
/*                                                                       */
/* FILE NAME                                            VERSION          */
/*                                                                       */
/*      regclip.c                                        1.9             */
/*                                                                       */
/* COMPONENT                                                             */
/*                                                                       */
/*      All                                                              */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      This file contains the region clipping functions.                */
/*                                                                       */
/* AUTHOR                                                                */
/*                                                                       */
/*      Robert G. Burrill, Accelerated Technology, Inc.                  */
/*                                                                       */
/* DATA STRUCTURES                                                       */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* FUNCTIONS                                                             */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* DEPENDENCIES                                                          */
/*                                                                       */
/*		None                                                             */
/*                                                                       */
/* HISTORY                                                               */
/*                                                                       */
/*		   NAME            DATE                    REMARKS               */
/*                                                                       */
/*		   BobB			  5/11/98		Corrected for drawing first line */
/*		   BobB			 11/17/98		Corrected line clipping loop     */
/*		   BobB			  7/1/99		Corrected clipping error         */
/*         BobB          11/18/99       Corrected first/last status      */
/*                                                                       */
/*************************************************************************/
#include "meta_wnd.h"
#include "metconst.h"    /* MetaWINDOW Constant & Stucture Definitions */
#include "metports.h"    /* MetaWINDOW Port & Bitmap Definitions */
#include "metaproc.h"
#include "grafdata.h"
#include "regclipv.h"


/*	Region-clipping functions. Variables required are in regclipv.h.  Set
isLine = 1 to disable support for YX banded blitRecs.  Set blitMayOverlap = 1
to enable set-up support for blits within the same bitmap that could
potentially overlap.  If NO_REGION_CLIP is defined, Set_Up_Clip only sets
up rect clipping, flagging region clipping as off, and all region-clipping
routines are effectively no-oped, so region clipping is turned off (and the
code is shrunk, too). Note that this no-oping relies on clipToRegionFlag
never being turned on by Set_Up_Clip (*all* region code is not compiled if
NOT_REGION_CLIP is defined, with only a return), so if NOT_REGION_CLIP is
defined, clipToRegionFlag should always be left at 0.  Check_YX_Band,
which doesn't require regions, stays the same. */


/* Function Blit_Clip_Region fills/blits a rectangle, clipped to a region,
processing the region from top->bottom, and left->right within each band for
the blit routines.  Returns a 1 if YX banded and there are more rectangles
to draw, else 0.

Parameters:
	fcRec = pointer to blitRcd
	fillRect = pointer rect to draw, already clipped to the clip rect
	sRect = pointer rect to draw from, already clipped to the clip rect; Ymin
	must be less than 0x7fff

The following regclipv.h common variables are required:
	FillDrawer = routine to call to draw each region-clipped rect
	nextRegionPtr must be set to the point at which to start scanning 
	through the region rect list (on exit, updated to start point for
	scanning next time)
	lclbfYXBanded must be set to !0 if the blitList of rects to draw is YX
	banded, 0 otherwise (used to advance nextRegionPtr, and to exit
	early when possible)
	bXmin, bYmin, bXmax, bYmax, bandYmin, dYminTemp, dYmaxTemp, bsXmin, bsYmin,
	bsXmax and bsYmax, sYminTemp and sYmaxTemp */
int Blit_Clip_Region(blitRcd *fcRec, rect *fillRect, rect *sRect)
{
	#ifndef NO_REGION_CLIP
	rect *regionRectPtr;

	regionRectPtr = nextRegionPtr;	/* point to the first region rect at
									which to start clipping */
	/* Find a region band not entirely above dest rect. */
	while (fillRect->Ymin >= regionRectPtr->Ymax)
	{
		regionRectPtr++;
	}

	/* Start at this point next time if the blitRcd is YX banded. */
	if (lclbfYXBanded != 0) nextRegionPtr = regionRectPtr;

	/* Skip if the band is entirely below dest rect. */
	if (fillRect->Ymax <= regionRectPtr->Ymin) goto BandFullyBelow;

	/* So long as we're in a band that overlaps vertically with destRect,
	scan across from the left until we find a region rect that overlaps
	horizontally or we move to another band, then draw destRect clipped
	to each region rect until we either find a region rect that doesn't
	overlap or we move to another band, then scan until we move to another
	band. If the next band isn't past the bottom of destRect, repeat. */
	bRect = *fillRect;	/* make a copy of dest rect, because we're going
						to alter the standard copy each time we clip it
						to a region rect */
	bsRect = *sRect;	/* likewise, make a copy of the source rect */

	do {	/* clipping and drawing loop */
		/* remember top edge of this YX band */
		bandYmin = regionRectPtr->Ymin;
		/* set Y extent of dest rect, clipped to the Y extent of this YX band */
		if (bRect.Ymin < regionRectPtr->Ymin)
		{
			dYminTemp = regionRectPtr->Ymin;
			sYminTemp = bsRect.Ymin - (bRect.Ymin - dYminTemp);
		}
		else
		{
			dYminTemp = bRect.Ymin;
			sYminTemp = bsRect.Ymin;
		}

		if (bRect.Ymax > regionRectPtr->Ymax)
		{
			dYmaxTemp = regionRectPtr->Ymax;
			sYmaxTemp = bsRect.Ymax - (bRect.Ymax - dYmaxTemp);
		}
		else
		{
			dYmaxTemp = bRect.Ymax;
			sYmaxTemp = bsRect.Ymax;
		}

		/* skip region rects in this band that are fully to the left of
		dest rect */
		while (bRect.Xmin >= regionRectPtr->Xmax)
		{
			regionRectPtr++;
			/* switch to next band if we just changed bands */
			if (regionRectPtr->Ymin != bandYmin) goto BandBottom;
		}

		/* start clipping and drawing */
		while (bRect.Xmax >= regionRectPtr->Xmin)
		{
			/* set the Y extent of the rectangle to draw (base rect clipped
			to YX band) */
			dRect.Ymin = dYminTemp;
			dRect.Ymax = dYmaxTemp;
			/* set the Y extent of the rectangle from which to draw (base
			source rect clipped to YX band) */
			sRect->Ymin = sYminTemp;
			sRect->Ymax = sYmaxTemp;
			if (bRect.Xmax > regionRectPtr->Xmax)
			{
				dRect.Xmax = regionRectPtr->Xmax;
				sRect->Xmax = bsRect.Xmax - (bRect.Xmax - dRect.Xmax);
			}
			else
			{
				dRect.Xmax = bRect.Xmax;
				sRect->Xmax = bsRect.Xmax;
			}

			if (bRect.Xmin < regionRectPtr->Xmin)
			{
				dRect.Xmin = regionRectPtr->Xmin;
				sRect->Xmin = bsRect.Xmin - (bRect.Xmin - dRect.Xmin);
			}
			else
			{
				dRect.Xmin = bRect.Xmin;
				sRect->Xmin = bsRect.Xmin;
			}

			/* fill the dest rect clipped to the region rect */
			FillDrawer(fcRec);

			regionRectPtr++;
			/* switch to next band if we just changed bands */
			if (regionRectPtr->Ymin != bandYmin) goto BandBottom;
		}

		/* skip region rects in this band that are fully to the right of
		dest rect; basically, scan to the next YX band */
		do {
			regionRectPtr++;
		} while (regionRectPtr->Ymin == bandYmin);

	/* continue as long as the dest rect's bottom is below the region
	rect's top (they overlap vertically) */
BandBottom:
		/* remember top edge of this YX band */
		bandYmin = regionRectPtr->Ymin;
	} while (bRect.Ymax > bandYmin);
	return(1);	/* get next rectangle */

BandFullyBelow:
	if (regionRectPtr->Ymin != 0x7fff) return(0);
	if (lclbfYXBanded != 0) return(1);

	#endif

	return(0);
}


/* Function Fill_Clip_Region fills a rectangle, clipped to a region,
processing the region from top->bottom, and left->right within each band for
non-blit routines.  Returns a 1 if YX banded and there are more rectangles
to draw, else 0.

Parameters:
	fcRec = pointer to blitRcd
	fillRect = pointer rect to draw, already clipped to the clip rect; Ymin
	must be less than 0x7fff

The following regclipv.h common variables are required:
	FillDrawer = routine to call to draw each region-clipped rect
	nextRegionPtr must be set to the point at which to start scanning 
	through the region rect list (on exit, updated to start point for
	scanning next time)
	lclbfYXBanded must be set to !0 if the blitList of rects to draw is YX
	banded, 0 otherwise (used to advance nextRegionPtr, and to exit
	early when possible)
	bXmin, bYmin, bXmax, bYmax, bandYmin, dYminTemp, dYmaxTemp, sYminTemp and
	sYmaxTemp */
int Fill_Clip_Region(blitRcd *fcRec, rect *fillRect)
{
	#ifndef NO_REGION_CLIP
	rect *regionRectPtr;

	regionRectPtr = nextRegionPtr;	/* point to the first region rect at
									which to start clipping */
	/* Find a region band not entirely above dest rect. */
	while (1)
	{
		if (fillRect->Ymin < regionRectPtr->Ymax) break;
		regionRectPtr++;
	}

	/* Start at this point next time if the blitRcd is YX banded. */
	if (lclbfYXBanded != 0) nextRegionPtr = regionRectPtr;

	/* Skip if the band is entirely below dest rect. */
	if (fillRect->Ymax <= regionRectPtr->Ymin)  goto BandFullyBelow;

	/* So long as we're in a band that overlaps vertically with destRect,
	scan across from the left until we find a region rect that overlaps
	horizontally or we move to another band, then draw destRect clipped
	to each region rect until we either find a region rect that doesn't
	overlap or we move to another band, then scan until we move to another
	band. If the next band isn't past the bottom of destRect, repeat. */
	bRect = *fillRect;	/* make a copy of dest rect, because we're going
						to alter the standard copy each time we clip it
						to a region rect */

	/* remember top edge of this YX band */
	bandYmin = regionRectPtr->Ymin;
	do {	/* clipping and drawing loop */
		/* set Y extent of dest rect, clipped to the Y extent of this YX band */
		if (bRect.Ymin < regionRectPtr->Ymin)
		{
			dYminTemp = regionRectPtr->Ymin;
		}
		else
		{
			dYminTemp = bRect.Ymin;
		}

		if (bRect.Ymax > regionRectPtr->Ymax)
		{
			dYmaxTemp = regionRectPtr->Ymax;
		}
		else
		{
			dYmaxTemp = bRect.Ymax;
		}

		/* skip region rects in this band that are fully to the left of
		dest rect */
		while (bRect.Xmin >= regionRectPtr->Xmax)
		{
			regionRectPtr++;
			/* switch to next band if we just changed bands */
			if (regionRectPtr->Ymin != bandYmin) goto BandBottom;
		}

		/* start clipping and drawing */
		while (bRect.Xmax >= regionRectPtr->Xmin)
		{
			/* set the Y extent of the rectangle to draw (base rect clipped
			to YX band) */
			dRect.Ymin = dYminTemp;
			dRect.Ymax = dYmaxTemp;
			if (bRect.Xmax > regionRectPtr->Xmax)
			{
				dRect.Xmax = regionRectPtr->Xmax;
			}
			else
			{
				dRect.Xmax = bRect.Xmax;
			}

			if (bRect.Xmin < regionRectPtr->Xmin)
			{
				dRect.Xmin = regionRectPtr->Xmin;
			}
			else
			{
				dRect.Xmin = bRect.Xmin;
			}

			/* fill the dest rect clipped to the region rect */
			FillDrawer(fcRec);

			regionRectPtr++;
			/* switch to next band if we just changed bands */
			if (regionRectPtr->Ymin != bandYmin) goto BandBottom;
		}

		/* skip region rects in this band that are fully to the right of
		dest rect; basically, scan to the next YX band */
		do {
			regionRectPtr++;
		} while (regionRectPtr->Ymin == bandYmin);

	/* continue as long as the dest rect's bottom is below the region
	rect's top (they overlap vertically) */
BandBottom:
		/* remember top edge of this YX band */
		bandYmin = regionRectPtr->Ymin;
	} while (bRect.Ymax > bandYmin);
	return(1);	/* get next rectangle */

BandFullyBelow:
	if (regionRectPtr->Ymin != 0x7fff) return(0);
	if (lclbfYXBanded != 0) return(1);

	#endif

	return(0);
}


/* Function Set_Up_Clip sets up rectangular and/or region clipping as
specified by the blitRcd clipBlit.

Returns 1 if no drawing to do (region clip specified but region empty, or
both region and rectangular clip specified but rectangle and region extent
have no overlap) else 0.

The following regclipv.h common variables are required:
	clipToRectFlag is set to 0 if no rect clipping, !0 if is rect clipping
	clipToRegionFlag is set to 0 if no region clipping, !0 if is region
	clipping
	nextRegionPtr is set to point to the start of the region rect list
	lclbfYXBanded is set to !0 if the blitList of rects to draw is
	YX banded, 0 otherwise (used to advance nextRegionPtr, and to
	exit early when possible)
	clipR is set to the clip rect (intersection of clip rect and region
	extent if both active)
	if BLIT_MAY_OVERLAP is TRUE, nextRegionPtrB is set by this macro to
	point to the end of the region rect list */
int Set_Up_Clip(blitRcd *clipBlit, rect *clipR, int blitMayOverlap,
				int isLine)
{

	if(isLine)
	{
		lclbfYXBanded = 0;	/* lines are never YX banded */
	}
	else
	{	/* 0 if not YX banded, !0 if is */
		lclbfYXBanded = clipBlit->blitFlags & bfYXBanded;
	}

	clipToRectFlag = clipBlit->blitFlags & bfClipRect;
	if (clipToRectFlag != 0)
	{	/* rect clipping; copy over the clip rect */
		*clipR = *clipBlit->blitClip;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -