📄 miwideline.c
字号:
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 voidmiWideSegment (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); }}SpanDataPtrmiSetupSpanData (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;}voidmiCleanupSpanData (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);}voidmiWideLine (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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -