📄 oval0.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 */
/* */
/* OVAL0.c 1.9 */
/* */
/* COMPONENT */
/* */
/* All */
/* */
/* DESCRIPTION */
/* */
/* This file contains the FrameOval function. */
/* */
/* AUTHOR */
/* */
/* Robert G. Burrill, Accelerated Technology, Inc. */
/* */
/* DATA STRUCTURES */
/* */
/* None */
/* */
/* FUNCTIONS */
/* */
/* None */
/* */
/* DEPENDENCIES */
/* */
/* None */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* BobB 5/12/99 Corrected inner radii for wide pen */
/* */
/*************************************************************************/
#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"
/* Procedure AddOuterEdgesO builds a GET containing a set of 4 outer edges. */
void AddOuterEdgesO(qarcState *newEdge)
{
void mwSTQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB);
void AddToGETYXSorted(qarcState *newEdge);
void mwSBQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB);
thisLeftEdge = rXmin.Xmin + xRadius; /* left edge + height */
nextTopEdge = rXmin.Ymin + yRadius; /* top edge + height */
thisRightEdge = rXmin.Xmax - xRadius + 1; /* shift right by 1 to compensate for
the filler not drawing right edges */
nextBottomEdge = rXmin.Ymax - yRadius; /* bottom edge - height */
/* 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 */
/* set up the lower left arc */
newEdge = &qaEdgeBuffer[2];
mwSBQA(newEdge, xRadius, yRadius, thisLeftEdge, nextBottomEdge, 1, -1);
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
/* set up the upper right arc */
newEdge = &qaEdgeBuffer[3];
mwSBQA(newEdge, xRadius, yRadius, thisRightEdge, nextBottomEdge, -1, 1);
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
return;
}
/* Function FrameOval draws an outline of the elliptical oval contained within
rectangle ovalR. The current "pen" position is not affected by FrameOval. */
void FrameOval(rect *ovalR)
{
void mwSTQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB);
void AddToGETYXSorted(qarcState *newEdge);
void mwSBQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB);
void mwFDA(rect *boundR, int BANGLE, int AANGLE);
void mwScanGET(void **GETPtrPtr, blitRcd *fillRcd, int scanRcdSize, int shape,
int fillRule, int allEdgesAreLines);
rect rXminBase; /* base rectangle */
short grafErrValue; /* error value */
short halfWidth; /* offsets to edges of square pen */
short halfHeight;
int i;
qarcState *newEdge = 0; /* pointer to new edge to add to table */
for (i = 0; i < 12; i++) qaEdgeBuffer[i].NextEdge = 0; /* GET is initially empty */
if (grafPort.pnLevel < 0) return; /* nothing to do */
if (grafPort.pnFlags & pnDashFlg) /* is it dashed? */
{ /* yes, handle it elsewhere */
mwFDA(ovalR, 0, 3600);
return;
}
rXmin = *ovalR; /* get rectangle */
if (globalLevel > 0)
{
/* convert from user to global */
U2GR(rXmin, &rXmin, 1);
}
if (!(grafPort.pnFlags & pnSizeFlg)) /* thin or wide line? */
{ /* thin */
rXWidth = rXmin.Xmax - rXmin.Xmin; /* width */
if (rXWidth < 0)
{
grafErrValue = c_FrameOva + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
return;
}
rXHeight = rXmin.Ymax - rXmin.Ymin; /* height */
if (rXHeight < 0)
{
grafErrValue = c_FrameOva + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
return;
}
xRadius = (rXWidth >> 1); /* calculate radii */
yRadius = (rXHeight >> 1);
AddOuterEdgesO(newEdge); /* set up the outer edges first */
/* if the outer arcs are flat, the current GET is all we need */
if (qaEdgeBuffer[0].Count != 1)
{ /* need inner edges too */
qaEdgeBuffer[4] = qaEdgeBuffer[0]; /* copy the outer arcs */
qaEdgeBuffer[5] = qaEdgeBuffer[1]; /* to the inner arcs */
qaEdgeBuffer[6] = qaEdgeBuffer[2];
qaEdgeBuffer[7] = qaEdgeBuffer[3];
/* flip arc top->bottom so this can work with the outer arc */
newEdge = &qaEdgeBuffer[4];
qaEdgeBuffer[4].TopToBottom = -qaEdgeBuffer[4].TopToBottom;
qaEdgeBuffer[4].CurrentX++; /* shift 1 to the right */
qaEdgeBuffer[4].StartY++; /* shift down 1 */
qaEdgeBuffer[4].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[5];
qaEdgeBuffer[5].TopToBottom = -qaEdgeBuffer[5].TopToBottom;
qaEdgeBuffer[5].CurrentX--; /* shift 1 to the left */
qaEdgeBuffer[5].StartY++; /* shift down 1 */
qaEdgeBuffer[5].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[6];
qaEdgeBuffer[6].TopToBottom = -qaEdgeBuffer[6].TopToBottom;
qaEdgeBuffer[6].CurrentX++; /* shift 1 to the right */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
qaEdgeBuffer[6].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[7];
qaEdgeBuffer[7].TopToBottom = -qaEdgeBuffer[7].TopToBottom;
qaEdgeBuffer[7].CurrentX--; /* shift 1 to the left */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
qaEdgeBuffer[7].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
}
}
else
{ /* wide */
/* Draws a wide-line framed oval. The approach is the same as for thin
framed ovals, except that the outer arcs are moved out by the X and Y
pen radii, and the inner arcs are moved in similarly. */
rXminBase = rXmin;
/* For odd pen dimensions, we can be symmetric about the thin edge. For
even, we bias the extra pixel to the outside of the frame. */
/* set up the four outer arcs first and rounded up */
halfWidth = (grafPort.pnSize.X >> 1);
rXmin.Xmin -= halfWidth;
rXmin.Xmax += halfWidth;
halfHeight = (grafPort.pnSize.Y >> 1);
rXmin.Ymin -= halfHeight;
rXmin.Ymax += halfHeight;
rXWidth = rXmin.Xmax - rXmin.Xmin; /* width */
if (rXWidth < 0)
{
grafErrValue = c_FrameOva + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
return;
}
rXHeight = rXmin.Ymax - rXmin.Ymin; /* height */
if (rXHeight < 0)
{
grafErrValue = c_FrameOva + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
return;
}
xRadius = (rXWidth >> 1); /* calculate radii */
yRadius = (rXHeight >> 1);
AddOuterEdgesO(newEdge); /* set up the outer edges first */
/* if the outer arcs are flat, the current GET is all we need */
if (qaEdgeBuffer[0].Count != 1)
{ /* need inner edges too */
/*Inner arcs are pulled in from frame edge by pen radii. For odd
pen dimensions, we can be symmetric between inner and outer edge
displacements. For even pen dimensions, we bias the extra pixel
to the outside. */
halfWidth = ((grafPort.pnSize.X - 1) >> 1);
rXmin.Xmin = rXminBase.Xmin + halfWidth;
rXmin.Xmax = rXminBase.Xmax - halfWidth;
halfHeight = ((grafPort.pnSize.Y - 1) >> 1);
rXmin.Ymin = rXminBase.Ymin + halfHeight;
rXmin.Ymax = rXminBase.Ymax - halfHeight;
rXWidth = rXmin.Xmax - rXmin.Xmin; /* width */
rXHeight = rXmin.Ymax - rXmin.Ymin; /* height */
if ((rXWidth > 0) && (rXHeight > 0))
{
/* BobB 5/12/99 - added the following 2 lines to get correct inner radius */
xRadius = (rXWidth >> 1); /* calculate radii */
yRadius = (rXHeight >> 1);
thisLeftEdge = rXmin.Xmin + xRadius; /* left edge + height */
nextTopEdge = rXmin.Ymin + yRadius; /* top edge + height */
thisRightEdge = rXmin.Xmax - xRadius + 1; /* shift right by 1 to
compensate for the filler not drawing right edges */
nextBottomEdge = rXmin.Ymax - yRadius; /* bottom edge - height */
/* set up the upper left arc */
newEdge = &qaEdgeBuffer[4];
mwSTQA(newEdge, xRadius, yRadius, thisLeftEdge, nextTopEdge, -1, 1);
/* set up the upper right arc */
newEdge = &qaEdgeBuffer[5];
mwSTQA(newEdge, xRadius, yRadius, thisRightEdge, nextTopEdge, 1, -1);
/* set up the lower left arc */
newEdge = &qaEdgeBuffer[6];
mwSBQA(newEdge, xRadius, yRadius, thisLeftEdge, nextBottomEdge, 1, 1);
/* set up the upper right arc */
newEdge = &qaEdgeBuffer[7];
mwSBQA(newEdge, xRadius, yRadius, thisRightEdge, nextBottomEdge, -1, -1);
/* Now shift the edges down and right 1, to compensate for filler
characteristics and to make 1 wide be really 1 wide, and add to the GET. */
newEdge = &qaEdgeBuffer[4];
newEdge->CurrentX++; /* shift 1 to the right */
newEdge->StartY++; /* shift down 1 */
newEdge->Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[5];
newEdge->CurrentX--; /* shift 1 to the left */
newEdge->StartY++; /* shift down 1 */
newEdge->Count--;
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[6];
newEdge->CurrentX++; /* shift 1 to the right */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
newEdge->Count--;
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[7];
newEdge->CurrentX--; /* shift 1 to the left */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
newEdge->Count--; /* skip the topmost point */
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 + -