📄 rect6.c
字号:
/*************************************************************************/
/* */
/* 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 */
/* */
/* RECT6.c 1.9 */
/* */
/* COMPONENT */
/* */
/* All */
/* */
/* DESCRIPTION */
/* */
/* This file contains the PaintRoundRect function. */
/* */
/* AUTHOR */
/* */
/* Robert G. Burrill, Accelerated Technology, Inc. */
/* */
/* DATA STRUCTURES */
/* */
/* None */
/* */
/* FUNCTIONS */
/* */
/* None */
/* */
/* DEPENDENCIES */
/* */
/* None */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* */
/*************************************************************************/
#include "meta_wnd.h"
#include "metconst.h" /* MetaWINDOW Constant & Stucture Definitions */
#include "metports.h" /* MetaWINDOW Port & Bitmap Definitions */
#include "grafdata.h"
#include "metmacs3.h"
#include "xpol_4.h"
/* Function PaintRoundRect fills the specified rounded rectangle defined by
rectangle argR with corner diameters DiaX and DiaY using the current pen pattern
(pnPat) and pen rasterOp mode (pnMode). The current "pen" position is not
affected by PaintRoundRect. */
void PaintRoundRect(rect *argR, int DiaX, int DiaY)
{
void mwSTQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB);
void mwScanGET(void **GETPtrPtr, blitRcd *fillRcd, int scanRcdSize, int shape,
int fillRule, int allEdgesAreLines);
void mwSBQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB);
void mwSV(Vedge *VLEdge, int VLX, int VLY, int VLHeight, int VLDir);
void AddToGETYXSorted(qarcState *newEdge);
short grafErrValue; /* error value */
int i;
qarcState *newEdge; /* pointer to new edge to add to table */
argDiaX = DiaX; /* get passed parameters */
argDiaY = DiaY;
for (i = 0; i < 12; i++) qaEdgeBuffer[i].NextEdge = 0; /* GET is initially empty */
if (grafPort.pnLevel < 0) return; /* nothing to do */
if (grafPort.portFlags & pfVirtual) /* check if virtual mode */
{
V2GSIZE(argDiaX, argDiaY, &argDiaX, &argDiaY); /* Virtual To Global size */
}
rXmin = *argR; /* get rectangle */
if (globalLevel > 0)
{
/* convert from user to global */
U2GR(rXmin, &rXmin, 0);
}
rXWidth = rXmin.Xmax - rXmin.Xmin; /* width */
if (rXWidth < 0)
{
grafErrValue = c_PaintRou + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
return;
}
rXHeight = rXmin.Ymax - rXmin.Ymin; /* height */
if (rXHeight < 0)
{
grafErrValue = c_PaintRou + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
return;
}
/* if either corner diameter is greater than the corresponding rectangle
dimension, limit it to the rectangle dimension */
if (argDiaX < rXWidth) rXWidth = argDiaX; /* use diameter */
if (argDiaY < rXHeight) rXHeight = argDiaY; /* use diameter */
xRadius = (rXWidth >> 1);
yRadius = (rXHeight >> 1);
thisLeftEdge = rXmin.Xmin + xRadius; /* left edge + height */
nextTopEdge = rXmin.Ymin + yRadius; /* top edge + height */
thisRightEdge = rXmin.Xmax - xRadius; /* right edge + height */
nextBottomEdge = rXmin.Ymax - yRadius - 1; /* bottom edge - height
-1 for filling */
/* set up the upper left arc */
GETPtr = &qaEdgeBuffer[0];
newEdge = GETPtr;
mwSTQA(newEdge, xRadius, yRadius, thisLeftEdge, nextTopEdge, -1, -1);
/* set up the upper right arc */
newEdge = &qaEdgeBuffer[1];
mwSTQA(newEdge, xRadius, yRadius, thisRightEdge, nextTopEdge, 1, 1);
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
/* now add the bottom arcs, with the top points trimmed off to avoid
overlap problems */
if (qaEdgeBuffer[0].Count != 1) /*are arcs only one scan line high? */
{ /* no */
newEdge = &qaEdgeBuffer[2];
mwSBQA(newEdge, xRadius, yRadius, thisLeftEdge, nextBottomEdge, 1, -1);
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
newEdge->StartY++; /* start on the next scan line */
newEdge->Count--; /* skip the topmost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
/* advance bottom arcs by one scan line to avoid overlap problems (skip
the top scan line, which can stick out too far and always overlaps with
the top quadrant arcs anyway) */
/* set up the lower right arc */
newEdge = &qaEdgeBuffer[3];
mwSBQA(newEdge, xRadius, yRadius, thisRightEdge, nextBottomEdge, -1, 1);
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
newEdge->StartY++; /* start on the next scan line */
newEdge->Count--; /* skip the topmost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
}
/* now add the vertical outer sides, if applicable */
nextTopEdge = rXmin.Ymin + yRadius + 1; /* start on the scan line after
the top arc ends */
nextBottomEdge = rXmin.Ymax - yRadius; /* top of bottom arc */
if (nextBottomEdge > nextTopEdge)
{ /* add the vertical edges */
nextBottomEdge -= nextTopEdge; /* distance between top & bottom, not inclusive */
newEdge = &qaEdgeBuffer[4];
mwSV((Vedge *)newEdge, rXmin.Xmin, nextTopEdge, nextBottomEdge, -1);
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
vertDirection = -vertDirection; /* reverse direction for other side */
newEdge = &qaEdgeBuffer[5];
mwSV((Vedge *)newEdge, rXmin.Xmax, nextTopEdge, nextBottomEdge, 1);
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
}
/* draw the oval and done! */
mwScanGET((void **)&GETPtr, (blitRcd *)&rFillRcd[0], fillRcdSize, cmplx, 1, 0);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -