📄 sdl_gfxprimitives.c
字号:
int pixx, pixy; Sint16 w; Sint16 xtmp; int result = -1; /* * 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 of hline */ if ((x1<left) && (x2<left)) { return(0); } if ((x1>right) && (x2>right)) { return(0); } if ((y<top) || (y>bottom)) { return (0); } /* * Clip x */ if (x1 < left) { x1 = left; } if (x2 > right) { x2 = right; } /* * Swap x1, x2 if required */ if (x1 > x2) { xtmp = x1; x1 = x2; x2 = xtmp; } /* * Calculate width */ w = x2 - x1; /* * Sanity check on width */ if (w < 0) { return (0); } /* * Lock surface */ SDL_LockSurface(dst); /* * More variable setup */ dx = w; pixx = dst->format->BytesPerPixel; pixy = dst->pitch; pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y; /* * Draw */ switch (dst->format->BytesPerPixel) { case 1: memset(pixel, color, dx); break; case 2: pixellast = pixel + dx + dx; for (; pixel <= pixellast; pixel += pixx) { *(Uint16 *) pixel = color; } break; case 3: pixellast = pixel + dx + dx + dx; for (; pixel <= pixellast; 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; } } break; default: /* case 4 */ dx = dx + dx; pixellast = pixel + dx + dx; for (; pixel <= pixellast; pixel += pixx) { *(Uint32 *) pixel = color; } break; } /* * Unlock surface */ SDL_UnlockSurface(dst); /* * Set result code */ result = 0; return (result);}int hlineRGBAStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ /* * Draw */ return (hlineColorStore(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));}int hlineColor(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color){ Sint16 left, right, top, bottom; Uint8 *pixel, *pixellast; int dx; int pixx, pixy; Sint16 w; Sint16 xtmp; int result = -1; 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 of hline */ if ((x1<left) && (x2<left)) { return(0); } if ((x1>right) && (x2>right)) { return(0); } if ((y<top) || (y>bottom)) { return (0); } /* * Clip x */ if (x1 < left) { x1 = left; } if (x2 > right) { x2 = right; } /* * Swap x1, x2 if required */ if (x1 > x2) { xtmp = x1; x1 = x2; x2 = xtmp; } /* * Calculate width */ w = x2 - x1; /* * Sanity check on width */ if (w < 0) { return (0); } /* * 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; pixx = dst->format->BytesPerPixel; pixy = dst->pitch; pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y; /* * Draw */ switch (dst->format->BytesPerPixel) { case 1: memset(pixel, color, dx); break; case 2: pixellast = pixel + dx + dx; for (; pixel <= pixellast; pixel += pixx) { *(Uint16 *) pixel = color; } break; case 3: pixellast = pixel + dx + dx + dx; for (; pixel <= pixellast; 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; } } break; default: /* case 4 */ dx = dx + dx; pixellast = pixel + dx + dx; for (; pixel <= pixellast; pixel += pixx) { *(Uint32 *) pixel = color; } break; } /* * Unlock surface */ SDL_UnlockSurface(dst); /* * Set result code */ result = 0; } else { /* * Alpha blending blit */ result = HLineAlpha(dst, x1, x1 + w, y, color); } return (result);}int hlineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ /* * Draw */ return (hlineColor(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));}/* ----- Vertical line */int vlineColor(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color){ Sint16 left, right, top, bottom; Uint8 *pixel, *pixellast; int dy; int pixx, pixy; Sint16 h; Sint16 ytmp; int result = -1; 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 of vline */ if ((x<left) || (x>right)) { return (0); } if ((y1<top) && (y2<top)) { return(0); } if ((y1>bottom) && (y2>bottom)) { return(0); } /* * Clip y */ if (y1 < top) { y1 = top; } if (y2 > bottom) { y2 = bottom; } /* * Swap y1, y2 if required */ if (y1 > y2) { ytmp = y1; y1 = y2; y2 = ytmp; } /* * Calculate height */ h = y2 - y1; /* * Sanity check on height */ if (h < 0) { return (0); } /* * 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 */ dy = h; pixx = dst->format->BytesPerPixel; pixy = dst->pitch; pixel = ((Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1; pixellast = pixel + pixy * dy; /* * Draw */ switch (dst->format->BytesPerPixel) { case 1: for (; pixel <= pixellast; pixel += pixy) { *(Uint8 *) pixel = color; } break; case 2: for (; pixel <= pixellast; pixel += pixy) { *(Uint16 *) pixel = color; } break; case 3: for (; pixel <= pixellast; pixel += pixy) { 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; } } break; default: /* case 4 */ for (; pixel <= pixellast; pixel += pixy) { *(Uint32 *) pixel = color; } break; } /* * Unlock surface */ SDL_UnlockSurface(dst); /* * Set result code */ result = 0; } else { /* * Alpha blending blit */ result = VLineAlpha(dst, x, y1, y1 + h, color); } return (result);}int vlineRGBA(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ /* * Draw */ return (vlineColor(dst, x, y1, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));}/* ----- Rectangle */int rectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color){ int result; Sint16 w, h, xtmp, ytmp; /* * Swap x1, x2 if required */ if (x1 > x2) { xtmp = x1; x1 = x2; x2 = xtmp; } /* * Swap y1, y2 if required */ if (y1 > y2) { ytmp = y1; y1 = y2; y2 = ytmp; } /* * Calculate width&height */ w = x2 - x1; h = y2 - y1; /* * Sanity check */ if ((w < 0) || (h < 0)) { return (0); } /* * Test for special cases of straight lines or single point */ if (x1 == x2) { if (y1 == y2) { return (pixelColor(dst, x1, y1, color)); } else { return (vlineColor(dst, x1, y1, y2, color)); } } else { if (y1 == y2) { return (hlineColor(dst, x1, x2, y1, color)); } } /* * Draw rectangle */ result = 0; result |= hlineColor(dst, x1, x2, y1, color); result |= hlineColor(dst, x1, x2, y2, color); y1 += 1; y2 -= 1; if (y1<=y2) { result |= vlineColor(dst, x1, y1, y2, color); result |= vlineColor(dst, x2, y1, y2, color); } return (result);}int rectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ /* * Draw */ return (rectangleColor (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));}/* --------- Clipping routines for line *//* Clipping based heavily on code from *//* http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c */#define CLIP_LEFT_EDGE 0x1#define CLIP_RIGHT_EDGE 0x2#define CLIP_BOTTOM_EDGE 0x4#define CLIP_TOP_EDGE 0x8#define CLIP_INSIDE(a) (!a)#define CLIP_REJECT(a,b) (a&b)#define CLIP_ACCEPT(a,b) (!(a|b))static int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom){ int code = 0; if (x < left) { code |= CLIP_LEFT_EDGE; } else if (x > right) { code |= CLIP_RIGHT_EDGE; } if (y < top) { code |= CLIP_TOP_EDGE; } else if (y > bottom) { code |= CLIP_BOTTOM_EDGE; } return code;}static int clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2){ Sint16 left, right, top, bottom; int code1, code2; int draw = 0; Sint16 swaptmp; float m; /* * 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; while (1) { code1 = clipEncode(*x1, *y1, left, top, right, bottom); code2 = clipEncode(*x2, *y2, left, top, right, bottom); if (CLIP_ACCEPT(code1, code2)) { draw = 1; break; } else if (CLIP_REJECT(code1, code2)) break; else { if (CLIP_INSIDE(code1)) { swaptmp = *x2; *x2 = *x1; *x1 = swaptmp; swaptmp = *y2; *y2 = *y1; *y1 = swaptmp; swaptmp = code2; code2 = code1; code1 = swaptmp; } if (*x2 != *x1) { m = (*y2 - *y1) / (float) (*x2 - *x1); } else { m = 1.0f; } if (code1 & CLIP_LEFT_EDGE) { *y1 += (Sint16) ((left - *x1) * m); *x1 = left; } else if (code1 & CLIP_RIGHT_EDGE) { *y1 += (Sint16) ((right - *x1) * m); *x1 = right; } else if (code1 & CLIP_BOTTOM_EDGE) { if (*x2 != *x1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -