📄 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_gfxPrimitives.h"#include "SDL_gfxPrimitives_font.h"/* -===================- *//* ----- 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 fastPixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color){ int bpp; Uint8 *p; /* * 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 */ } return (0);}/* ----- Pixel - fast, no blending, no locking, no clipping *//* (faster but dangerous, make sure we stay in surface bounds) */int fastPixelColorNolockNoclip(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color){ int bpp; Uint8 *p; /* * 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 */ return (0);}/* ----- Pixel - fast, no blending, locking, clipping */int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color){ int result; /* * Lock the surface */ if (SDL_MUSTLOCK(dst)) { if (SDL_LockSurface(dst) < 0) { return (-1); } } result = fastPixelColorNolock(dst, x, y, color); /* * Unlock surface */ if (SDL_MUSTLOCK(dst)) { SDL_UnlockSurface(dst); } return (result);}/* ----- Pixel - fast, no blending, locking, RGB input */int fastPixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ Uint32 color; /* * Setup color */ color = SDL_MapRGBA(dst->format, r, g, b, a); /* * Draw */ return (fastPixelColor(dst, x, y, color));}/* ----- Pixel - fast, no blending, no locking RGB input */int fastPixelRGBANolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ Uint32 color; /* * Setup color */ color = SDL_MapRGBA(dst->format, r, g, b, a); /* * Draw */ return (fastPixelColorNolock(dst, x, y, color));}/* PutPixel routine with alpha blending, input color in destination format *//* New, faster routine - default blending pixel */int _putPixelAlpha(SDL_Surface * surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha){ Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask; Uint32 R, G, B, A = 0; if (x >= clip_xmin(surface) && x <= clip_xmax(surface) && y >= clip_ymin(surface) && y <= clip_ymax(surface)) { switch (surface->format->BytesPerPixel) { case 1:{ /* Assuming 8-bpp */ if (alpha == 255) { *((Uint8 *) surface->pixels + y * surface->pitch + x) = color; } else { Uint8 *pixel = (Uint8 *) surface->pixels + y * surface->pitch + x; Uint8 dR = surface->format->palette->colors[*pixel].r; Uint8 dG = surface->format->palette->colors[*pixel].g; Uint8 dB = surface->format->palette->colors[*pixel].b; Uint8 sR = surface->format->palette->colors[color].r; Uint8 sG = surface->format->palette->colors[color].g; Uint8 sB = surface->format->palette->colors[color].b; dR = dR + ((sR - dR) * alpha >> 8); dG = dG + ((sG - dG) * alpha >> 8); dB = dB + ((sB - dB) * alpha >> 8); *pixel = SDL_MapRGB(surface->format, dR, dG, dB); } } break; case 2:{ /* Probably 15-bpp or 16-bpp */ if (alpha == 255) { *((Uint16 *) surface->pixels + y * surface->pitch / 2 + x) = color; } else { Uint16 *pixel = (Uint16 *) surface->pixels + y * surface->pitch / 2 + x; Uint32 dc = *pixel; R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask; G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask; B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask; if (Amask) A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask; *pixel = R | G | B | A; } } break; case 3:{ /* Slow 24-bpp mode, usually not used */ Uint8 *pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3; Uint8 rshift8 = surface->format->Rshift / 8; Uint8 gshift8 = surface->format->Gshift / 8; Uint8 bshift8 = surface->format->Bshift / 8; Uint8 ashift8 = surface->format->Ashift / 8; if (alpha == 255) { *(pix + rshift8) = color >> surface->format->Rshift; *(pix + gshift8) = color >> surface->format->Gshift; *(pix + bshift8) = color >> surface->format->Bshift; *(pix + ashift8) = color >> surface->format->Ashift; } else { Uint8 dR, dG, dB, dA = 0; Uint8 sR, sG, sB, sA = 0; pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3; dR = *((pix) + rshift8); dG = *((pix) + gshift8); dB = *((pix) + bshift8); dA = *((pix) + ashift8); sR = (color >> surface->format->Rshift) & 0xff; sG = (color >> surface->format->Gshift) & 0xff; sB = (color >> surface->format->Bshift) & 0xff; sA = (color >> surface->format->Ashift) & 0xff; dR = dR + ((sR - dR) * alpha >> 8); dG = dG + ((sG - dG) * alpha >> 8); dB = dB + ((sB - dB) * alpha >> 8); dA = dA + ((sA - dA) * alpha >> 8); *((pix) + rshift8) = dR; *((pix) + gshift8) = dG; *((pix) + bshift8) = dB; *((pix) + ashift8) = dA; } } break; case 4:{ /* Probably 32-bpp */ if (alpha == 255) { *((Uint32 *) surface->pixels + y * surface->pitch / 4 + x) = color; } else { Uint32 *pixel = (Uint32 *) surface->pixels + y * surface->pitch / 4 + x; Uint32 dc = *pixel; R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask; G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask; B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask; if (Amask) A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask; *pixel = R | G | B | A; } } break; } } return (0);}/* ----- Pixel - pixel draw with blending enabled if a<255 */int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color){ Uint8 alpha; Uint32 mcolor; int result = 0; /* * Lock the surface */ if (SDL_MUSTLOCK(dst)) { if (SDL_LockSurface(dst) < 0) { return (-1); } } /* * Setup color */ alpha = color & 0x000000ff; mcolor = SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24, (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha); /* * Draw */ result = _putPixelAlpha(dst, x, y, mcolor, alpha); /* * Unlock the surface */ if (SDL_MUSTLOCK(dst)) { SDL_UnlockSurface(dst); } return (result);}int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color){ Uint8 alpha; Uint32 mcolor; int result = 0; /* * Setup color */ alpha = color & 0x000000ff; mcolor = SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24, (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha); /* * Draw */ result = _putPixelAlpha(dst, x, y, mcolor, alpha); return (result);}/* Filled rectangle with alpha blending, color in destination format */int _filledRectAlpha(SDL_Surface * surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha){ Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask; Uint32 R, G, B, A = 0; Sint16 x, y; switch (surface->format->BytesPerPixel) { case 1:{ /* Assuming 8-bpp */ Uint8 *row, *pixel; Uint8 dR, dG, dB; Uint8 sR = surface->format->palette->colors[color].r; Uint8 sG = surface->format->palette->colors[color].g; Uint8 sB = surface->format->palette->colors[color].b; for (y = y1; y <= y2; y++) { row = (Uint8 *) surface->pixels + y * surface->pitch; for (x = x1; x <= x2; x++) { pixel = row + x; dR = surface->format->palette->colors[*pixel].r; dG = surface->format->palette->colors[*pixel].g; dB = surface->format->palette->colors[*pixel].b; dR = dR + ((sR - dR) * alpha >> 8); dG = dG + ((sG - dG) * alpha >> 8); dB = dB + ((sB - dB) * alpha >> 8); *pixel = SDL_MapRGB(surface->format, dR, dG, dB); } } } break; case 2:{ /* Probably 15-bpp or 16-bpp */ Uint16 *row, *pixel; Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask); for (y = y1; y <= y2; y++) { row = (Uint16 *) surface->pixels + y * surface->pitch / 2; for (x = x1; x <= x2; x++) { pixel = row + x; R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask; G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask; B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask; if (Amask) A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask; *pixel = R | G | B | A; } } } break; case 3:{ /* Slow 24-bpp mode, usually not used */ Uint8 *row, *pix; Uint8 dR, dG, dB, dA; Uint8 rshift8 = surface->format->Rshift / 8; Uint8 gshift8 = surface->format->Gshift / 8; Uint8 bshift8 = surface->format->Bshift / 8; Uint8 ashift8 = surface->format->Ashift / 8; Uint8 sR = (color >> surface->format->Rshift) & 0xff; Uint8 sG = (color >> surface->format->Gshift) & 0xff; Uint8 sB = (color >> surface->format->Bshift) & 0xff; Uint8 sA = (color >> surface->format->Ashift) & 0xff; for (y = y1; y <= y2; y++) { row = (Uint8 *) surface->pixels + y * surface->pitch; for (x = x1; x <= x2; x++) { pix = row + x * 3; dR = *((pix) + rshift8); dG = *((pix) + gshift8); dB = *((pix) + bshift8); dA = *((pix) + ashift8); dR = dR + ((sR - dR) * alpha >> 8); dG = dG + ((sG - dG) * alpha >> 8); dB = dB + ((sB - dB) * alpha >> 8); dA = dA + ((sA - dA) * alpha >> 8); *((pix) + rshift8) = dR; *((pix) + gshift8) = dG; *((pix) + bshift8) = dB; *((pix) + ashift8) = dA; } } } break; case 4:{ /* Probably 32-bpp */ Uint32 *row, *pixel; Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask); for (y = y1; y <= y2; y++) { row = (Uint32 *) surface->pixels + y * surface->pitch / 4; for (x = x1; x <= x2; x++) { pixel = row + x; R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask; G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask; B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask; if (Amask) A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask; *pixel = R | G | B | A; } } } break; } return (0);}/* Draw rectangle with alpha enabled from RGBA color. */int filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color){ Uint8 alpha; Uint32 mcolor; int result = 0; /* * Lock the surface */ if (SDL_MUSTLOCK(dst)) { if (SDL_LockSurface(dst) < 0) { return (-1); } } /* * Setup color */ alpha = color & 0x000000ff; mcolor = SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24, (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha); /* * Draw */ result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha); /* * Unlock the surface */ if (SDL_MUSTLOCK(dst)) { SDL_UnlockSurface(dst); } return (result);}/* Draw horizontal line with alpha enabled from RGBA color */int HLineAlpha(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color){ return (filledRectAlpha(dst, x1, y, x2, y, color));}/* Draw vertical line with alpha enabled from RGBA color */int VLineAlpha(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color){ return (filledRectAlpha(dst, x, y1, x, y2, color));}/* Pixel - using alpha weight on color for AA-drawing */int pixelColorWeight(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight){ Uint32 a; /* * Get alpha */ a = (color & (Uint32) 0x000000ff); /* * Modify Alpha by weight */ a = ((a * weight) >> 8); return (pixelColor(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));}/* Pixel - using alpha weight on color for AA-drawing - no locking */int pixelColorWeightNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight){ Uint32 a; /* * Get alpha */ a = (color & (Uint32) 0x000000ff); /* * Modify Alpha by weight */ a = ((a * weight) >> 8); return (pixelColorNolock(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));}int pixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ Uint32 color; /* * Check Alpha */ if (a == 255) { /* * No alpha blending required */ /* * Setup color */ color = SDL_MapRGBA(dst->format, r, g, b, a); /* * Draw */ return (fastPixelColor(dst, x, y, color)); } else { /* * Alpha blending required */ /* * Draw */ return (pixelColor(dst, x, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a)); }}/* ----- Horizontal line *//* Just store color including alpha, no blending */int hlineColorStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color){ Sint16 left, right, top, bottom; Uint8 *pixel, *pixellast; int dx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -