📄 gxj_putpixel.c
字号:
* draw dotted pixels from (x1,y1) through (x2,y1) * x1 should be <= x2, y1 == y2 * coordinates are clipped against the clip */static voiddrawClippedDottedHorzLine(const jshort *clip, gxj_screen_buffer *sbuf, gxj_pixel_type color, int x1, int y1, int x2, int y2, dotted_draw_state dds) { const jshort clipX1 = clip[0]; const jshort clipY1 = clip[1]; const jshort clipX2 = clip[2]; const jshort clipY2 = clip[3]; (void)y2; if (x1 >= clipX2 || x2 < clipX1 || y1 < clipY1 || y1 >= clipY2) return; if (x1 < clipX1) { SetUpDottedParamsByPixels(clipX1 - x1, &dds); x1 = clipX1; } x2 = (x2 >= clipX2) ? clipX2-1 : x2; CHECK_XY_CLIP(sbuf, x1, y1); CHECK_XY_CLIP(sbuf, x2, y1); drawDottedHorzLine(sbuf, color, x1, y1, x2, y1, dds);}/** * draw rectangle outline, without painting corner pixels twice * * x2 >= x1, y2 >= y1 */static voidprimDrawSolidRect(gxj_screen_buffer *sbuf, gxj_pixel_type color, int x1, int y1, int x2, int y2) { primDrawHorzLine(sbuf, color, x1, y1, x2, y1); primDrawHorzLine(sbuf, color, x1, y2, x2, y2); if (y2-1 > y1+1) { primDrawVertLine(sbuf, color, x1, y1 + 1, x1, y2 - 1); primDrawVertLine(sbuf, color, x2, y1 + 1, x2, y2 - 1); }}/** * draw patterned rectangle outline, without painting corner pixels twice * NOTE: pattern is reset for each segment * * x2 >= x1, y2 >= y1 */static voidprimDrawDottedRect(gxj_screen_buffer *sbuf, gxj_pixel_type color, int x1, int y1, int x2, int y2) { primDrawDottedHorzLine(sbuf, color, x1, y1, x2, y1); primDrawDottedHorzLine(sbuf, color, x1, y2, x2, y2); if (y2-1 > y1+1) { primDrawDottedVertLine(sbuf, color, x1, y1 + 1, x1, y2 - 1); primDrawDottedVertLine(sbuf, color, x2, y1 + 1, x2, y2 - 1); }}/** * draw filled rectangle, this does NOT paint the pixels * along the x2 or y2 edges. * * x2 > x1, y2 > y1 */static voidprimDrawFilledRect(gxj_screen_buffer *sbuf, gxj_pixel_type color, int x1, int y1, int x2, int y2) {#if 0 int width = sbuf->width; int height = sbuf->height; int count; gxj_pixel_type* pPtr; gxj_pixel_type* lPtr;#if PRIM_CLIPPING x1 = (x1 < 0) ? 0 : ((x1 > width) ? width : x1); x2 = (x2 < 0) ? 0 : ((x2 > width) ? width : x2); y1 = (y1 < 0) ? 0 : ((y1 > height) ? height : y1); y2 = (y2 < 0) ? 0 : ((y2 > height) ? height : y2);#endif if ((count=x2-x1) < 0) { SWAP(x2, x1); count = -count; } pPtr = &(sbuf->pixelData[y1 * width + x1]); for (lPtr = pPtr; y1 < y2; y1++) { while (count & ~0x7) { CHECK_PTR_CLIP(sbuf,pPtr); *pPtr = color; pPtr += 1; *pPtr = color; pPtr += 1; *pPtr = color; pPtr += 1; *pPtr = color; pPtr += 1; *pPtr = color; pPtr += 1; *pPtr = color; pPtr += 1; *pPtr = color; pPtr += 1; *pPtr = color; CHECK_PTR_CLIP(sbuf,pPtr); pPtr += 1; count -= 8; } while (count > 0) { CHECK_PTR_CLIP(sbuf,pPtr); *pPtr = color; pPtr += 1; count -= 1; } lPtr += width; count = x2 - x1; pPtr = lPtr; }#else int width = sbuf->width; int height = sbuf->height; int count; gxj_pixel_type* pPtr; gxj_pixel_type* lPtr; registers_4 regs; unsigned int c = ((unsigned int)color) << 16 | ((unsigned int)color); jlong lcol = ((jlong) c) << 32 | ((jlong) c); regs.r0 = regs.r1 = regs.r2 = regs.r3 = c;#if PRIM_CLIPPING y1 = (y1 < 0) ? 0 : ((y1 > height) ? height : y1); y2 = (y2 < 0) ? 0 : ((y2 > height) ? height : y2);#endif pPtr = &(sbuf->pixelData[y1 * width]);#if PRIM_CLIPPING x1 = (x1 < 0) ? 0 : ((x1 > width) ? width : x1); x2 = (x2 < 0) ? 0 : ((x2 > width) ? width : x2);#endif if ((count=x2-x1) < 0) { SWAP(x2, x1); count = -count; } pPtr += x1; if (x1 == 0 && x2 == (width)) { count = width*(y2-y1); y2 = y1+1; } for (lPtr = pPtr; y1 < y2; y1++) { if (((unsigned int)pPtr & 0x3) && (count > 0)) { CHECK_PTR_CLIP(sbuf,pPtr); *pPtr++ = color; --count; } while (count >= 16) { CHECK_LLPTR_CLIP(sbuf,pPtr); *((registers_4 *)pPtr) = regs; pPtr += 8; CHECK_LLPTR_CLIP(sbuf,pPtr); *((registers_4 *)pPtr) = regs; pPtr += 8; count -= 16; } if (count >= 8) { CHECK_LLPTR_CLIP(sbuf,pPtr); *((registers_4 *)pPtr) = regs; pPtr += 8; count -= 8; } if (count >= 4) { CHECK_LLPTR_CLIP(sbuf,pPtr); *((jlong *)pPtr) = lcol; pPtr += 4; count -= 4; } while (count > 0) { CHECK_PTR_CLIP(sbuf,pPtr); *pPtr++ = color; count -= 1; } lPtr += width; count = x2 - x1; pPtr = lPtr; }#endif}static voiddrawClippedRect(gxj_screen_buffer *sbuf, gxj_pixel_type color, int lineStyle, int filled, const jshort *clip, int x, int y, int width, int height) { int x1, y1, x2, y2, x2UnClipped, y2UnClipped; if (clip == NULL) { x1 = x; y1 = y; x2 = x + width; y2 = y + height; if (filled) { primDrawFilledRect(sbuf, color, x1, y1, x2, y2); } else { if (lineStyle == DOTTED) { primDrawDottedVertLine(sbuf, color, x1, y1, x1, y2); primDrawDottedHorzLine(sbuf, color, x1, y1, x2, y1); primDrawDottedVertLine(sbuf, color, x2, y1, x2, y2); primDrawDottedHorzLine(sbuf, color, x1, y2, x2, y2); } else { primDrawVertLine(sbuf, color, x1, y1, x1, y2); primDrawHorzLine(sbuf, color, x1, y1, x2, y1); primDrawVertLine(sbuf, color, x2, y1, x2, y2); primDrawHorzLine(sbuf, color, x1, y2, x2, y2); } } return; } CHECK_SBUF_CLIP_BOUNDS(sbuf, clip); { const jshort clipX1 = clip[0]; const jshort clipY1 = clip[1]; const jshort clipX2 = clip[2]; const jshort clipY2 = clip[3]; if (clipX1 == clipX2 || clipY1 == clipY2) return; x1 = max(x, clipX1); y1 = max(y, clipY1); x2UnClipped = x + width; y2UnClipped = y + height; x2 = min(x2UnClipped, clipX2); y2 = min(y2UnClipped, clipY2); } if (filled) { /* check that it's still there after clipping */ if ((x1 > x2) || (y1 > y2)) { return; } primDrawFilledRect(sbuf, color, x1, y1, x2, y2); } else { /* have we been clipped out of existence? */ if (((x1 > x) && (x2 < x2UnClipped) && (y1 > y) && (y2 < y2UnClipped)) || (x1 > x2) || (y1 > y2)) { return; } /* is the left side still there? */ if (x1 == x) { if (lineStyle == DOTTED) { primDrawDottedVertLine(sbuf, color, x1, y1, x1, y2); } else { primDrawVertLine(sbuf, color, x1, y1, x1, y2); } } /* is the top still there? */ if (y1 == y) { if (lineStyle == DOTTED) { primDrawDottedHorzLine(sbuf, color, x1, y1, x2, y1); } else { primDrawHorzLine(sbuf, color, x1, y1, x2, y1); } } /* is the left side still there? */ if (x2 == x2UnClipped) { if (lineStyle == DOTTED) { primDrawDottedVertLine(sbuf, color, x2, y1, x2, y2); } else { primDrawVertLine(sbuf, color, x2, y1, x2, y2); } } /* and how about the bottom? */ if (y2 == y2UnClipped) { if (lineStyle == DOTTED) { primDrawDottedHorzLine(sbuf, color, x1, y2, x2, y2); } else { primDrawHorzLine(sbuf, color, x1, y2, x2, y2); } } }}/* IMPL_NOTE easy optimization is to break drawSymmetricPixels into separate routines for the different cases, then use function pointers to call the appropriate one IMPL_NOTE another one is to make the params to drawSymmetricPixels sit in a struct and just pass the pointer to the struct instead of all the params - this will probably help, depending on number of references taking xOrigin and yOrigin as the origin in Windows coordinates, and x, y as Cartesian coordinates, this draws the Windows points for all 4 quadrants. (remember that in Windows bigger y goes down, opposite of Cartesian) this function is not used for filled partial or filled clipped arcs it is used for all non-filled arcs, and unclipped,full filled arcs. dds is used only if lineStyle == DOTTED */static voiddrawSymmetricPixels(gxj_screen_buffer *sbuf, gxj_pixel_type color, int lineStyle, int filled, const jshort *clip, int startRatio, int startQuadrant, int endRatio, int endQuadrant, int quadrantStatus[4], dotted_draw_state * dds, int xOrigin, int yOrigin, int evenXOffset, int evenYOffset, int x, int y) { int x1, y1, x2, y2; int curRatio; const jshort clipX1 = clip[0]; const jshort clipY1 = clip[1]; const jshort clipX2 = clip[2]; const jshort clipY2 = clip[3]; CHECK_SBUF_CLIP_BOUNDS(sbuf, clip); /* Surpress unused parameter warnings */ (void)filled; x1 = xOrigin + x; y1 = yOrigin - y; x2 = xOrigin - x - evenXOffset; y2 = yOrigin + y + evenYOffset; /* check for case of unclipped, complete ellipse */ if (startQuadrant == -1) { } /* take care of unfilled partial or clipped (or both) arc */ else { if (x == 0) { curRatio = MAXINT32; } else { curRatio = (y * 1000) / x; } /* this is for an unfilled, partial or clipped (or both) arc */ if (((quadrantStatus[0] & QUADRANT_STATUS_FULL_ARC) || ((quadrantStatus[0] & QUADRANT_STATUS_PARTIAL_ARC) && (((startQuadrant == 1) && (endQuadrant != 1) && (curRatio >= startRatio)) || ((endQuadrant == 1) && (startQuadrant != 1) && (curRatio <= endRatio)) || ((startQuadrant == 1) && (endQuadrant == 1) && (startRatio >= endRatio) && ((curRatio >= endRatio) || (curRatio <= startRatio))) || ((startQuadrant == 1) && (endQuadrant == 1) && (startRatio < endRatio) && (curRatio >= startRatio) && (curRatio <= endRatio))))) && ((quadrantStatus[0] & QUADRANT_STATUS_UNCLIPPED) || ((quadrantStatus[0] & QUADRANT_STATUS_PARTIALLY_CLIPPED) && (x1 >= clipX1) && (y1 >= clipY1) && (x1 < clipX2) && (y1 < clipY2)))) { if (lineStyle == DOTTED) { drawDottedPixel(sbuf, color, x1, y1, &dds[0]); } else { PRIMDRAWPIXEL(sbuf, color, x1, y1); } } if (((quadrantStatus[1] & QUADRANT_STATUS_FULL_ARC) || ((quadrantStatus[1] & QUADRANT_STATUS_PARTIAL_ARC) && (((startQuadrant == 2) && (endQuadrant != 2) && (curRatio <= startRatio)) || ((endQuadrant == 2) && (startQuadrant != 2) && (curRatio >= endRatio)) || ((startQuadrant == 2) && (endQuadrant == 2) && (startRatio <= endRatio) && ((curRatio <= endRatio) || (curRatio >= startRatio))) || ((startQuadrant == 2) && (endQuadrant == 2) && (startRatio > endRatio) && (curRatio <= startRatio) && (curRatio >= endRatio))))) && ((quadrantStatus[1] & QUADRANT_STATUS_UNCLIPPED) || ((quadrantStatus[1] & QUADRANT_STATUS_PARTIALLY_CLIPPED) && (x2 >= clipX1) && (y1 >= clipY1) && (x2 < clipX2) && (y1 < clipY2)))) { if (lineStyle == DOTTED) { drawDottedPixel(sbuf, color, x2, y1, &dds[1]); } else { PRIMDRAWPIXEL(sbuf, color, x2, y1); } } if (((quadrantStatus[2] & QUADRANT_STATUS_FULL_ARC) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -