X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fmi%2Fmiwideline.c;fp=Xserver%2Fprograms%2FXserver%2Fmi%2Fmiwideline.c;h=0000000000000000000000000000000000000000;hp=60049135eebbe335079ab4209fbcb283ce702c26;hb=ce66b81460e5353db09d45c02339d4583fbda255;hpb=7772d71ffd742cfc9b7ff214659d16c5bb56a391 diff --git a/Xserver/programs/Xserver/mi/miwideline.c b/Xserver/programs/Xserver/mi/miwideline.c deleted file mode 100644 index 6004913..0000000 --- a/Xserver/programs/Xserver/mi/miwideline.c +++ /dev/null @@ -1,2206 +0,0 @@ -/* $XConsortium: miwideline.c /main/58 1996/08/12 21:51:21 dpw $ */ -/* - -Copyright (c) 1988 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -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 X CONSORTIUM 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 X Consortium 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 X Consortium. - -*/ -/* $XFree86: xc/programs/Xserver/mi/miwideline.c,v 1.1.1.3.2.2 1998/02/01 22:08:22 robin Exp $ */ - -/* Author: Keith Packard, MIT X Consortium */ - -/* - * Mostly integer wideline code. Uses a technique similar to - * bresenham zero-width lines, except walks an X edge - */ - -#include -#ifdef _XOPEN_SOURCE -#include -#else -#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ -#include -#undef _XOPEN_SOURCE -#endif -#include "X.h" -#include "windowstr.h" -#include "gcstruct.h" -#include "miscstruct.h" -#include "miwideline.h" -#include "mi.h" - -#ifdef ICEILTEMPDECL -ICEILTEMPDECL -#endif - -static void miLineArc(); - -/* - * spans-based polygon filler - */ - -void -miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height, - left, right, left_count, right_count) - DrawablePtr pDrawable; - GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - int y; /* start y coordinate */ - int overall_height; /* height of entire segment */ - PolyEdgePtr left, right; - int left_count, right_count; -{ - register int left_x, left_e; - int left_stepx; - int left_signdx; - int left_dy, left_dx; - - register int right_x, right_e; - int right_stepx; - int right_signdx; - int right_dy, right_dx; - - int height; - int left_height, right_height; - - register DDXPointPtr ppt; - DDXPointPtr pptInit; - register int *pwidth; - int *pwidthInit; - XID oldPixel; - int xorg; - Spans spanRec; - - left_height = 0; - right_height = 0; - - if (!spanData) - { - pptInit = (DDXPointPtr) ALLOCATE_LOCAL (overall_height * sizeof(*ppt)); - if (!pptInit) - return; - pwidthInit = (int *) ALLOCATE_LOCAL (overall_height * sizeof(*pwidth)); - if (!pwidthInit) - { - DEALLOCATE_LOCAL (pptInit); - return; - } - ppt = pptInit; - pwidth = pwidthInit; - oldPixel = pGC->fgPixel; - if (pixel != oldPixel) - { - DoChangeGC (pGC, GCForeground, (XID *)&pixel, FALSE); - ValidateGC (pDrawable, pGC); - } - } - else - { - spanRec.points = (DDXPointPtr) xalloc (overall_height * sizeof (*ppt)); - if (!spanRec.points) - return; - spanRec.widths = (int *) xalloc (overall_height * sizeof (int)); - if (!spanRec.widths) - { - xfree (spanRec.points); - return; - } - ppt = spanRec.points; - pwidth = spanRec.widths; - } - - xorg = 0; - if (pGC->miTranslate) - { - y += pDrawable->y; - xorg = pDrawable->x; - } - while ((left_count || left_height) && - (right_count || right_height)) - { - MIPOLYRELOADLEFT - MIPOLYRELOADRIGHT - - height = left_height; - if (height > right_height) - height = right_height; - - left_height -= height; - right_height -= height; - - while (--height >= 0) - { - if (right_x >= left_x) - { - ppt->y = y; - ppt->x = left_x + xorg; - ppt++; - *pwidth++ = right_x - left_x + 1; - } - y++; - - MIPOLYSTEPLEFT - - MIPOLYSTEPRIGHT - } - } - if (!spanData) - { - (*pGC->ops->FillSpans) (pDrawable, pGC, ppt - pptInit, pptInit, pwidthInit, TRUE); - DEALLOCATE_LOCAL (pwidthInit); - DEALLOCATE_LOCAL (pptInit); - if (pixel != oldPixel) - { - DoChangeGC (pGC, GCForeground, &oldPixel, FALSE); - ValidateGC (pDrawable, pGC); - } - } - else - { - spanRec.count = ppt - spanRec.points; - AppendSpanGroup (pGC, pixel, &spanRec, spanData) - } -} - -static void -miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, x, y, w, h) - DrawablePtr pDrawable; - GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - int x, y, w, h; -{ - register DDXPointPtr ppt; - register int *pwidth; - XID oldPixel; - Spans spanRec; - xRectangle rect; - - if (!spanData) - { - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - oldPixel = pGC->fgPixel; - if (pixel != oldPixel) - { - DoChangeGC (pGC, GCForeground, (XID *)&pixel, FALSE); - ValidateGC (pDrawable, pGC); - } - (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &rect); - if (pixel != oldPixel) - { - DoChangeGC (pGC, GCForeground, &oldPixel, FALSE); - ValidateGC (pDrawable, pGC); - } - } - else - { - spanRec.points = (DDXPointPtr) xalloc (h * sizeof (*ppt)); - if (!spanRec.points) - return; - spanRec.widths = (int *) xalloc (h * sizeof (int)); - if (!spanRec.widths) - { - xfree (spanRec.points); - return; - } - ppt = spanRec.points; - pwidth = spanRec.widths; - - if (pGC->miTranslate) - { - y += pDrawable->y; - x += pDrawable->x; - } - while (h--) - { - ppt->x = x; - ppt->y = y; - ppt++; - *pwidth++ = w; - y++; - } - spanRec.count = ppt - spanRec.points; - AppendSpanGroup (pGC, pixel, &spanRec, spanData) - } -} - -int -miPolyBuildEdge (x0, y0, k, dx, dy, xi, yi, left, edge) - double x0, y0; - double k; /* x0 * dy - y0 * dx */ - register int dx, dy; - int xi, yi; - int left; - register PolyEdgePtr edge; -{ - int x, y, e; - int xady; - - if (dy < 0) - { - dy = -dy; - dx = -dx; - k = -k; - } - -#ifdef NOTDEF - { - double realk, kerror; - realk = x0 * dy - y0 * dx; - kerror = Fabs (realk - k); - if (kerror > .1) - printf ("realk: %g k: %g\n", realk, k); - } -#endif - y = ICEIL (y0); - xady = ICEIL (k) + y * dx; - - if (xady <= 0) - x = - (-xady / dy) - 1; - else - x = (xady - 1) / dy; - - e = xady - x * dy; - - if (dx >= 0) - { - edge->signdx = 1; - edge->stepx = dx / dy; - edge->dx = dx % dy; - } - else - { - edge->signdx = -1; - edge->stepx = - (-dx / dy); - edge->dx = -dx % dy; - e = dy - e + 1; - } - edge->dy = dy; - edge->x = x + left + xi; - edge->e = e - dy; /* bias to compare against 0 instead of dy */ - return y + yi; -} - -#define StepAround(v, incr, max) (((v) + (incr) < 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr))) - -int -miPolyBuildPoly (vertices, slopes, count, xi, yi, left, right, pnleft, pnright, h) - register PolyVertexPtr vertices; - register PolySlopePtr slopes; - int count; - int xi, yi; - PolyEdgePtr left, right; - int *pnleft, *pnright; - int *h; -{ - int top, bottom; - double miny, maxy; - register int i; - int j; - int clockwise; - int slopeoff; - register int s; - register int nright, nleft; - int y, lasty, bottomy, topy; - - /* find the top of the polygon */ - maxy = miny = vertices[0].y; - bottom = top = 0; - for (i = 1; i < count; i++) - { - if (vertices[i].y < miny) - { - top = i; - miny = vertices[i].y; - } - if (vertices[i].y >= maxy) - { - bottom = i; - maxy = vertices[i].y; - } - } - clockwise = 1; - slopeoff = 0; - - i = top; - j = StepAround (top, -1, count); - - if (slopes[j].dy * slopes[i].dx > slopes[i].dy * slopes[j].dx) - { - clockwise = -1; - slopeoff = -1; - } - - bottomy = ICEIL (maxy) + yi; - - nright = 0; - - s = StepAround (top, slopeoff, count); - i = top; - while (i != bottom) - { - if (slopes[s].dy != 0) - { - y = miPolyBuildEdge (vertices[i].x, vertices[i].y, - slopes[s].k, - slopes[s].dx, slopes[s].dy, - xi, yi, 0, - &right[nright]); - if (nright != 0) - right[nright-1].height = y - lasty; - else - topy = y; - nright++; - lasty = y; - } - - i = StepAround (i, clockwise, count); - s = StepAround (s, clockwise, count); - } - if (nright != 0) - right[nright-1].height = bottomy - lasty; - - if (slopeoff == 0) - slopeoff = -1; - else - slopeoff = 0; - - nleft = 0; - s = StepAround (top, slopeoff, count); - i = top; - while (i != bottom) - { - if (slopes[s].dy != 0) - { - y = miPolyBuildEdge (vertices[i].x, vertices[i].y, - slopes[s].k, - slopes[s].dx, slopes[s].dy, xi, yi, 1, - &left[nleft]); - - if (nleft != 0) - left[nleft-1].height = y - lasty; - nleft++; - lasty = y; - } - i = StepAround (i, -clockwise, count); - s = StepAround (s, -clockwise, count); - } - if (nleft != 0) - left[nleft-1].height = bottomy - lasty; - *pnleft = nleft; - *pnright = nright; - *h = bottomy - topy; - return topy; -} - -static void -miLineOnePoint (pDrawable, pGC, pixel, spanData, x, y) - DrawablePtr pDrawable; - GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - int x, y; -{ - DDXPointRec pt; - int wid; - unsigned long oldPixel; - - MILINESETPIXEL (pDrawable, pGC, pixel, oldPixel); - if (pGC->fillStyle == FillSolid) - { - pt.x = x; - pt.y = y; - (*pGC->ops->PolyPoint) (pDrawable, pGC, CoordModeOrigin, 1, &pt); - } - else - { - wid = 1; - if (pGC->miTranslate) - { - x += pDrawable->x; - y += pDrawable->y; - } - pt.x = x; - pt.y = y; - (*pGC->ops->FillSpans) (pDrawable, pGC, 1, &pt, &wid, TRUE); - } - MILINERESETPIXEL (pDrawable, pGC, pixel, oldPixel); -} - -static void -miLineJoin (pDrawable, pGC, pixel, spanData, pLeft, pRight) - DrawablePtr pDrawable; - GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - register LineFacePtr pLeft, pRight; -{ - double mx, my; - double denom; - PolyVertexRec vertices[4]; - PolySlopeRec slopes[4]; - int edgecount; - PolyEdgeRec left[4], right[4]; - int nleft, nright; - int y, height; - int swapslopes; - int joinStyle = pGC->joinStyle; - int lw = pGC->lineWidth; - - if (lw == 1 && !spanData) { - /* Lines going in the same direction have no join */ - if (pLeft->dx >= 0 == pRight->dx <= 0) - return; - if (joinStyle != JoinRound) { - denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy; - if (denom == 0) - return; /* no join to draw */ - } - if (joinStyle != JoinMiter) { - miLineOnePoint (pDrawable, pGC, pixel, spanData, pLeft->x, pLeft->y); - return; - } - } else { - if (joinStyle == JoinRound) - { - miLineArc(pDrawable, pGC, pixel, spanData, - pLeft, pRight, - (double)0.0, (double)0.0, TRUE); - return; - } - denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy; - if (denom == 0.0) - return; /* no join to draw */ - } - - swapslopes = 0; - if (denom > 0) - { - pLeft->xa = -pLeft->xa; - pLeft->ya = -pLeft->ya; - pLeft->dx = -pLeft->dx; - pLeft->dy = -pLeft->dy; - } - else - { - swapslopes = 1; - pRight->xa = -pRight->xa; - pRight->ya = -pRight->ya; - pRight->dx = -pRight->dx; - pRight->dy = -pRight->dy; - } - - vertices[0].x = pRight->xa; - vertices[0].y = pRight->ya; - slopes[0].dx = -pRight->dy; - slopes[0].dy = pRight->dx; - slopes[0].k = 0; - - vertices[1].x = 0; - vertices[1].y = 0; - slopes[1].dx = pLeft->dy; - slopes[1].dy = -pLeft->dx; - slopes[1].k = 0; - - vertices[2].x = pLeft->xa; - vertices[2].y = pLeft->ya; - - if (joinStyle == JoinMiter) - { - my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) - - pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx )) / - denom; - if (pLeft->dy != 0) - { - mx = pLeft->xa + (my - pLeft->ya) * - (double) pLeft->dx / (double) pLeft->dy; - } - else - { - mx = pRight->xa + (my - pRight->ya) * - (double) pRight->dx / (double) pRight->dy; - } - /* check miter limit */ - if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw) - joinStyle = JoinBevel; - } - - if (joinStyle == JoinMiter) - { - slopes[2].dx = pLeft->dx; - slopes[2].dy = pLeft->dy; - slopes[2].k = pLeft->k; - if (swapslopes) - { - slopes[2].dx = -slopes[2].dx; - slopes[2].dy = -slopes[2].dy; - slopes[2].k = -slopes[2].k; - } - vertices[3].x = mx; - vertices[3].y = my; - slopes[3].dx = pRight->dx; - slopes[3].dy = pRight->dy; - slopes[3].k = pRight->k; - if (swapslopes) - { - slopes[3].dx = -slopes[3].dx; - slopes[3].dy = -slopes[3].dy; - slopes[3].k = -slopes[3].k; - } - edgecount = 4; - } - else - { - double scale, dx, dy, adx, ady; - - adx = dx = pRight->xa - pLeft->xa; - ady = dy = pRight->ya - pLeft->ya; - if (adx < 0) - adx = -adx; - if (ady < 0) - ady = -ady; - scale = ady; - if (adx > ady) - scale = adx; - slopes[2].dx = (dx * 65536) / scale; - slopes[2].dy = (dy * 65536) / scale; - slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy - - (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0; - edgecount = 3; - } - - y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y, - left, right, &nleft, &nright, &height); - miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, height, left, right, nleft, nright); -} - -static int -miLineArcI (pDraw, pGC, xorg, yorg, points, widths) - DrawablePtr pDraw; - GCPtr pGC; - int xorg, yorg; - DDXPointPtr points; - int *widths; -{ - register DDXPointPtr tpts, bpts; - register int *twids, *bwids; - register int x, y, e, ex, slw; - - tpts = points; - twids = widths; - if (pGC->miTranslate) - { - xorg += pDraw->x; - yorg += pDraw->y; - } - slw = pGC->lineWidth; - if (slw == 1) - { - tpts->x = xorg; - tpts->y = yorg; - *twids = 1; - return 1; - } - bpts = tpts + slw; - bwids = twids + slw; - y = (slw >> 1) + 1; - if (slw & 1) - e = - ((y << 2) + 3); - else - e = - (y << 3); - ex = -4; - x = 0; - while (y) - { - e += (y << 3) - 4; - while (e >= 0) - { - x++; - e += (ex = -((x << 3) + 4)); - } - y--; - slw = (x << 1) + 1; - if ((e == ex) && (slw > 1)) - slw--; - tpts->x = xorg - x; - tpts->y = yorg - y; - tpts++; - *twids++ = slw; - if ((y != 0) && ((slw > 1) || (e != ex))) - { - bpts--; - bpts->x = xorg - x; - bpts->y = yorg + y; - *--bwids = slw; - } - } - return (pGC->lineWidth); -} - -#define CLIPSTEPEDGE(edgey,edge,edgeleft) \ - if (ybase == edgey) \ - { \ - if (edgeleft) \ - { \ - if (edge->x > xcl) \ - xcl = edge->x; \ - } \ - else \ - { \ - if (edge->x < xcr) \ - xcr = edge->x; \ - } \ - edgey++; \ - edge->x += edge->stepx; \ - edge->e += edge->dx; \ - if (edge->e > 0) \ - { \ - edge->x += edge->signdx; \ - edge->e -= edge->dy; \ - } \ - } - -static int -miLineArcD (pDraw, pGC, xorg, yorg, points, widths, - edge1, edgey1, edgeleft1, edge2, edgey2, edgeleft2) - DrawablePtr pDraw; - GCPtr pGC; - double xorg, yorg; - DDXPointPtr points; - int *widths; - PolyEdgePtr edge1, edge2; - int edgey1, edgey2; - Bool edgeleft1, edgeleft2; -{ - register DDXPointPtr pts; - register int *wids; - double radius, x0, y0, el, er, yk, xlk, xrk, k; - int xbase, ybase, y, boty, xl, xr, xcl, xcr; - int ymin, ymax; - Bool edge1IsMin, edge2IsMin; - int ymin1, ymin2; - - pts = points; - wids = widths; - xbase = floor(xorg); - x0 = xorg - xbase; - ybase = ICEIL (yorg); - y0 = yorg - ybase; - if (pGC->miTranslate) - { - xbase += pDraw->x; - ybase += pDraw->y; - edge1->x += pDraw->x; - edge2->x += pDraw->x; - edgey1 += pDraw->y; - edgey2 += pDraw->y; - } - xlk = x0 + x0 + 1.0; - xrk = x0 + x0 - 1.0; - yk = y0 + y0 - 1.0; - radius = ((double)pGC->lineWidth) / 2.0; - y = floor(radius - y0 + 1.0); - ybase -= y; - ymin = ybase; - ymax = 65536; - edge1IsMin = FALSE; - ymin1 = edgey1; - if (edge1->dy >= 0) - { - if (!edge1->dy) - { - if (edgeleft1) - edge1IsMin = TRUE; - else - ymax = edgey1; - edgey1 = 65536; - } - else - { - if ((edge1->signdx < 0) == edgeleft1) - edge1IsMin = TRUE; - } - } - edge2IsMin = FALSE; - ymin2 = edgey2; - if (edge2->dy >= 0) - { - if (!edge2->dy) - { - if (edgeleft2) - edge2IsMin = TRUE; - else - ymax = edgey2; - edgey2 = 65536; - } - else - { - if ((edge2->signdx < 0) == edgeleft2) - edge2IsMin = TRUE; - } - } - if (edge1IsMin) - { - ymin = ymin1; - if (edge2IsMin && ymin1 > ymin2) - ymin = ymin2; - } else if (edge2IsMin) - ymin = ymin2; - el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0); - er = el + xrk; - xl = 1; - xr = 0; - if (x0 < 0.5) - { - xl = 0; - el -= xlk; - } - boty = (y0 < -0.5) ? 1 : 0; - if (ybase + y - boty > ymax) - boty = ymax - ybase - y; - while (y > boty) - { - k = (y << 1) + yk; - er += k; - while (er > 0.0) - { - xr++; - er += xrk - (xr << 1); - } - el += k; - while (el >= 0.0) - { - xl--; - el += (xl << 1) - xlk; - } - y--; - ybase++; - if (ybase < ymin) - continue; - xcl = xl + xbase; - xcr = xr + xbase; - CLIPSTEPEDGE(edgey1, edge1, edgeleft1); - CLIPSTEPEDGE(edgey2, edge2, edgeleft2); - if (xcr >= xcl) - { - pts->x = xcl; - pts->y = ybase; - pts++; - *wids++ = xcr - xcl + 1; - } - } - er = xrk - (xr << 1) - er; - el = (xl << 1) - xlk - el; - boty = floor(-y0 - radius + 1.0); - if (ybase + y - boty > ymax) - boty = ymax - ybase - y; - while (y > boty) - { - k = (y << 1) + yk; - er -= k; - while ((er >= 0.0) && (xr >= 0)) - { - xr--; - er += xrk - (xr << 1); - } - el -= k; - while ((el > 0.0) && (xl <= 0)) - { - xl++; - el += (xl << 1) - xlk; - } - y--; - ybase++; - if (ybase < ymin) - continue; - xcl = xl + xbase; - xcr = xr + xbase; - CLIPSTEPEDGE(edgey1, edge1, edgeleft1); - CLIPSTEPEDGE(edgey2, edge2, edgeleft2); - if (xcr >= xcl) - { - pts->x = xcl; - pts->y = ybase; - pts++; - *wids++ = xcr - xcl + 1; - } - } - return (pts - points); -} - -int -miRoundJoinFace (face, edge, leftEdge) - register LineFacePtr face; - register PolyEdgePtr edge; - Bool *leftEdge; -{ - int y; - int dx, dy; - double xa, ya; - Bool left; - - dx = -face->dy; - dy = face->dx; - xa = face->xa; - ya = face->ya; - left = 1; - if (ya > 0) - { - ya = 0.0; - xa = 0.0; - } - if (dy < 0 || dy == 0 && dx > 0) - { - dx = -dx; - dy = -dy; - left = !left; - } - if (dx == 0 && dy == 0) - dy = 1; - if (dy == 0) - { - y = ICEIL (face->ya) + face->y; - edge->x = -32767; - edge->stepx = 0; - edge->signdx = 0; - edge->e = -1; - edge->dy = 0; - edge->dx = 0; - edge->height = 0; - } - else - { - y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge); - edge->height = 32767; - } - *leftEdge = !left; - return y; -} - -void -miRoundJoinClip (pLeft, pRight, edge1, edge2, y1, y2, left1, left2) - register LineFacePtr pLeft, pRight; - PolyEdgePtr edge1, edge2; - int *y1, *y2; - Bool *left1, *left2; -{ - double denom; - - denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy; - - if (denom >= 0) - { - pLeft->xa = -pLeft->xa; - pLeft->ya = -pLeft->ya; - } - else - { - pRight->xa = -pRight->xa; - pRight->ya = -pRight->ya; - } - *y1 = miRoundJoinFace (pLeft, edge1, left1); - *y2 = miRoundJoinFace (pRight, edge2, left2); -} - -int -miRoundCapClip (face, isInt, edge, leftEdge) - register LineFacePtr face; - Bool isInt; - register PolyEdgePtr edge; - Bool *leftEdge; -{ - int y; - register int dx, dy; - double xa, ya, k; - Bool left; - - dx = -face->dy; - dy = face->dx; - xa = face->xa; - ya = face->ya; - k = 0.0; - if (!isInt) - k = face->k; - left = 1; - if (dy < 0 || dy == 0 && dx > 0) - { - dx = -dx; - dy = -dy; - xa = -xa; - ya = -ya; - left = !left; - } - if (dx == 0 && dy == 0) - dy = 1; - if (dy == 0) - { - y = ICEIL (face->ya) + face->y; - edge->x = -32767; - edge->stepx = 0; - edge->signdx = 0; - edge->e = -1; - edge->dy = 0; - edge->dx = 0; - edge->height = 0; - } - else - { - y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge); - edge->height = 32767; - } - *leftEdge = !left; - return y; -} - -static void -miLineArc (pDraw, pGC, pixel, spanData, leftFace, rightFace, xorg, yorg, isInt) - DrawablePtr pDraw; - register GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - register LineFacePtr leftFace, rightFace; - double xorg, yorg; - Bool isInt; -{ - DDXPointPtr points; - int *widths; - int xorgi, yorgi; - XID oldPixel; - Spans spanRec; - int n; - PolyEdgeRec edge1, edge2; - int edgey1, edgey2; - Bool edgeleft1, edgeleft2; - - if (isInt) - { - xorgi = leftFace ? leftFace->x : rightFace->x; - yorgi = leftFace ? leftFace->y : rightFace->y; - } - edgey1 = 65536; - edgey2 = 65536; - edge1.x = 0; /* not used, keep memory checkers happy */ - edge1.dy = -1; - edge2.x = 0; /* not used, keep memory checkers happy */ - edge2.dy = -1; - edgeleft1 = FALSE; - edgeleft2 = FALSE; - if ((pGC->lineStyle != LineSolid || pGC->lineWidth > 2) && - (pGC->capStyle == CapRound && pGC->joinStyle != JoinRound || - pGC->joinStyle == JoinRound && pGC->capStyle == CapButt)) - { - if (isInt) - { - xorg = (double) xorgi; - yorg = (double) yorgi; - } - if (leftFace && rightFace) - { - miRoundJoinClip (leftFace, rightFace, &edge1, &edge2, - &edgey1, &edgey2, &edgeleft1, &edgeleft2); - } - else if (leftFace) - { - edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1); - } - else if (rightFace) - { - edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2); - } - isInt = FALSE; - } - if (!spanData) - { - points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * pGC->lineWidth); - if (!points) - return; - widths = (int *)ALLOCATE_LOCAL(sizeof(int) * pGC->lineWidth); - if (!widths) - { - DEALLOCATE_LOCAL(points); - return; - } - oldPixel = pGC->fgPixel; - if (pixel != oldPixel) - { - DoChangeGC(pGC, GCForeground, (XID *)&pixel, FALSE); - ValidateGC (pDraw, pGC); - } - } - else - { - points = (DDXPointPtr) xalloc (pGC->lineWidth * sizeof (DDXPointRec)); - if (!points) - return; - widths = (int *) xalloc (pGC->lineWidth * sizeof (int)); - if (!widths) - { - xfree (points); - return; - } - spanRec.points = points; - spanRec.widths = widths; - } - if (isInt) - n = miLineArcI(pDraw, pGC, xorgi, yorgi, points, widths); - else - n = miLineArcD(pDraw, pGC, xorg, yorg, points, widths, - &edge1, edgey1, edgeleft1, - &edge2, edgey2, edgeleft2); - - if (!spanData) - { - (*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, TRUE); - DEALLOCATE_LOCAL(widths); - DEALLOCATE_LOCAL(points); - if (pixel != oldPixel) - { - DoChangeGC(pGC, GCForeground, &oldPixel, FALSE); - ValidateGC (pDraw, pGC); - } - } - else - { - spanRec.count = n; - AppendSpanGroup (pGC, pixel, &spanRec, spanData) - } -} - -void -miLineProjectingCap (pDrawable, pGC, pixel, spanData, face, isLeft, xorg, yorg, isInt) - DrawablePtr pDrawable; - register GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - register LineFacePtr face; - Bool isLeft; - double xorg, yorg; - Bool isInt; -{ - int xorgi, yorgi; - int lw; - PolyEdgeRec lefts[2], rights[2]; - int lefty, righty, topy, bottomy; - PolyEdgePtr left, right; - PolyEdgePtr top, bottom; - double xa,ya; - double k; - double xap, yap; - int dx, dy; - double projectXoff, projectYoff; - double maxy; - int finaly; - - if (isInt) - { - xorgi = face->x; - yorgi = face->y; - } - lw = pGC->lineWidth; - dx = face->dx; - dy = face->dy; - k = face->k; - if (dy == 0) - { - lefts[0].height = lw; - lefts[0].x = xorgi; - if (isLeft) - lefts[0].x -= (lw >> 1); - lefts[0].stepx = 0; - lefts[0].signdx = 1; - lefts[0].e = -lw; - lefts[0].dx = 0; - lefts[0].dy = lw; - rights[0].height = lw; - rights[0].x = xorgi; - if (!isLeft) - rights[0].x += (lw + 1 >> 1); - rights[0].stepx = 0; - rights[0].signdx = 1; - rights[0].e = -lw; - rights[0].dx = 0; - rights[0].dy = lw; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, yorgi - (lw >> 1), lw, - lefts, rights, 1, 1); - } - else if (dx == 0) - { - topy = yorgi; - bottomy = yorgi + dy; - if (isLeft) - topy -= (lw >> 1); - else - bottomy += (lw >> 1); - lefts[0].height = bottomy - topy; - lefts[0].x = xorgi - (lw >> 1); - lefts[0].stepx = 0; - lefts[0].signdx = 1; - lefts[0].e = -dy; - lefts[0].dx = dx; - lefts[0].dy = dy; - - rights[0].height = bottomy - topy; - rights[0].x = lefts[0].x + (lw-1); - rights[0].stepx = 0; - rights[0].signdx = 1; - rights[0].e = -dy; - rights[0].dx = dx; - rights[0].dy = dy; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, bottomy - topy, lefts, rights, 1, 1); - } - else - { - xa = face->xa; - ya = face->ya; - projectXoff = -ya; - projectYoff = xa; - if (dx < 0) - { - right = &rights[1]; - left = &lefts[0]; - top = &rights[0]; - bottom = &lefts[1]; - } - else - { - right = &rights[0]; - left = &lefts[1]; - top = &lefts[0]; - bottom = &rights[1]; - } - if (isLeft) - { - righty = miPolyBuildEdge (xa, ya, - k, dx, dy, xorgi, yorgi, 0, right); - - xa = -xa; - ya = -ya; - k = -k; - lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, xorgi, yorgi, 1, left); - if (dx > 0) - { - ya = -ya; - xa = -xa; - } - xap = xa - projectXoff; - yap = ya - projectYoff; - topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, xorgi, yorgi, dx > 0, top); - bottomy = miPolyBuildEdge (xa, ya, - 0.0, -dy, dx, xorgi, yorgi, dx < 0, bottom); - maxy = -ya; - } - else - { - righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, xorgi, yorgi, 0, right); - - xa = -xa; - ya = -ya; - k = -k; - lefty = miPolyBuildEdge (xa, ya, - k, dx, dy, xorgi, yorgi, 1, left); - if (dx > 0) - { - ya = -ya; - xa = -xa; - } - xap = xa - projectXoff; - yap = ya - projectYoff; - topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, top); - bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, xorgi, xorgi, dx < 0, bottom); - maxy = -ya + projectYoff; - } - finaly = ICEIL(maxy) + yorgi; - if (dx < 0) - { - left->height = bottomy - lefty; - right->height = finaly - righty; - top->height = righty - topy; - } - else - { - right->height = bottomy - righty; - left->height = finaly - lefty; - top->height = lefty - topy; - } - bottom->height = finaly - bottomy; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, - bottom->height + bottomy - topy, lefts, rights, 2, 2); - } -} - -static void -miWideSegment (pDrawable, pGC, pixel, spanData, - x1, y1, x2, y2, projectLeft, projectRight, leftFace, rightFace) - DrawablePtr pDrawable; - GCPtr pGC; - unsigned long pixel; - SpanDataPtr spanData; - register int x1, y1, x2, y2; - Bool projectLeft, projectRight; - register LineFacePtr leftFace, rightFace; -{ - double l, L, r; - double xa, ya; - double projectXoff, projectYoff; - double k; - double maxy; - int x, y; - int dx, dy; - int finaly; - PolyEdgePtr left, right; - PolyEdgePtr top, bottom; - int lefty, righty, topy, bottomy; - int signdx; - PolyEdgeRec lefts[2], rights[2]; - LineFacePtr tface; - int lw = pGC->lineWidth; - - /* draw top-to-bottom always */ - if (y2 < y1 || y2 == y1 && x2 < x1) - { - x = x1; - x1 = x2; - x2 = x; - - y = y1; - y1 = y2; - y2 = y; - - x = projectLeft; - projectLeft = projectRight; - projectRight = x; - - tface = leftFace; - leftFace = rightFace; - rightFace = tface; - } - - dy = y2 - y1; - signdx = 1; - dx = x2 - x1; - if (dx < 0) - signdx = -1; - - leftFace->x = x1; - leftFace->y = y1; - leftFace->dx = dx; - leftFace->dy = dy; - - rightFace->x = x2; - rightFace->y = y2; - rightFace->dx = -dx; - rightFace->dy = -dy; - - if (dy == 0) - { - rightFace->xa = 0; - rightFace->ya = (double) lw / 2.0; - rightFace->k = -(double) (lw * dx) / 2.0; - leftFace->xa = 0; - leftFace->ya = -rightFace->ya; - leftFace->k = rightFace->k; - x = x1; - if (projectLeft) - x -= (lw >> 1); - y = y1 - (lw >> 1); - dx = x2 - x; - if (projectRight) - dx += (lw + 1 >> 1); - dy = lw; - miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, - x, y, dx, dy); - } - else if (dx == 0) - { - leftFace->xa = (double) lw / 2.0; - leftFace->ya = 0; - leftFace->k = (double) (lw * dy) / 2.0; - rightFace->xa = -leftFace->xa; - rightFace->ya = 0; - rightFace->k = leftFace->k; - y = y1; - if (projectLeft) - y -= lw >> 1; - x = x1 - (lw >> 1); - dy = y2 - y; - if (projectRight) - dy += (lw + 1 >> 1); - dx = lw; - miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, - x, y, dx, dy); - } - else - { - l = ((double) lw) / 2.0; - L = hypot ((double) dx, (double) dy); - - if (dx < 0) - { - right = &rights[1]; - left = &lefts[0]; - top = &rights[0]; - bottom = &lefts[1]; - } - else - { - right = &rights[0]; - left = &lefts[1]; - top = &lefts[0]; - bottom = &rights[1]; - } - r = l / L; - - /* coord of upper bound at integral y */ - ya = -r * dx; - xa = r * dy; - - if (projectLeft | projectRight) - { - projectXoff = -ya; - projectYoff = xa; - } - - /* xa * dy - ya * dx */ - k = l * L; - - leftFace->xa = xa; - leftFace->ya = ya; - leftFace->k = k; - rightFace->xa = -xa; - rightFace->ya = -ya; - rightFace->k = k; - - if (projectLeft) - righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, x1, y1, 0, right); - else - righty = miPolyBuildEdge (xa, ya, - k, dx, dy, x1, y1, 0, right); - - /* coord of lower bound at integral y */ - ya = -ya; - xa = -xa; - - /* xa * dy - ya * dx */ - k = - k; - - if (projectLeft) - lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, x1, y1, 1, left); - else - lefty = miPolyBuildEdge (xa, ya, - k, dx, dy, x1, y1, 1, left); - - /* coord of top face at integral y */ - - if (signdx > 0) - { - ya = -ya; - xa = -xa; - } - - if (projectLeft) - { - double xap = xa - projectXoff; - double yap = ya - projectYoff; - topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, x1, y1, dx > 0, top); - } - else - topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top); - - /* coord of bottom face at integral y */ - - if (projectRight) - { - double xap = xa + projectXoff; - double yap = ya + projectYoff; - bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, x2, y2, dx < 0, bottom); - maxy = -ya + projectYoff; - } - else - { - bottomy = miPolyBuildEdge (xa, ya, - 0.0, -dy, dx, x2, y2, dx < 0, bottom); - maxy = -ya; - } - - finaly = ICEIL (maxy) + y2; - - if (dx < 0) - { - left->height = bottomy - lefty; - right->height = finaly - righty; - top->height = righty - topy; - } - else - { - right->height = bottomy - righty; - left->height = finaly - lefty; - top->height = lefty - topy; - } - bottom->height = finaly - bottomy; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, - bottom->height + bottomy - topy, lefts, rights, 2, 2); - } -} - -SpanDataPtr -miSetupSpanData (pGC, spanData, npt) - register GCPtr pGC; - SpanDataPtr spanData; - int npt; -{ - if (npt < 3 && pGC->capStyle != CapRound || miSpansEasyRop(pGC->alu)) - return (SpanDataPtr) NULL; - if (pGC->lineStyle == LineDoubleDash) - miInitSpanGroup (&spanData->bgGroup); - miInitSpanGroup (&spanData->fgGroup); - return spanData; -} - -void -miCleanupSpanData (pDrawable, pGC, spanData) - DrawablePtr pDrawable; - GCPtr pGC; - SpanDataPtr spanData; -{ - if (pGC->lineStyle == LineDoubleDash) - { - XID oldPixel, pixel; - - pixel = pGC->bgPixel; - oldPixel = pGC->fgPixel; - if (pixel != oldPixel) - { - DoChangeGC (pGC, GCForeground, &pixel, FALSE); - ValidateGC (pDrawable, pGC); - } - miFillUniqueSpanGroup (pDrawable, pGC, &spanData->bgGroup); - miFreeSpanGroup (&spanData->bgGroup); - if (pixel != oldPixel) - { - DoChangeGC (pGC, GCForeground, &oldPixel, FALSE); - ValidateGC (pDrawable, pGC); - } - } - miFillUniqueSpanGroup (pDrawable, pGC, &spanData->fgGroup); - miFreeSpanGroup (&spanData->fgGroup); -} - -void -miWideLine (pDrawable, pGC, mode, npt, pPts) - DrawablePtr pDrawable; - register GCPtr pGC; - int mode; - register int npt; - register DDXPointPtr pPts; -{ - int x1, y1, x2, y2; - SpanDataRec spanDataRec; - SpanDataPtr spanData; - unsigned long pixel; - Bool projectLeft, projectRight; - LineFaceRec leftFace, rightFace, prevRightFace; - LineFaceRec firstFace; - register int first; - Bool somethingDrawn = FALSE; - Bool selfJoin; - - spanData = miSetupSpanData (pGC, &spanDataRec, npt); - pixel = pGC->fgPixel; - x2 = pPts->x; - y2 = pPts->y; - first = TRUE; - selfJoin = FALSE; - if (npt > 1) - { - if (mode == CoordModePrevious) - { - int nptTmp; - DDXPointPtr pPtsTmp; - - x1 = x2; - y1 = y2; - nptTmp = npt; - pPtsTmp = pPts + 1; - while (--nptTmp) - { - x1 += pPtsTmp->x; - y1 += pPtsTmp->y; - ++pPtsTmp; - } - if (x2 == x1 && y2 == y1) - selfJoin = TRUE; - } - else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y) - { - selfJoin = TRUE; - } - } - projectLeft = pGC->capStyle == CapProjecting && !selfJoin; - projectRight = FALSE; - while (--npt) - { - x1 = x2; - y1 = y2; - ++pPts; - x2 = pPts->x; - y2 = pPts->y; - if (mode == CoordModePrevious) - { - x2 += x1; - y2 += y1; - } - if (x1 != x2 || y1 != y2) - { - somethingDrawn = TRUE; - if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin) - projectRight = TRUE; - miWideSegment (pDrawable, pGC, pixel, spanData, x1, y1, x2, y2, - projectLeft, projectRight, &leftFace, &rightFace); - if (first) - { - if (selfJoin) - firstFace = leftFace; - else if (pGC->capStyle == CapRound) - { - if (pGC->lineWidth == 1 && !spanData) - miLineOnePoint (pDrawable, pGC, pixel, spanData, x1, y1); - else - miLineArc (pDrawable, pGC, pixel, spanData, - &leftFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, - TRUE); - } - } - else - { - miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace, - &prevRightFace); - } - prevRightFace = rightFace; - first = FALSE; - projectLeft = FALSE; - } - if (npt == 1 && somethingDrawn) - { - if (selfJoin) - miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace, - &rightFace); - else if (pGC->capStyle == CapRound) - { - if (pGC->lineWidth == 1 && !spanData) - miLineOnePoint (pDrawable, pGC, pixel, spanData, x2, y2); - else - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rightFace, - (double)0.0, (double)0.0, - TRUE); - } - } - } - /* handle crock where all points are coincedent */ - if (!somethingDrawn) - { - projectLeft = pGC->capStyle == CapProjecting; - miWideSegment (pDrawable, pGC, pixel, spanData, - x2, y2, x2, y2, projectLeft, projectLeft, - &leftFace, &rightFace); - if (pGC->capStyle == CapRound) - { - miLineArc (pDrawable, pGC, pixel, spanData, - &leftFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, - TRUE); - rightFace.dx = -1; /* sleezy hack to make it work */ - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rightFace, - (double)0.0, (double)0.0, - TRUE); - } - } - if (spanData) - miCleanupSpanData (pDrawable, pGC, spanData); -} - -#define V_TOP 0 -#define V_RIGHT 1 -#define V_BOTTOM 2 -#define V_LEFT 3 - -static void -miWideDashSegment (pDrawable, pGC, spanData, pDashOffset, pDashIndex, - x1, y1, x2, y2, projectLeft, projectRight, leftFace, rightFace) - DrawablePtr pDrawable; - register GCPtr pGC; - int *pDashOffset, *pDashIndex; - SpanDataPtr spanData; - int x1, y1, x2, y2; - Bool projectLeft, projectRight; - LineFacePtr leftFace, rightFace; -{ - int dashIndex, dashRemain; - unsigned char *pDash; - double L, l; - double k; - PolyVertexRec vertices[4]; - PolyVertexRec saveRight, saveBottom; - PolySlopeRec slopes[4]; - PolyEdgeRec left[2], right[2]; - LineFaceRec lcapFace, rcapFace; - int nleft, nright; - int h; - int y; - int dy, dx; - unsigned long pixel; - double LRemain; - double r; - double rdx, rdy; - double dashDx, dashDy; - double saveK; - Bool first = TRUE; - double lcenterx, lcentery, rcenterx, rcentery; - unsigned long fgPixel, bgPixel; - - dx = x2 - x1; - dy = y2 - y1; - dashIndex = *pDashIndex; - pDash = pGC->dash; - dashRemain = pDash[dashIndex] - *pDashOffset; - fgPixel = pGC->fgPixel; - bgPixel = pGC->bgPixel; - if (pGC->fillStyle == FillOpaqueStippled || - pGC->fillStyle == FillTiled) - { - bgPixel = fgPixel; - } - - l = ((double) pGC->lineWidth) / 2.0; - if (dx == 0) - { - L = dy; - rdx = 0; - rdy = l; - if (dy < 0) - { - L = -dy; - rdy = -l; - } - } - else if (dy == 0) - { - L = dx; - rdx = l; - rdy = 0; - if (dx < 0) - { - L = -dx; - rdx = -l; - } - } - else - { - L = hypot ((double) dx, (double) dy); - r = l / L; - - rdx = r * dx; - rdy = r * dy; - } - k = l * L; - LRemain = L; - /* All position comments are relative to a line with dx and dy > 0, - * but the code does not depend on this */ - /* top */ - slopes[V_TOP].dx = dx; - slopes[V_TOP].dy = dy; - slopes[V_TOP].k = k; - /* right */ - slopes[V_RIGHT].dx = -dy; - slopes[V_RIGHT].dy = dx; - slopes[V_RIGHT].k = 0; - /* bottom */ - slopes[V_BOTTOM].dx = -dx; - slopes[V_BOTTOM].dy = -dy; - slopes[V_BOTTOM].k = k; - /* left */ - slopes[V_LEFT].dx = dy; - slopes[V_LEFT].dy = -dx; - slopes[V_LEFT].k = 0; - - /* preload the start coordinates */ - vertices[V_RIGHT].x = vertices[V_TOP].x = rdy; - vertices[V_RIGHT].y = vertices[V_TOP].y = -rdx; - - vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy; - vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx; - - if (projectLeft) - { - vertices[V_TOP].x -= rdx; - vertices[V_TOP].y -= rdy; - - vertices[V_LEFT].x -= rdx; - vertices[V_LEFT].y -= rdy; - - slopes[V_LEFT].k = rdx * dx + rdy * dy; - } - - lcenterx = x1; - lcentery = y1; - - if (pGC->capStyle == CapRound) - { - lcapFace.dx = dx; - lcapFace.dy = dy; - lcapFace.x = x1; - lcapFace.y = y1; - - rcapFace.dx = -dx; - rcapFace.dy = -dy; - rcapFace.x = x1; - rcapFace.y = y1; - } - while (LRemain > dashRemain) - { - dashDx = (dashRemain * dx) / L; - dashDy = (dashRemain * dy) / L; - - rcenterx = lcenterx + dashDx; - rcentery = lcentery + dashDy; - - vertices[V_RIGHT].x += dashDx; - vertices[V_RIGHT].y += dashDy; - - vertices[V_BOTTOM].x += dashDx; - vertices[V_BOTTOM].y += dashDy; - - slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy; - - if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) - { - if (pGC->lineStyle == LineOnOffDash && - pGC->capStyle == CapProjecting) - { - saveRight = vertices[V_RIGHT]; - saveBottom = vertices[V_BOTTOM]; - saveK = slopes[V_RIGHT].k; - - if (!first) - { - vertices[V_TOP].x -= rdx; - vertices[V_TOP].y -= rdy; - - vertices[V_LEFT].x -= rdx; - vertices[V_LEFT].y -= rdy; - - slopes[V_LEFT].k = vertices[V_LEFT].x * - slopes[V_LEFT].dy - - vertices[V_LEFT].y * - slopes[V_LEFT].dx; - } - - vertices[V_RIGHT].x += rdx; - vertices[V_RIGHT].y += rdy; - - vertices[V_BOTTOM].x += rdx; - vertices[V_BOTTOM].y += rdy; - - slopes[V_RIGHT].k = vertices[V_RIGHT].x * - slopes[V_RIGHT].dy - - vertices[V_RIGHT].y * - slopes[V_RIGHT].dx; - } - y = miPolyBuildPoly (vertices, slopes, 4, x1, y1, - left, right, &nleft, &nright, &h); - pixel = (dashIndex & 1) ? bgPixel : fgPixel; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright); - - if (pGC->lineStyle == LineOnOffDash) - { - switch (pGC->capStyle) - { - case CapProjecting: - vertices[V_BOTTOM] = saveBottom; - vertices[V_RIGHT] = saveRight; - slopes[V_RIGHT].k = saveK; - break; - case CapRound: - if (!first) - { - if (dx < 0) - { - lcapFace.xa = -vertices[V_LEFT].x; - lcapFace.ya = -vertices[V_LEFT].y; - lcapFace.k = slopes[V_LEFT].k; - } - else - { - lcapFace.xa = vertices[V_TOP].x; - lcapFace.ya = vertices[V_TOP].y; - lcapFace.k = -slopes[V_LEFT].k; - } - miLineArc (pDrawable, pGC, pixel, spanData, - &lcapFace, (LineFacePtr) NULL, - lcenterx, lcentery, FALSE); - } - if (dx < 0) - { - rcapFace.xa = vertices[V_BOTTOM].x; - rcapFace.ya = vertices[V_BOTTOM].y; - rcapFace.k = slopes[V_RIGHT].k; - } - else - { - rcapFace.xa = -vertices[V_RIGHT].x; - rcapFace.ya = -vertices[V_RIGHT].y; - rcapFace.k = -slopes[V_RIGHT].k; - } - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rcapFace, - rcenterx, rcentery, FALSE); - break; - } - } - } - LRemain -= dashRemain; - ++dashIndex; - if (dashIndex == pGC->numInDashList) - dashIndex = 0; - dashRemain = pDash[dashIndex]; - - lcenterx = rcenterx; - lcentery = rcentery; - - vertices[V_TOP] = vertices[V_RIGHT]; - vertices[V_LEFT] = vertices[V_BOTTOM]; - slopes[V_LEFT].k = -slopes[V_RIGHT].k; - first = FALSE; - } - - if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) - { - vertices[V_TOP].x -= dx; - vertices[V_TOP].y -= dy; - - vertices[V_LEFT].x -= dx; - vertices[V_LEFT].y -= dy; - - vertices[V_RIGHT].x = rdy; - vertices[V_RIGHT].y = -rdx; - - vertices[V_BOTTOM].x = -rdy; - vertices[V_BOTTOM].y = rdx; - - - if (projectRight) - { - vertices[V_RIGHT].x += rdx; - vertices[V_RIGHT].y += rdy; - - vertices[V_BOTTOM].x += rdx; - vertices[V_BOTTOM].y += rdy; - slopes[V_RIGHT].k = vertices[V_RIGHT].x * - slopes[V_RIGHT].dy - - vertices[V_RIGHT].y * - slopes[V_RIGHT].dx; - } - else - slopes[V_RIGHT].k = 0; - - if (!first && pGC->lineStyle == LineOnOffDash && - pGC->capStyle == CapProjecting) - { - vertices[V_TOP].x -= rdx; - vertices[V_TOP].y -= rdy; - - vertices[V_LEFT].x -= rdx; - vertices[V_LEFT].y -= rdy; - slopes[V_LEFT].k = vertices[V_LEFT].x * - slopes[V_LEFT].dy - - vertices[V_LEFT].y * - slopes[V_LEFT].dx; - } - else - slopes[V_LEFT].k += dx * dx + dy * dy; - - - y = miPolyBuildPoly (vertices, slopes, 4, x2, y2, - left, right, &nleft, &nright, &h); - - pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright); - if (!first && pGC->lineStyle == LineOnOffDash && - pGC->capStyle == CapRound) - { - lcapFace.x = x2; - lcapFace.y = y2; - if (dx < 0) - { - lcapFace.xa = -vertices[V_LEFT].x; - lcapFace.ya = -vertices[V_LEFT].y; - lcapFace.k = slopes[V_LEFT].k; - } - else - { - lcapFace.xa = vertices[V_TOP].x; - lcapFace.ya = vertices[V_TOP].y; - lcapFace.k = -slopes[V_LEFT].k; - } - miLineArc (pDrawable, pGC, pixel, spanData, - &lcapFace, (LineFacePtr) NULL, - rcenterx, rcentery, FALSE); - } - } - dashRemain = ((double) dashRemain) - LRemain; - if (dashRemain == 0) - { - dashIndex++; - if (dashIndex == pGC->numInDashList) - dashIndex = 0; - dashRemain = pDash[dashIndex]; - } - - leftFace->x = x1; - leftFace->y = y1; - leftFace->dx = dx; - leftFace->dy = dy; - leftFace->xa = rdy; - leftFace->ya = -rdx; - leftFace->k = k; - - rightFace->x = x2; - rightFace->y = y2; - rightFace->dx = -dx; - rightFace->dy = -dy; - rightFace->xa = -rdy; - rightFace->ya = rdx; - rightFace->k = k; - - *pDashIndex = dashIndex; - *pDashOffset = pDash[dashIndex] - dashRemain; -} - -void -miWideDash (pDrawable, pGC, mode, npt, pPts) - DrawablePtr pDrawable; - register GCPtr pGC; - int mode; - register int npt; - register DDXPointPtr pPts; -{ - int x1, y1, x2, y2; - unsigned long pixel; - Bool projectLeft, projectRight; - LineFaceRec leftFace, rightFace, prevRightFace; - LineFaceRec firstFace; - int first; - int dashIndex, dashOffset; - register int prevDashIndex; - SpanDataRec spanDataRec; - SpanDataPtr spanData; - Bool somethingDrawn = FALSE; - Bool selfJoin; - Bool endIsFg, startIsFg, firstIsFg = FALSE, prevIsFg; - - /* XXX backward compatibility */ - if (pGC->lineWidth == 0) - { - miZeroDashLine (pDrawable, pGC, mode, npt, pPts); - return; - } - if (pGC->lineStyle == LineDoubleDash && - (pGC->fillStyle == FillOpaqueStippled || pGC->fillStyle == FillTiled)) - { - miWideLine (pDrawable, pGC, mode, npt, pPts); - return; - } - if (npt == 0) - return; - spanData = miSetupSpanData (pGC, &spanDataRec, npt); - x2 = pPts->x; - y2 = pPts->y; - first = TRUE; - selfJoin = FALSE; - if (mode == CoordModePrevious) - { - int nptTmp; - DDXPointPtr pPtsTmp; - - x1 = x2; - y1 = y2; - nptTmp = npt; - pPtsTmp = pPts + 1; - while (--nptTmp) - { - x1 += pPtsTmp->x; - y1 += pPtsTmp->y; - ++pPtsTmp; - } - if (x2 == x1 && y2 == y1) - selfJoin = TRUE; - } - else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y) - { - selfJoin = TRUE; - } - projectLeft = pGC->capStyle == CapProjecting && !selfJoin; - projectRight = FALSE; - dashIndex = 0; - dashOffset = 0; - miStepDash ((int)pGC->dashOffset, &dashIndex, - pGC->dash, (int)pGC->numInDashList, &dashOffset); - while (--npt) - { - x1 = x2; - y1 = y2; - ++pPts; - x2 = pPts->x; - y2 = pPts->y; - if (mode == CoordModePrevious) - { - x2 += x1; - y2 += y1; - } - if (x1 != x2 || y1 != y2) - { - somethingDrawn = TRUE; - if (npt == 1 && pGC->capStyle == CapProjecting && - (!selfJoin || !firstIsFg)) - projectRight = TRUE; - prevDashIndex = dashIndex; - miWideDashSegment (pDrawable, pGC, spanData, &dashOffset, &dashIndex, - x1, y1, x2, y2, - projectLeft, projectRight, &leftFace, &rightFace); - startIsFg = !(prevDashIndex & 1); - endIsFg = (dashIndex & 1) ^ (dashOffset != 0); - if (pGC->lineStyle == LineDoubleDash || startIsFg) - { - pixel = startIsFg ? pGC->fgPixel : pGC->bgPixel; - if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg)) - { - if (first && selfJoin) - { - firstFace = leftFace; - firstIsFg = startIsFg; - } - else if (pGC->capStyle == CapRound) - miLineArc (pDrawable, pGC, pixel, spanData, - &leftFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, TRUE); - } - else - { - miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace, - &prevRightFace); - } - } - prevRightFace = rightFace; - prevIsFg = endIsFg; - first = FALSE; - projectLeft = FALSE; - } - if (npt == 1 && somethingDrawn) - { - if (pGC->lineStyle == LineDoubleDash || endIsFg) - { - pixel = endIsFg ? pGC->fgPixel : pGC->bgPixel; - if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg)) - { - miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace, - &rightFace); - } - else - { - if (pGC->capStyle == CapRound) - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rightFace, - (double)0.0, (double)0.0, TRUE); - } - } - else - { - /* glue a cap to the start of the line if - * we're OnOffDash and ended on odd dash - */ - if (selfJoin && firstIsFg) - { - pixel = pGC->fgPixel; - if (pGC->capStyle == CapProjecting) - miLineProjectingCap (pDrawable, pGC, pixel, spanData, - &firstFace, TRUE, - (double)0.0, (double)0.0, TRUE); - else if (pGC->capStyle == CapRound) - miLineArc (pDrawable, pGC, pixel, spanData, - &firstFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, TRUE); - } - } - } - } - /* handle crock where all points are coincident */ - if (!somethingDrawn && (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))) - { - /* not the same as endIsFg computation above */ - pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel; - switch (pGC->capStyle) { - case CapRound: - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, (LineFacePtr) NULL, - (double)x2, (double)y2, - FALSE); - break; - case CapProjecting: - x1 = pGC->lineWidth; - miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, - x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1); - break; - } - } - if (spanData) - miCleanupSpanData (pDrawable, pGC, spanData); -} - -/* these are stubs to allow old ddx ValidateGCs to work without change */ - -void -miMiter() -{ -} - -void -miNotMiter() -{ -}