📄 sdl_gfxprimitives.c
字号:
*x1 += (Sint16) ((bottom - *y1) / m); } *y1 = bottom; } else if (code1 & CLIP_TOP_EDGE) { if (*x2 != *x1) { *x1 += (Sint16) ((top - *y1) / m); } *y1 = top; } } } return draw;}/* ----- Filled rectangle (Box) */int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color){ Sint16 left, right, top, bottom; Uint8 *pixel, *pixellast; int x, dx; int dy; int pixx, pixy; Sint16 w, h, tmp; int result; Uint8 *colorptr; /* * Get clipping boundary */ left = dst->clip_rect.x; right = dst->clip_rect.x + dst->clip_rect.w - 1; top = dst->clip_rect.y; bottom = dst->clip_rect.y + dst->clip_rect.h - 1; /* Check visibility */ if ((x1<left) && (x2<left)) { return(0); } if ((x1>right) && (x2>right)) { return(0); } if ((y1<top) && (y2<top)) { return(0); } if ((y1>bottom) && (y2>bottom)) { return(0); } /* Clip all points */ if (x1<left) { x1=left; } else if (x1>right) { x1=right; } if (x2<left) { x2=left; } else if (x2>right) { x2=right; } if (y1<top) { y1=top; } else if (y1>bottom) { y1=bottom; } if (y2<top) { y2=top; } else if (y2>bottom) { y2=bottom; } /* * Order coordinates */ if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; } if (y1 > y2) { tmp = y1; y1 = y2; y2 = tmp; } /* * Test for special cases of straight line or single point */ if (x1 == x2) { if (y1 == y2) { return (pixelColor(dst, x1, y1, color)); } else { return (vlineColor(dst, x1, y1, y2, color)); } } if (y1 == y2) { return (hlineColor(dst, x1, x2, y1, color)); } /* * Calculate width&height */ w = x2 - x1; h = y2 - y1; /* * Alpha check */ if ((color & 255) == 255) { /* * No alpha-blending required */ /* * Setup color */ colorptr = (Uint8 *) & color; if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]); } else { color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]); } /* * Lock surface */ SDL_LockSurface(dst); /* * More variable setup */ dx = w; dy = h; pixx = dst->format->BytesPerPixel; pixy = dst->pitch; pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1; pixellast = pixel + pixx * dx + pixy * dy; dx++; /* * Draw */ switch (dst->format->BytesPerPixel) { case 1: for (; pixel <= pixellast; pixel += pixy) { memset(pixel, (Uint8) color, dx); } break; case 2: pixy -= (pixx * dx); for (; pixel <= pixellast; pixel += pixy) { for (x = 0; x < dx; x++) { *(Uint16 *) pixel = color; pixel += pixx; } } break; case 3: pixy -= (pixx * dx); for (; pixel <= pixellast; pixel += pixy) { for (x = 0; x < dx; x++) { if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { pixel[0] = (color >> 16) & 0xff; pixel[1] = (color >> 8) & 0xff; pixel[2] = color & 0xff; } else { pixel[0] = color & 0xff; pixel[1] = (color >> 8) & 0xff; pixel[2] = (color >> 16) & 0xff; } pixel += pixx; } } break; default: /* case 4 */ pixy -= (pixx * dx); for (; pixel <= pixellast; pixel += pixy) { for (x = 0; x < dx; x++) { *(Uint32 *) pixel = color; pixel += pixx; } } break; } /* * Unlock surface */ SDL_UnlockSurface(dst); result = 0; } else { result = filledRectAlpha(dst, x1, y1, x1 + w, y1 + h, color); } return (result);}int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ /* * Draw */ return (boxColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));}/* ----- Line *//* Non-alpha line drawing code adapted from routine *//* by Pete Shinners, pete@shinners.org *//* Originally from pygame, http://pygame.seul.org */#define ABS(a) (((a)<0) ? -(a) : (a))int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color){ int pixx, pixy; int x, y; int dx, dy; int ax, ay; int sx, sy; int swaptmp; Uint8 *pixel; Uint8 *colorptr; /* * Clip line and test if we have to draw */ if (!(clipLine(dst, &x1, &y1, &x2, &y2))) { return (0); } /* * Test for special cases of straight lines or single point */ if (x1 == x2) { if (y1 < y2) { return (vlineColor(dst, x1, y1, y2, color)); } else if (y1 > y2) { return (vlineColor(dst, x1, y2, y1, color)); } else { return (pixelColor(dst, x1, y1, color)); } } if (y1 == y2) { if (x1 < x2) { return (hlineColor(dst, x1, x2, y1, color)); } else if (x1 > x2) { return (hlineColor(dst, x2, x1, y1, color)); } } /* * Variable setup */ dx = x2 - x1; dy = y2 - y1; sx = (dx >= 0) ? 1 : -1; sy = (dy >= 0) ? 1 : -1; /* Lock surface */ if (SDL_MUSTLOCK(dst)) { if (SDL_LockSurface(dst) < 0) { return (-1); } } /* * Check for alpha blending */ if ((color & 255) == 255) { /* * No alpha blending - use fast pixel routines */ /* * Setup color */ colorptr = (Uint8 *) & color; if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]); } else { color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]); } /* * More variable setup */ dx = sx * dx + 1; dy = sy * dy + 1; pixx = dst->format->BytesPerPixel; pixy = dst->pitch; pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1; pixx *= sx; pixy *= sy; if (dx < dy) { swaptmp = dx; dx = dy; dy = swaptmp; swaptmp = pixx; pixx = pixy; pixy = swaptmp; } /* * Draw */ x = 0; y = 0; switch (dst->format->BytesPerPixel) { case 1: for (; x < dx; x++, pixel += pixx) { *pixel = color; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } } break; case 2: for (; x < dx; x++, pixel += pixx) { *(Uint16 *) pixel = color; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } } break; case 3: for (; x < dx; x++, pixel += pixx) { if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { pixel[0] = (color >> 16) & 0xff; pixel[1] = (color >> 8) & 0xff; pixel[2] = color & 0xff; } else { pixel[0] = color & 0xff; pixel[1] = (color >> 8) & 0xff; pixel[2] = (color >> 16) & 0xff; } y += dy; if (y >= dx) { y -= dx; pixel += pixy; } } break; default: /* case 4 */ for (; x < dx; x++, pixel += pixx) { *(Uint32 *) pixel = color; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } } break; } } else { /* * Alpha blending required - use single-pixel blits */ ax = ABS(dx) << 1; ay = ABS(dy) << 1; x = x1; y = y1; if (ax > ay) { int d = ay - (ax >> 1); while (x != x2) { pixelColorNolock (dst, x, y, color); if (d > 0 || (d == 0 && sx == 1)) { y += sy; d -= ax; } x += sx; d += ay; } } else { int d = ax - (ay >> 1); while (y != y2) { pixelColorNolock (dst, x, y, color); if (d > 0 || ((d == 0) && (sy == 1))) { x += sx; d -= ay; } y += sy; d += ax; } } pixelColorNolock (dst, x, y, color); } /* Unlock surface */ if (SDL_MUSTLOCK(dst)) { SDL_UnlockSurface(dst); } return (0);}int lineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ /* * Draw */ return (lineColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));}/* AA Line */#define AAlevels 256#define AAbits 8/* This implementation of the Wu antialiasing code is based on Mike Abrash'sDDJ article which was reprinted as Chapter 42 of his Graphics ProgrammingBlack Book, but has been optimized to work with SDL and utilizes 32-bitfixed-point arithmetic. (A. Schiffler).*/int aalineColorInt(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint){ Sint32 xx0, yy0, xx1, yy1; int result; Uint32 intshift, erracc, erradj; Uint32 erracctmp, wgt, wgtcompmask; int dx, dy, tmp, xdir, y0p1, x0pxdir; /* * Clip line and test if we have to draw */ if (!(clipLine(dst, &x1, &y1, &x2, &y2))) { return (0); } /* * Keep on working with 32bit numbers */ xx0 = x1; yy0 = y1; xx1 = x2; yy1 = y2; /* * Reorder points if required */ if (yy0 > yy1) { tmp = yy0; yy0 = yy1; yy1 = tmp; tmp = xx0; xx0 = xx1; xx1 = tmp; } /* * Calculate distance */ dx = xx1 - xx0; dy = yy1 - yy0; /* * Adjust for negative dx and set xdir */ if (dx >= 0) { xdir = 1; } else { xdir = -1; dx = (-dx); } /* * Check for special cases */ if (dx == 0) { /* * Vertical line */ return (vlineColor(dst, x1, y1, y2, color)); } else if (dy == 0) { /* * Horizontal line */ return (hlineColor(dst, x1, x2, y1, color)); } else if (dx == dy) { /* * Diagonal line */ return (lineColor(dst, x1, y1, x2, y2, color)); } /* * Line is not horizontal, vertical or diagonal */ result = 0; /* * Zero accumulator */ erracc = 0; /* * # of bits by which to shift erracc to get intensity level */ intshift = 32 - AAbits; /* * Mask used to flip all bits in an intensity weighting */ wgtcompmask = AAlevels - 1; /* Lock surface */ if (SDL_MUSTLOCK(dst)) { if (SDL_LockSurface(dst) < 0) { return (-1); } } /* * Draw the initial pixel in the foreground color */ result |= pixelColorNolock(dst, x1, y1, color); /* * x-major or y-major? */ if (dy > dx) { /* * y-major. Calculate 16-bit fixed point fractional part of a pixel that * X advances every time Y advances 1 pixel, truncating the result so that * we won't overrun the endpoint along the X axis */ /* * Not-so-portable version: erradj = ((Uint64)dx << 32) / (Uint64)dy; */ erradj = ((dx << 16) / dy) << 16; /* * draw all pixels other than the first and last */ x0pxdir = xx0 + xdir; while (--dy) { erracctmp = erracc; erracc += erradj; if (erracc <= erracctmp) { /* * rollover in error accumulator, x coord advances */ xx0 = x0pxdir; x0pxdir += xdir; } yy0++; /* y-major so always advance Y */ /* * the AAbits most significant bits of erracc give us the intensity * weighting for this pixel, and the complement of the weighting for * the paired pixel. */ wgt = (erracc >> intshift) & 255; result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt); result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt); } } else { /* * x-major line. Calculate 16-bit fixed-point fractional part of a pixel * that Y advances each time X advances 1 pixel, truncating the result so * that we won't overrun the endpoint along the X axis. */ /* * Not-so-portable version: erradj = ((Uint64)dy << 32) / (Uint64)dx; */ erradj = ((dy << 16) / dx) << 16; /* * draw all pixels other than the first and last */ y0p1 = yy0 + 1; while (--dx) { erracctmp = erracc; erracc += erradj; if (erracc <= erracctmp) { /* * Accumulator turned over, advance y */ yy0 = y0p1; y0p1++; } xx0 += xdir; /* x-major so always advance X */ /* * the AAbits most significant bits of erracc give us the intensity
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -