sync code with last improvements from OpenBSD
This commit is contained in:
commit
88965415ff
26235 changed files with 29195616 additions and 0 deletions
767
xserver/mi/mizerarc.c
Normal file
767
xserver/mi/mizerarc.c
Normal file
|
@ -0,0 +1,767 @@
|
|||
/************************************************************
|
||||
|
||||
Copyright 1989, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Author: Bob Scheifler, MIT X Consortium
|
||||
|
||||
********************************************************/
|
||||
|
||||
/* Derived from:
|
||||
* "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
|
||||
* by M. L. V. Pitteway
|
||||
* The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xprotostr.h>
|
||||
#include "regionstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "mi.h"
|
||||
#include "mizerarc.h"
|
||||
|
||||
#define FULLCIRCLE (360 * 64)
|
||||
#define OCTANT (45 * 64)
|
||||
#define QUADRANT (90 * 64)
|
||||
#define HALFCIRCLE (180 * 64)
|
||||
#define QUADRANT3 (270 * 64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define Dsin(d) ((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \
|
||||
((d) == HALFCIRCLE ? 0.0 : \
|
||||
((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0))))))
|
||||
|
||||
#define Dcos(d) ((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \
|
||||
((d) == HALFCIRCLE ? -1.0 : \
|
||||
((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0))))))
|
||||
|
||||
#define EPSILON45 64
|
||||
|
||||
typedef struct {
|
||||
int skipStart;
|
||||
int haveStart;
|
||||
DDXPointRec startPt;
|
||||
int haveLast;
|
||||
int skipLast;
|
||||
DDXPointRec endPt;
|
||||
int dashIndex;
|
||||
int dashOffset;
|
||||
int dashIndexInit;
|
||||
int dashOffsetInit;
|
||||
} DashInfo;
|
||||
|
||||
static miZeroArcPtRec oob = { 65536, 65536, 0 };
|
||||
|
||||
/*
|
||||
* (x - l)^2 / (W/2)^2 + (y + H/2)^2 / (H/2)^2 = 1
|
||||
*
|
||||
* where l is either 0 or .5
|
||||
*
|
||||
* alpha = 4(W^2)
|
||||
* beta = 4(H^2)
|
||||
* gamma = 0
|
||||
* u = 2(W^2)H
|
||||
* v = 4(H^2)l
|
||||
* k = -4(H^2)(l^2)
|
||||
*
|
||||
*/
|
||||
|
||||
Bool
|
||||
miZeroArcSetup(xArc * arc, miZeroArcRec * info, Bool ok360)
|
||||
{
|
||||
int l;
|
||||
int angle1, angle2;
|
||||
int startseg, endseg;
|
||||
int startAngle, endAngle;
|
||||
int i, overlap;
|
||||
miZeroArcPtRec start, end;
|
||||
|
||||
l = arc->width & 1;
|
||||
if (arc->width == arc->height) {
|
||||
info->alpha = 4;
|
||||
info->beta = 4;
|
||||
info->k1 = -8;
|
||||
info->k3 = -16;
|
||||
info->b = 12;
|
||||
info->a = (arc->width << 2) - 12;
|
||||
info->d = 17 - (arc->width << 1);
|
||||
if (l) {
|
||||
info->b -= 4;
|
||||
info->a += 4;
|
||||
info->d -= 7;
|
||||
}
|
||||
}
|
||||
else if (!arc->width || !arc->height) {
|
||||
info->alpha = 0;
|
||||
info->beta = 0;
|
||||
info->k1 = 0;
|
||||
info->k3 = 0;
|
||||
info->a = -(int) arc->height;
|
||||
info->b = 0;
|
||||
info->d = -1;
|
||||
}
|
||||
else {
|
||||
/* initial conditions */
|
||||
info->alpha = (arc->width * arc->width) << 2;
|
||||
info->beta = (arc->height * arc->height) << 2;
|
||||
info->k1 = info->beta << 1;
|
||||
info->k3 = info->k1 + (info->alpha << 1);
|
||||
info->b = l ? 0 : -info->beta;
|
||||
info->a = info->alpha * arc->height;
|
||||
info->d = info->b - (info->a >> 1) - (info->alpha >> 2);
|
||||
if (l)
|
||||
info->d -= info->beta >> 2;
|
||||
info->a -= info->b;
|
||||
/* take first step, d < 0 always */
|
||||
info->b -= info->k1;
|
||||
info->a += info->k1;
|
||||
info->d += info->b;
|
||||
/* octant change, b < 0 always */
|
||||
info->k1 = -info->k1;
|
||||
info->k3 = -info->k3;
|
||||
info->b = -info->b;
|
||||
info->d = info->b - info->a - info->d;
|
||||
info->a = info->a - (info->b << 1);
|
||||
}
|
||||
info->dx = 1;
|
||||
info->dy = 0;
|
||||
info->w = (arc->width + 1) >> 1;
|
||||
info->h = arc->height >> 1;
|
||||
info->xorg = arc->x + (arc->width >> 1);
|
||||
info->yorg = arc->y;
|
||||
info->xorgo = info->xorg + l;
|
||||
info->yorgo = info->yorg + arc->height;
|
||||
if (!arc->width) {
|
||||
if (!arc->height) {
|
||||
info->x = 0;
|
||||
info->y = 0;
|
||||
info->initialMask = 0;
|
||||
info->startAngle = 0;
|
||||
info->endAngle = 0;
|
||||
info->start = oob;
|
||||
info->end = oob;
|
||||
return FALSE;
|
||||
}
|
||||
info->x = 0;
|
||||
info->y = 1;
|
||||
}
|
||||
else {
|
||||
info->x = 1;
|
||||
info->y = 0;
|
||||
}
|
||||
angle1 = arc->angle1;
|
||||
angle2 = arc->angle2;
|
||||
if ((angle1 == 0) && (angle2 >= FULLCIRCLE)) {
|
||||
startAngle = 0;
|
||||
endAngle = 0;
|
||||
}
|
||||
else {
|
||||
if (angle2 > FULLCIRCLE)
|
||||
angle2 = FULLCIRCLE;
|
||||
else if (angle2 < -FULLCIRCLE)
|
||||
angle2 = -FULLCIRCLE;
|
||||
if (angle2 < 0) {
|
||||
startAngle = angle1 + angle2;
|
||||
endAngle = angle1;
|
||||
}
|
||||
else {
|
||||
startAngle = angle1;
|
||||
endAngle = angle1 + angle2;
|
||||
}
|
||||
if (startAngle < 0)
|
||||
startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
|
||||
if (startAngle >= FULLCIRCLE)
|
||||
startAngle = startAngle % FULLCIRCLE;
|
||||
if (endAngle < 0)
|
||||
endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
|
||||
if (endAngle >= FULLCIRCLE)
|
||||
endAngle = endAngle % FULLCIRCLE;
|
||||
}
|
||||
info->startAngle = startAngle;
|
||||
info->endAngle = endAngle;
|
||||
if (ok360 && (startAngle == endAngle) && arc->angle2 &&
|
||||
arc->width && arc->height) {
|
||||
info->initialMask = 0xf;
|
||||
info->start = oob;
|
||||
info->end = oob;
|
||||
return TRUE;
|
||||
}
|
||||
startseg = startAngle / OCTANT;
|
||||
if (!arc->height || (((startseg + 1) & 2) && arc->width)) {
|
||||
start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0);
|
||||
if (start.x < 0)
|
||||
start.x = -start.x;
|
||||
start.y = -1;
|
||||
}
|
||||
else {
|
||||
start.y = Dsin(startAngle) * (arc->height / 2.0);
|
||||
if (start.y < 0)
|
||||
start.y = -start.y;
|
||||
start.y = info->h - start.y;
|
||||
start.x = 65536;
|
||||
}
|
||||
endseg = endAngle / OCTANT;
|
||||
if (!arc->height || (((endseg + 1) & 2) && arc->width)) {
|
||||
end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0);
|
||||
if (end.x < 0)
|
||||
end.x = -end.x;
|
||||
end.y = -1;
|
||||
}
|
||||
else {
|
||||
end.y = Dsin(endAngle) * (arc->height / 2.0);
|
||||
if (end.y < 0)
|
||||
end.y = -end.y;
|
||||
end.y = info->h - end.y;
|
||||
end.x = 65536;
|
||||
}
|
||||
info->firstx = start.x;
|
||||
info->firsty = start.y;
|
||||
info->initialMask = 0;
|
||||
overlap = arc->angle2 && (endAngle <= startAngle);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (overlap ?
|
||||
((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) :
|
||||
((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle)))
|
||||
info->initialMask |= (1 << i);
|
||||
}
|
||||
start.mask = info->initialMask;
|
||||
end.mask = info->initialMask;
|
||||
startseg >>= 1;
|
||||
endseg >>= 1;
|
||||
overlap = overlap && (endseg == startseg);
|
||||
if (start.x != end.x || start.y != end.y || !overlap) {
|
||||
if (startseg & 1) {
|
||||
if (!overlap)
|
||||
info->initialMask &= ~(1 << startseg);
|
||||
if (start.x > end.x || start.y > end.y)
|
||||
end.mask &= ~(1 << startseg);
|
||||
}
|
||||
else {
|
||||
start.mask &= ~(1 << startseg);
|
||||
if (((start.x < end.x || start.y < end.y) ||
|
||||
(start.x == end.x && start.y == end.y && (endseg & 1))) &&
|
||||
!overlap)
|
||||
end.mask &= ~(1 << startseg);
|
||||
}
|
||||
if (endseg & 1) {
|
||||
end.mask &= ~(1 << endseg);
|
||||
if (((start.x > end.x || start.y > end.y) ||
|
||||
(start.x == end.x && start.y == end.y && !(startseg & 1))) &&
|
||||
!overlap)
|
||||
start.mask &= ~(1 << endseg);
|
||||
}
|
||||
else {
|
||||
if (!overlap)
|
||||
info->initialMask &= ~(1 << endseg);
|
||||
if (start.x < end.x || start.y < end.y)
|
||||
start.mask &= ~(1 << endseg);
|
||||
}
|
||||
}
|
||||
/* take care of case when start and stop are both near 45 */
|
||||
/* handle here rather than adding extra code to pixelization loops */
|
||||
if (startAngle &&
|
||||
((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0))) {
|
||||
i = (startAngle + OCTANT) % OCTANT;
|
||||
if (i < EPSILON45 || i > OCTANT - EPSILON45) {
|
||||
i = (endAngle + OCTANT) % OCTANT;
|
||||
if (i < EPSILON45 || i > OCTANT - EPSILON45) {
|
||||
if (start.y < 0) {
|
||||
i = Dsin(startAngle) * (arc->height / 2.0);
|
||||
if (i < 0)
|
||||
i = -i;
|
||||
if (info->h - i == end.y)
|
||||
start.mask = end.mask;
|
||||
}
|
||||
else {
|
||||
i = Dsin(endAngle) * (arc->height / 2.0);
|
||||
if (i < 0)
|
||||
i = -i;
|
||||
if (info->h - i == start.y)
|
||||
end.mask = start.mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (startseg & 1) {
|
||||
info->start = start;
|
||||
info->end = oob;
|
||||
}
|
||||
else {
|
||||
info->end = start;
|
||||
info->start = oob;
|
||||
}
|
||||
if (endseg & 1) {
|
||||
info->altend = end;
|
||||
if (info->altend.x < info->end.x || info->altend.y < info->end.y) {
|
||||
miZeroArcPtRec tmp;
|
||||
|
||||
tmp = info->altend;
|
||||
info->altend = info->end;
|
||||
info->end = tmp;
|
||||
}
|
||||
info->altstart = oob;
|
||||
}
|
||||
else {
|
||||
info->altstart = end;
|
||||
if (info->altstart.x < info->start.x ||
|
||||
info->altstart.y < info->start.y) {
|
||||
miZeroArcPtRec tmp;
|
||||
|
||||
tmp = info->altstart;
|
||||
info->altstart = info->start;
|
||||
info->start = tmp;
|
||||
}
|
||||
info->altend = oob;
|
||||
}
|
||||
if (!info->start.x || !info->start.y) {
|
||||
info->initialMask = info->start.mask;
|
||||
info->start = info->altstart;
|
||||
}
|
||||
if (!arc->width && (arc->height == 1)) {
|
||||
/* kludge! */
|
||||
info->initialMask |= info->end.mask;
|
||||
info->initialMask |= info->initialMask << 1;
|
||||
info->end.x = 0;
|
||||
info->end.mask = 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define Pixelate(xval,yval) \
|
||||
{ \
|
||||
pts->x = xval; \
|
||||
pts->y = yval; \
|
||||
pts++; \
|
||||
}
|
||||
|
||||
#define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval);
|
||||
|
||||
static DDXPointPtr
|
||||
miZeroArcPts(xArc * arc, DDXPointPtr pts)
|
||||
{
|
||||
miZeroArcRec info;
|
||||
int x, y, a, b, d, mask;
|
||||
int k1, k3, dx, dy;
|
||||
Bool do360;
|
||||
|
||||
do360 = miZeroArcSetup(arc, &info, TRUE);
|
||||
MIARCSETUP();
|
||||
mask = info.initialMask;
|
||||
if (!(arc->width & 1)) {
|
||||
DoPix(1, info.xorgo, info.yorg);
|
||||
DoPix(3, info.xorgo, info.yorgo);
|
||||
}
|
||||
if (!info.end.x || !info.end.y) {
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
|
||||
int yorgh = info.yorg + info.h;
|
||||
int xorghp = info.xorg + info.h;
|
||||
int xorghn = info.xorg - info.h;
|
||||
|
||||
while (1) {
|
||||
Pixelate(info.xorg + x, info.yorg + y);
|
||||
Pixelate(info.xorg - x, info.yorg + y);
|
||||
Pixelate(info.xorg - x, info.yorgo - y);
|
||||
Pixelate(info.xorg + x, info.yorgo - y);
|
||||
if (a < 0)
|
||||
break;
|
||||
Pixelate(xorghp - y, yorgh - x);
|
||||
Pixelate(xorghn + y, yorgh - x);
|
||||
Pixelate(xorghn + y, yorgh + x);
|
||||
Pixelate(xorghp - y, yorgh + x);
|
||||
MIARCCIRCLESTEP(;
|
||||
);
|
||||
}
|
||||
if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y)
|
||||
pts -= 4;
|
||||
x = info.w;
|
||||
y = info.h;
|
||||
}
|
||||
else if (do360) {
|
||||
while (y < info.h || x < info.w) {
|
||||
MIARCOCTANTSHIFT(;
|
||||
);
|
||||
Pixelate(info.xorg + x, info.yorg + y);
|
||||
Pixelate(info.xorgo - x, info.yorg + y);
|
||||
Pixelate(info.xorgo - x, info.yorgo - y);
|
||||
Pixelate(info.xorg + x, info.yorgo - y);
|
||||
MIARCSTEP(;
|
||||
,;
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (y < info.h || x < info.w) {
|
||||
MIARCOCTANTSHIFT(;
|
||||
);
|
||||
if ((x == info.start.x) || (y == info.start.y)) {
|
||||
mask = info.start.mask;
|
||||
info.start = info.altstart;
|
||||
}
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
if ((x == info.end.x) || (y == info.end.y)) {
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
MIARCSTEP(;
|
||||
,;
|
||||
);
|
||||
}
|
||||
}
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
mask = info.start.mask;
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
if (arc->height & 1) {
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
#undef DoPix
|
||||
#define DoPix(idx,xval,yval) \
|
||||
if (mask & (1 << idx)) \
|
||||
{ \
|
||||
arcPts[idx]->x = xval; \
|
||||
arcPts[idx]->y = yval; \
|
||||
arcPts[idx]++; \
|
||||
}
|
||||
|
||||
static void
|
||||
miZeroArcDashPts(GCPtr pGC,
|
||||
xArc * arc,
|
||||
DashInfo * dinfo,
|
||||
DDXPointPtr points,
|
||||
int maxPts, DDXPointPtr * evenPts, DDXPointPtr * oddPts)
|
||||
{
|
||||
miZeroArcRec info;
|
||||
int x, y, a, b, d, mask;
|
||||
int k1, k3, dx, dy;
|
||||
int dashRemaining;
|
||||
DDXPointPtr arcPts[4];
|
||||
DDXPointPtr startPts[5], endPts[5];
|
||||
int deltas[5];
|
||||
DDXPointPtr startPt, pt, lastPt, pts;
|
||||
int i, j, delta, ptsdelta, seg, startseg;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
arcPts[i] = points + (i * maxPts);
|
||||
(void) miZeroArcSetup(arc, &info, FALSE);
|
||||
MIARCSETUP();
|
||||
mask = info.initialMask;
|
||||
startseg = info.startAngle / QUADRANT;
|
||||
startPt = arcPts[startseg];
|
||||
if (!(arc->width & 1)) {
|
||||
DoPix(1, info.xorgo, info.yorg);
|
||||
DoPix(3, info.xorgo, info.yorgo);
|
||||
}
|
||||
if (!info.end.x || !info.end.y) {
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
while (y < info.h || x < info.w) {
|
||||
MIARCOCTANTSHIFT(;
|
||||
);
|
||||
if ((x == info.firstx) || (y == info.firsty))
|
||||
startPt = arcPts[startseg];
|
||||
if ((x == info.start.x) || (y == info.start.y)) {
|
||||
mask = info.start.mask;
|
||||
info.start = info.altstart;
|
||||
}
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
if ((x == info.end.x) || (y == info.end.y)) {
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
MIARCSTEP(;
|
||||
,;
|
||||
);
|
||||
}
|
||||
if ((x == info.firstx) || (y == info.firsty))
|
||||
startPt = arcPts[startseg];
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
mask = info.start.mask;
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
if (arc->height & 1) {
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
seg = (startseg + i) & 3;
|
||||
pt = points + (seg * maxPts);
|
||||
if (seg & 1) {
|
||||
startPts[i] = pt;
|
||||
endPts[i] = arcPts[seg];
|
||||
deltas[i] = 1;
|
||||
}
|
||||
else {
|
||||
startPts[i] = arcPts[seg] - 1;
|
||||
endPts[i] = pt - 1;
|
||||
deltas[i] = -1;
|
||||
}
|
||||
}
|
||||
startPts[4] = startPts[0];
|
||||
endPts[4] = startPt;
|
||||
startPts[0] = startPt;
|
||||
if (startseg & 1) {
|
||||
if (startPts[4] != endPts[4])
|
||||
endPts[4]--;
|
||||
deltas[4] = 1;
|
||||
}
|
||||
else {
|
||||
if (startPts[0] > startPts[4])
|
||||
startPts[0]--;
|
||||
if (startPts[4] < endPts[4])
|
||||
endPts[4]--;
|
||||
deltas[4] = -1;
|
||||
}
|
||||
if (arc->angle2 < 0) {
|
||||
DDXPointPtr tmps, tmpe;
|
||||
int tmpd;
|
||||
|
||||
tmpd = deltas[0];
|
||||
tmps = startPts[0] - tmpd;
|
||||
tmpe = endPts[0] - tmpd;
|
||||
startPts[0] = endPts[4] - deltas[4];
|
||||
endPts[0] = startPts[4] - deltas[4];
|
||||
deltas[0] = -deltas[4];
|
||||
startPts[4] = tmpe;
|
||||
endPts[4] = tmps;
|
||||
deltas[4] = -tmpd;
|
||||
tmpd = deltas[1];
|
||||
tmps = startPts[1] - tmpd;
|
||||
tmpe = endPts[1] - tmpd;
|
||||
startPts[1] = endPts[3] - deltas[3];
|
||||
endPts[1] = startPts[3] - deltas[3];
|
||||
deltas[1] = -deltas[3];
|
||||
startPts[3] = tmpe;
|
||||
endPts[3] = tmps;
|
||||
deltas[3] = -tmpd;
|
||||
tmps = startPts[2] - deltas[2];
|
||||
startPts[2] = endPts[2] - deltas[2];
|
||||
endPts[2] = tmps;
|
||||
deltas[2] = -deltas[2];
|
||||
}
|
||||
for (i = 0; i < 5 && startPts[i] == endPts[i]; i++);
|
||||
if (i == 5)
|
||||
return;
|
||||
pt = startPts[i];
|
||||
for (j = 4; startPts[j] == endPts[j]; j--);
|
||||
lastPt = endPts[j] - deltas[j];
|
||||
if (dinfo->haveLast &&
|
||||
(pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y)) {
|
||||
startPts[i] += deltas[i];
|
||||
}
|
||||
else {
|
||||
dinfo->dashIndex = dinfo->dashIndexInit;
|
||||
dinfo->dashOffset = dinfo->dashOffsetInit;
|
||||
}
|
||||
if (!dinfo->skipStart && (info.startAngle != info.endAngle)) {
|
||||
dinfo->startPt = *pt;
|
||||
dinfo->haveStart = TRUE;
|
||||
}
|
||||
else if (!dinfo->skipLast && dinfo->haveStart &&
|
||||
(lastPt->x == dinfo->startPt.x) &&
|
||||
(lastPt->y == dinfo->startPt.y) && (lastPt != startPts[i]))
|
||||
endPts[j] = lastPt;
|
||||
if (info.startAngle != info.endAngle) {
|
||||
dinfo->haveLast = TRUE;
|
||||
dinfo->endPt = *lastPt;
|
||||
}
|
||||
dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset;
|
||||
for (i = 0; i < 5; i++) {
|
||||
pt = startPts[i];
|
||||
lastPt = endPts[i];
|
||||
delta = deltas[i];
|
||||
while (pt != lastPt) {
|
||||
if (dinfo->dashIndex & 1) {
|
||||
pts = *oddPts;
|
||||
ptsdelta = -1;
|
||||
}
|
||||
else {
|
||||
pts = *evenPts;
|
||||
ptsdelta = 1;
|
||||
}
|
||||
while ((pt != lastPt) && --dashRemaining >= 0) {
|
||||
*pts = *pt;
|
||||
pts += ptsdelta;
|
||||
pt += delta;
|
||||
}
|
||||
if (dinfo->dashIndex & 1)
|
||||
*oddPts = pts;
|
||||
else
|
||||
*evenPts = pts;
|
||||
if (dashRemaining <= 0) {
|
||||
if (++(dinfo->dashIndex) == pGC->numInDashList)
|
||||
dinfo->dashIndex = 0;
|
||||
dashRemaining = pGC->dash[dinfo->dashIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining;
|
||||
}
|
||||
|
||||
void
|
||||
miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||
{
|
||||
int maxPts = 0;
|
||||
int n, maxw = 0;
|
||||
xArc *arc;
|
||||
int i;
|
||||
DDXPointPtr points, pts, oddPts = NULL;
|
||||
DDXPointPtr pt;
|
||||
int numPts;
|
||||
Bool dospans;
|
||||
int *widths = NULL;
|
||||
XID fgPixel = pGC->fgPixel;
|
||||
DashInfo dinfo;
|
||||
|
||||
for (arc = parcs, i = narcs; --i >= 0; arc++) {
|
||||
if (!miCanZeroArc(arc))
|
||||
miWideArc(pDraw, pGC, 1, arc);
|
||||
else {
|
||||
if (arc->width > arc->height)
|
||||
n = arc->width + (arc->height >> 1);
|
||||
else
|
||||
n = arc->height + (arc->width >> 1);
|
||||
if (n > maxPts)
|
||||
maxPts = n;
|
||||
}
|
||||
}
|
||||
if (!maxPts)
|
||||
return;
|
||||
numPts = maxPts << 2;
|
||||
dospans = (pGC->fillStyle != FillSolid);
|
||||
if (dospans) {
|
||||
widths = xallocarray(numPts, sizeof(int));
|
||||
if (!widths)
|
||||
return;
|
||||
maxw = 0;
|
||||
}
|
||||
if (pGC->lineStyle != LineSolid) {
|
||||
numPts <<= 1;
|
||||
dinfo.haveStart = FALSE;
|
||||
dinfo.skipStart = FALSE;
|
||||
dinfo.haveLast = FALSE;
|
||||
dinfo.dashIndexInit = 0;
|
||||
dinfo.dashOffsetInit = 0;
|
||||
miStepDash((int) pGC->dashOffset, &dinfo.dashIndexInit,
|
||||
(unsigned char *) pGC->dash, (int) pGC->numInDashList,
|
||||
&dinfo.dashOffsetInit);
|
||||
}
|
||||
points = xallocarray(numPts, sizeof(DDXPointRec));
|
||||
if (!points) {
|
||||
if (dospans) {
|
||||
free(widths);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (arc = parcs, i = narcs; --i >= 0; arc++) {
|
||||
if (miCanZeroArc(arc)) {
|
||||
if (pGC->lineStyle == LineSolid)
|
||||
pts = miZeroArcPts(arc, points);
|
||||
else {
|
||||
pts = points;
|
||||
oddPts = &points[(numPts >> 1) - 1];
|
||||
dinfo.skipLast = i;
|
||||
miZeroArcDashPts(pGC, arc, &dinfo,
|
||||
oddPts + 1, maxPts, &pts, &oddPts);
|
||||
dinfo.skipStart = TRUE;
|
||||
}
|
||||
n = pts - points;
|
||||
if (!dospans)
|
||||
(*pGC->ops->PolyPoint) (pDraw, pGC, CoordModeOrigin, n, points);
|
||||
else {
|
||||
if (n > maxw) {
|
||||
while (maxw < n)
|
||||
widths[maxw++] = 1;
|
||||
}
|
||||
if (pGC->miTranslate) {
|
||||
for (pt = points; pt != pts; pt++) {
|
||||
pt->x += pDraw->x;
|
||||
pt->y += pDraw->y;
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, n, points, widths, FALSE);
|
||||
}
|
||||
if (pGC->lineStyle != LineDoubleDash)
|
||||
continue;
|
||||
if ((pGC->fillStyle == FillSolid) ||
|
||||
(pGC->fillStyle == FillStippled)) {
|
||||
ChangeGCVal gcval;
|
||||
|
||||
gcval.val = pGC->bgPixel;
|
||||
ChangeGC(NullClient, pGC, GCForeground, &gcval);
|
||||
ValidateGC(pDraw, pGC);
|
||||
}
|
||||
pts = &points[numPts >> 1];
|
||||
oddPts++;
|
||||
n = pts - oddPts;
|
||||
if (!dospans)
|
||||
(*pGC->ops->PolyPoint) (pDraw, pGC, CoordModeOrigin, n, oddPts);
|
||||
else {
|
||||
if (n > maxw) {
|
||||
while (maxw < n)
|
||||
widths[maxw++] = 1;
|
||||
}
|
||||
if (pGC->miTranslate) {
|
||||
for (pt = oddPts; pt != pts; pt++) {
|
||||
pt->x += pDraw->x;
|
||||
pt->y += pDraw->y;
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, n, oddPts, widths, FALSE);
|
||||
}
|
||||
if ((pGC->fillStyle == FillSolid) ||
|
||||
(pGC->fillStyle == FillStippled)) {
|
||||
ChangeGCVal gcval;
|
||||
|
||||
gcval.val = fgPixel;
|
||||
ChangeGC(NullClient, pGC, GCForeground, &gcval);
|
||||
ValidateGC(pDraw, pGC);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(points);
|
||||
if (dospans) {
|
||||
free(widths);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue