📄 miwideline.c
字号:
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 (GdkDrawable *pDrawable, GdkGC *pGC, GdkColor *pixel, SpanDataPtr spanData, int x1, int y1, int x2, int y2, gboolean projectLeft, gboolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace){ double l, L, r; double xa, ya; double projectXoff = 0.0, projectYoff = 0.0; 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 = GDK_GC_FBDATA(pGC)->values.line_width; g_assert(leftFace); /* 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; g_assert(leftFace); 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 (register GdkGC *pGC, SpanDataPtr spanData, int npt){ if ((npt < 3 && GDK_GC_FBDATA(pGC)->values.cap_style != GDK_CAP_ROUND) || miSpansEasyRop(GDK_GC_FBDATA(pGC)->alu)) return (SpanDataPtr) NULL; if (GDK_GC_FBDATA(pGC)->values.line_style == GDK_LINE_DOUBLE_DASH) miInitSpanGroup (&spanData->bgGroup); miInitSpanGroup (&spanData->fgGroup); return spanData;}voidmiCleanupSpanData (GdkDrawable *pDrawable, GdkGC *pGC, SpanDataPtr spanData){ if (GDK_GC_FBDATA(pGC)->values.line_style == GDK_LINE_DOUBLE_DASH) { GdkColor oldPixel, pixel; pixel = GDK_GC_FBDATA(pGC)->values.background; oldPixel = GDK_GC_FBDATA(pGC)->values.foreground; if (pixel.pixel != oldPixel.pixel) gdk_gc_set_foreground(pGC, &pixel); miFillUniqueSpanGroup (pDrawable, pGC, &spanData->bgGroup); miFreeSpanGroup (&spanData->bgGroup); if (pixel.pixel != oldPixel.pixel) gdk_gc_set_foreground(pGC, &oldPixel); } miFillUniqueSpanGroup (pDrawable, pGC, &spanData->fgGroup); miFreeSpanGroup (&spanData->fgGroup);}voidmiWideLine (GdkDrawable *pDrawable, GdkGC *pGC, int mode, register int npt, register GdkPoint *pPts){ int x1, y1, x2, y2; SpanDataRec spanDataRec; SpanDataPtr spanData; GdkColor pixel; gboolean projectLeft, projectRight; LineFaceRec leftFace, rightFace, prevRightFace; LineFaceRec firstFace; register int first; gboolean somethingDrawn = FALSE; gboolean selfJoin; spanData = miSetupSpanData (pGC, &spanDataRec, npt); pixel = GDK_GC_FBDATA(pGC)->values.foreground; x2 = pPts->x; y2 = pPts->y; first = TRUE; selfJoin = FALSE; if (npt > 1) { if (0 /* mode == CoordModePrevious*/) { int nptTmp; GdkPoint* 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 = GDK_GC_FBDATA(pGC)->values.cap_style == GDK_CAP_PROJECTING && !selfJoin; projectRight = FALSE; while (--npt) { x1 = x2; y1 = y2; ++pPts; x2 = pPts->x; y2 = pPts->y; if (0 /* mode == CoordModePrevious */) { x2 += x1; y2 += y1; } if (x1 != x2 || y1 != y2) { somethingDrawn = TRUE; if (npt == 1 && GDK_GC_FBDATA(pGC)->values.cap_style == GDK_CAP_PROJECTING && !selfJoin) projectRight = TRUE; miWideSegment (pDrawable, pGC, &pixel, spanData, x1, y1, x2, y2, projectLeft, projectRight, &leftFace, &rightFace); if (first) { if (selfJoin) firstFace = leftFace; else if (GDK_GC_FBDATA(pGC)->values.cap_style == GDK_CAP_ROUND) { if (GDK_GC_FBDATA(pGC)->values.line_width == 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 (GDK_GC_FBDATA(pGC)->values.cap_style == GDK_CAP_ROUND) { if (GDK_GC_FBDATA(pGC)->values.line_width == 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 = GDK_GC_FBDATA(pGC)->values.cap_style == GDK_CAP_PROJECTING; miWideSegment (pDrawable, pGC, &pixel, spanData, x2, y2, x2, y2, projectLeft, projectLeft, &leftFace, &rightFace); if (GDK_GC_FBDATA(pGC)->values.cap_style == GDK_CAP_ROUND) { 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 3static voidmiWideDashSegment (GdkDrawable *pDrawable, register GdkGC *pGC, SpanDataPtr spanData, int *pDashOffset, int *pDashIndex, int x1, int y1, int x2, int y2, gboolean projectLeft, gboolean projectRight, LineFacePtr leftFace, LineFacePtr 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; GdkColor pixel; double LRemain; double r; double rdx, rdy; double dashDx, dashDy; double saveK = 0.0; gboolean first = TRUE; double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0; GdkColor fgPixel, bgPixel; dx = x2 - x1; dy = y2 - y1; dashIndex = *pDashIndex; pDash = GDK_GC_FBDATA(pGC)->dash_list; dashRemain = pDash[dashIndex] - *pDashOffset; fgPixel = GDK_GC_FBDATA(pGC)->values.foreground; bgPixel = GDK_GC_FBDATA(pGC)->values.background; if (GDK_GC_FBDATA(pGC)->values.fill == GDK_OPAQUE_STIPPLED ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -