📄 gxj_putpixel.c
字号:
((quadrantStatus[2] & QUADRANT_STATUS_PARTIAL_ARC) && (((startQuadrant == 3) && (endQuadrant != 3) && (curRatio >= startRatio)) || ((endQuadrant == 3) && (startQuadrant != 3) && (curRatio <= endRatio)) || ((startQuadrant == 3) && (endQuadrant == 3) && (startRatio >= endRatio) && ((curRatio >= endRatio) || (curRatio <= startRatio))) || ((startQuadrant == 3) && (endQuadrant == 3) && (startRatio < endRatio) && (curRatio >= startRatio) && (curRatio <= endRatio))))) && ((quadrantStatus[2] & QUADRANT_STATUS_UNCLIPPED) || ((quadrantStatus[2] & QUADRANT_STATUS_PARTIALLY_CLIPPED) && (x2 >= clipX1) && (y2 >= clipY1) && (x2 < clipX2) && (y2 < clipY2)))) { if (lineStyle == DOTTED) { drawDottedPixel(sbuf, color, x2, y2, &dds[2]); } else { PRIMDRAWPIXEL(sbuf, color, x2, y2); } } if (((quadrantStatus[3] & QUADRANT_STATUS_FULL_ARC) || ((quadrantStatus[3] & QUADRANT_STATUS_PARTIAL_ARC) && (((startQuadrant == 4) && (endQuadrant != 4) && (curRatio <= startRatio)) || ((endQuadrant == 4) && (startQuadrant != 4) && (curRatio >= endRatio)) || ((startQuadrant == 4) && (endQuadrant == 4) && (startRatio <= endRatio) && ((curRatio <= endRatio) || (curRatio >= startRatio))) || ((startQuadrant == 4) && (endQuadrant == 4) && (startRatio > endRatio) && (curRatio <= startRatio) && (curRatio >= endRatio))))) && ((quadrantStatus[3] & QUADRANT_STATUS_UNCLIPPED) || ((quadrantStatus[3] & QUADRANT_STATUS_PARTIALLY_CLIPPED) && (x1 >= clipX1) && (y2 >= clipY1) && (x1 < clipX2) && (y2 < clipY2)))) { if (lineStyle == DOTTED) { drawDottedPixel(sbuf, color, x1, y2, &dds[3]); } else { PRIMDRAWPIXEL(sbuf, color, x1, y2); } } }}static voidSetUpEllipseParams(int x1, int y1, int x2, int y2, int *a, int *b, int *a2, int *b2, int *S, int *T, int *xCenter, int *yCenter, int *evenXOffset, int *evenYOffset) { (*a) = (x2 - x1) / 2; (*evenXOffset) = ((x2 - x1) % 2) == 0 ? 0 : 1; (*b) = (y2 - y1) / 2; (*evenYOffset) = ((y2 - y1) % 2) == 0 ? 0 : 1; (*a2) = (*a)*(*a); (*b2) = (*b)*(*b); /* x and y are cartesian coordinates around the origin (0, 0) * other coordinates are Windows style */ (*S) = (*a2)*(1-2*(*b)) + 2*(*b2); (*T) = (*b2) - 2*(*a2)*(2*(*b)-1); (*xCenter) = x1 + (*a) + (*evenXOffset); (*yCenter) = y1 + (*b);}static voidGetNextEllipsePoint(int a2, int b2, int *S, int *T, int *x, int *y) { if ((*S)<0) { (*S) += 2*b2*(2*(*x)+3); (*T) += 4*b2*((*x)+1); (*x)++; } else if ((*T)<0) { (*S) += 2*b2*(2*(*x)+3) - 4*a2*((*y)-1); (*T) += 4*b2*((*x)+1) - 2*a2*(2*(*y)-3); (*x)++; (*y)--; } else { (*S) -= 4*a2*((*y)-1); (*T) -= 2*a2*(2*(*y)-3); (*y)--; }}static voidSetUpDottedLineParams(int nPixels, int evenXOffset, int evenYOffset, dotted_draw_state * dds) { int offset; int nPixelsTwoQuadrants; nPixelsTwoQuadrants = (2 * nPixels) + ((evenYOffset == 0) ? -1 : 0); /* 1st quadrant starts drawing the pattern from the beginning */ dds[0] = START_STROKE; /* the following is the magic formula for figuring out how to draw * the fourth quadrant backwards so that when it's done it meets * the first quadrant in such a way that it continues the dotted * line pattern cleanly */ offset = (DOTTED_SOLID_SIZE - nPixelsTwoQuadrants) % (DOTTED_SOLID_SIZE + DOTTED_EMPTY_SIZE); if (offset < 0) { /* Really need to just remember proper mod operator! */ offset += (DOTTED_SOLID_SIZE + DOTTED_EMPTY_SIZE); } dds[3].solidcount = (offset >= DOTTED_SOLID_SIZE) ? DOTTED_SOLID_SIZE : offset; dds[3].emptycount = (offset >= DOTTED_SOLID_SIZE) ? offset - DOTTED_SOLID_SIZE : DOTTED_EMPTY_SIZE; dds[3].drawing = dds[3].solidcount < DOTTED_SOLID_SIZE; /* same idea for making drawing of third quadrant match the adjacent * part of the pattern in the fourth quadrant */ offset = nPixelsTwoQuadrants % (DOTTED_SOLID_SIZE + DOTTED_EMPTY_SIZE); offset += ((evenXOffset == 0) ? -1 : 0); dds[2].solidcount = (offset >= DOTTED_SOLID_SIZE) ? DOTTED_SOLID_SIZE : offset; dds[2].emptycount = (offset >= DOTTED_SOLID_SIZE) ? offset - DOTTED_SOLID_SIZE : DOTTED_EMPTY_SIZE; dds[2].drawing = dds[3].solidcount < DOTTED_SOLID_SIZE; /* same idea for meeting of second and first quadrants */ offset = DOTTED_SOLID_SIZE + ((evenXOffset == 0) ? -1 : 0); dds[1].solidcount = (offset >= DOTTED_SOLID_SIZE) ? DOTTED_SOLID_SIZE : offset; dds[1].emptycount = (offset >= DOTTED_SOLID_SIZE) ? offset - DOTTED_SOLID_SIZE : DOTTED_EMPTY_SIZE; dds[1].drawing = dds[3].solidcount < DOTTED_SOLID_SIZE; /* alas, the meeting of the second and third * quadrants can't be made exact */}static intgetQuadrantStatus(int quadrant, int x1, int y1, int x2, int y2, const jshort *clip, int startRatio, int startQuadrant, int endRatio, int endQuadrant) { int quadrantStatus; const jshort clipX1 = clip[0]; const jshort clipY1 = clip[1]; const jshort clipX2 = clip[2]; const jshort clipY2 = clip[3]; quadrantStatus = QUADRANT_STATUS_UNDEFINED; if ((x1 >= clipX1) && (x2 < clipX2) && (y1 >= clipY1) && (y2 < clipY2)) { quadrantStatus |= QUADRANT_STATUS_UNCLIPPED; } else if ((x1 >= clipX2) || (x2 < clipX1) || (y1 >= clipY2) || (y2 <= clipY1)) { quadrantStatus |= QUADRANT_STATUS_TOTALLY_CLIPPED; return quadrantStatus; } else { quadrantStatus |= QUADRANT_STATUS_PARTIALLY_CLIPPED; } if (startQuadrant == -1) { quadrantStatus |= QUADRANT_STATUS_FULL_ARC; } else if (((quadrant == startQuadrant) && (startRatio > 0) && (startRatio < MAXINT32)) || ((quadrant == endQuadrant) && (endRatio > 0) && (endRatio < MAXINT32))) { quadrantStatus |= QUADRANT_STATUS_PARTIAL_ARC; } else if ((quadrant == startQuadrant) && (quadrant != endQuadrant)) { quadrantStatus |= QUADRANT_STATUS_FULL_ARC; } else if ((startQuadrant < endQuadrant) && (quadrant > startQuadrant) && (quadrant < endQuadrant)) { quadrantStatus |= QUADRANT_STATUS_FULL_ARC; } else if ((startQuadrant > endQuadrant) && ((quadrant > startQuadrant) || (quadrant < endQuadrant))) { quadrantStatus |= QUADRANT_STATUS_FULL_ARC; } else if ((startQuadrant == endQuadrant) && ((((startQuadrant == 1) || (startQuadrant == 3)) && (startRatio > endRatio)) || (((startQuadrant == 2) || (startQuadrant == 4)) && (startRatio < endRatio))) && (quadrant != startQuadrant)) { quadrantStatus |= QUADRANT_STATUS_FULL_ARC; } else { quadrantStatus |= QUADRANT_STATUS_NO_ARC; } return quadrantStatus;}static voidGetArcHelperParams(int x, int y, int w, int h, int startAngle, int endAngle, const jshort *clip, int *startQuadrant, int *startRatio, int *endQuadrant, int *endRatio, int *quadrantStatus) { int a, b, a2, b2, S, T; int evenXOffset, evenYOffset; int x2, y2; int xCenter, yCenter; x2 = x + w; y2 = y + h; /* only need some of these params, but for * now haven't separated out the code */ SetUpEllipseParams(x, y, x2, y2, &a, &b, &a2, &b2, &S, &T, &xCenter, &yCenter, &evenXOffset, &evenYOffset); if (startAngle != endAngle) { *startQuadrant = (startAngle / 90) + 1; *endQuadrant = (endAngle / 90) + 1; *startRatio = absIntTan1000(startAngle); if (*startRatio < MAXINT32) { *startRatio = (h * *startRatio) / w; } *endRatio = absIntTan1000(endAngle); if (*endRatio < MAXINT32) { *endRatio = (h * *endRatio) / w; } } else { *startRatio = 0; *endRatio = 0; } /* now check each quadrant's status */ quadrantStatus[0] = getQuadrantStatus(1, xCenter, y, x2, yCenter, clip, *startRatio, *startQuadrant, *endRatio, *endQuadrant); quadrantStatus[1] = getQuadrantStatus(2, x, y, xCenter, yCenter, clip, *startRatio, *startQuadrant, *endRatio, *endQuadrant); quadrantStatus[2] = getQuadrantStatus(3, x, yCenter, xCenter, y2, clip, *startRatio, *startQuadrant, *endRatio, *endQuadrant); quadrantStatus[3] = getQuadrantStatus(4, xCenter, yCenter, x2, y2, clip, *startRatio, *startQuadrant, *endRatio, *endQuadrant);}static voidSetUpArcEndPoints(int x, int y, int w, int h, int startQuadrant, int startRatio, int endQuadrant, int endRatio, int *start_x, int *start_y, int *end_x, int *end_y, int *start_x1, int *start_y1, int *end_x1, int *end_y1, int *start_x2, int *start_y2, int *end_x2, int *end_y2) { int a,b; int a2,b2, S, T; int xCenter, yCenter; int evenXOffset, evenYOffset; int x_point, y_point; int curRatio; int boundary_x1 = 0, boundary_x2 = 0, boundary_x3 = 0, boundary_x4 = 0; int boundary_y1 = 0, boundary_y2 = 0, boundary_y3 = 0, boundary_y4 = 0; /* we need to set up start and end points for partial, filled arcs * we do this by getting 4 pairs of coordinates, right before and * after each exact start and end point, and afterwards choosing * the correct two pairs depending on which quadrant they're in */ boundary_x1 = -1; boundary_x3 = -1; SetUpEllipseParams(x, y, x + w, y + h, &a, &b, &a2, &b2, &S, &T, &xCenter, &yCenter, &evenXOffset, &evenYOffset); x_point = 0; y_point = b; while(y_point >= 0) { curRatio = (x_point == 0) ? MAXINT32 : ((y_point * 1000) / x_point); if ((boundary_x1 == -1) && (curRatio <= startRatio)) { boundary_x1 = x_point; boundary_y1 = y_point; } if (curRatio >= startRatio) { boundary_x2 = x_point; boundary_y2 = y_point; } if ((boundary_x3 == -1) && (curRatio <= endRatio)) { boundary_x3 = x_point; boundary_y3 = y_point; } if (curRatio >= endRatio) { boundary_x4 = x_point; boundary_y4 = y_point; } GetNextEllipsePoint(a2, b2, &S, &T, &x_point, &y_point); } /* first establish where the start and end points of the partial arc are */ if ((startQuadrant == 1) || (startQuadrant == 3)) { *start_x = boundary_x1; *start_y = boundary_y1; } else { *start_x = boundary_x2; *start_y = boundary_y2; } if ((endQuadrant == 1) || (endQuadrant == 3)) { *end_x = boundary_x3; *end_y = boundary_y3; } else { *end_x = boundary_x4; *end_y = boundary_y4; } *start_x1 = xCenter + *start_x; *start_y1 = yCenter - *start_y; *start_x2 = xCenter - *start_x - evenXOffset; *start_y2 = yCenter + *start_y + evenYOffset; *end_x1 = xCenter + *end_x; *end_y1 = yCenter - *end_y; *end_x2 = xCenter - *end_x - evenXOffset; *end_y2 = yCenter + *end_y + evenYOffset;}static intcalcNPixelsInQuadrant(int x, int y, int w, int h){ int a, b, a2, b2, S, T; int evenXOffset, evenYOffset; int xCenter, yCenter; int x_point, y_point; int nPixels; SetUpEllipseParams(x, y, x + w, y + h, &a, &b, &a2, &b2, &S, &T, &xCenter, &yCenter, &evenXOffset, &evenYOffset); x_point = 0; y_point = b; for (nPixels = 0; (y_point >= 0); ++nPixels) { GetNextEllipsePoint(a2, b2, &S, &T, &x_point, &y_point); } return nPixels;}static voiddrawClippedOutlineArc(gxj_screen_buffer *sbuf, gxj_pixel_type color, int lineStyle, const jshort *clip, int startQuadrant, int startRatio, int endQuadrant, int endRatio, int nPixelsInQuadrant, int quadrantStatus[4], int x, int y, int w, int h) { int a,b; int a2,b2, S, T; int xCenter, yCenter; int curRatio; int evenXOffset, evenYOffset; dotted_draw_state dds[4]; /* used for dotted lines only */ int x_point, y_point; CHECK_SBUF_CLIP_BOUNDS(sbuf, clip); SetUpEllipseParams(x, y, x + w, y + h, &a, &b, &a2, &b2, &S, &T, &xCenter, &yCenter, &evenXOffset, &evenYOffset); if (lineStyle == DOTTED) { SetUpDottedLineParams(nPixelsInQuadrant, evenXOffset, evenYOffset, dds); } x_point = 0; y_point = b; while(y_point >= 0) { curRatio = (x_point == 0) ? MAXINT32 : ((y_point * 1000) / x_point); drawSymmetricPixels(sbuf, color, lineStyle, 0, clip, startRatio, startQuadrant, endRatio, endQuadrant, quadrantStatus, dds, xCenter, yCenter, evenXOffset, evenYOffset, x_point, y_point); GetNextEllipsePoint(a2, b2, &S, &T, &x_point, &y_point); }}/* drawFilledRightTriangle is called with the two points that aren't the * square corner the corner is located at x2, y1 */static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -