📄 sdl_gfxprimitives.c
字号:
/* SDL_gfxPrimitives - Graphics primitives for SDL surfaces LGPL (c) A. Schiffler*/#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <SDL.h>#include "SDL_gfxPrimitives.h"/* -===================- *//* Define this flag to use surface blits for alpha blended drawing. *//* This is usually slower that direct surface calculations. */#undef SURFACE_ALPHA_PIXEL/* ----- Defines for pixel clipping tests */#define clip_xmin(surface) surface->clip_rect.x#define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1#define clip_ymin(surface) surface->clip_rect.y#define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1/* ----- Pixel - fast, no blending, no locking, clipping */int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color){ int bpp; Uint8 *p; if (SDL_MUSTLOCK(dst)) { if (SDL_LockSurface(dst) < 0) { return (-1); } } /* * Honor clipping setup at pixel level */ if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) { /* * Get destination format */ bpp = dst->format->BytesPerPixel; p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp; switch (bpp) { case 1: *p = color; break; case 2: *(Uint16 *) p = color; break; case 3: if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { p[0] = (color >> 16) & 0xff; p[1] = (color >> 8) & 0xff; p[2] = color & 0xff; } else { p[0] = color & 0xff; p[1] = (color >> 8) & 0xff; p[2] = (color >> 16) & 0xff; } break; case 4: *(Uint32 *) p = color; break; } /* switch */ } if (SDL_MUSTLOCK(dst)) { SDL_UnlockSurface(dst); } return (0);}/* --------- Clipping routines for box/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) { *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;}/* ----- 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 sx, sy; int swaptmp; Uint8 *pixel; /* * Clip line and test if we have to draw */ if (!(clipLine(dst, &x1, &y1, &x2, &y2))) { return (0); } /* * 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 */ { /* * 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; } } /* Unlock surface */ if (SDL_MUSTLOCK(dst)) { SDL_UnlockSurface(dst); } return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -