📄 surface.c
字号:
sr.y = srcy; sr.w = dstrect->w = w; sr.h = dstrect->h = h; return GAL_LowerBlit(src, &sr, dst, dstrect); } dstrect->w = dstrect->h = 0; return 0;}/* * This function performs a fast fill of the given rectangle with 'color' */int GAL_FillRect(GAL_Surface *dst, const GAL_Rect *dstrect, Uint32 color){ GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video; int x, y; Uint8 *row; GAL_Rect my_dstrect; /* If 'dstrect' == NULL, then fill the whole surface */ if ( dstrect ) { /* Perform clipping */ if ( !GAL_IntersectRect(dstrect, &dst->clip_rect, &my_dstrect) ) { return(0); } } else { my_dstrect = dst->clip_rect; } /* Check for hardware acceleration */ if ( ((dst->flags & GAL_HWSURFACE) == GAL_HWSURFACE) && video->info.blit_fill ) { return(video->FillHWRect(this, dst, &my_dstrect, color)); }#if 0 /* Perform software fill */ if ( GAL_LockSurface(dst) != 0 ) { return(-1); }#endif row = (Uint8 *)dst->pixels+my_dstrect.y*dst->pitch+ my_dstrect.x*dst->format->BytesPerPixel; if ( dst->format->palette || (color == 0) ) { x = my_dstrect.w*dst->format->BytesPerPixel; if ( !color && !((long)row&3) && !(x&3) && !(dst->pitch&3) ) { int n = x >> 2; for ( y=my_dstrect.h; y; --y ) { GAL_memset4(row, 0, n); row += dst->pitch; } } else {#if 0 /* * memset() on PPC (both glibc and codewarrior) uses * the dcbz (Data Cache Block Zero) instruction, which * causes an alignment exception if the destination is * uncachable, so only use it on software surfaces */ if((dst->flags & GAL_HWSURFACE) == GAL_HWSURFACE) { if(my_dstrect.w >= 8) { /* * 64-bit stores are probably most * efficient to uncached video memory */ double fill; memset(&fill, color, (sizeof fill)); for(y = my_dstrect.h; y; y--) { Uint8 *d = row; unsigned n = x; unsigned nn; Uint8 c = color; double f = fill; while((unsigned long)d & (sizeof(double) - 1)) { *d++ = c; n--; } nn = n / (sizeof(double) * 4); while(nn) { ((double *)d)[0] = f; ((double *)d)[1] = f; ((double *)d)[2] = f; ((double *)d)[3] = f; d += 4*sizeof(double); nn--; } n &= ~(sizeof(double) * 4 - 1); nn = n / sizeof(double); while(nn) { *(double *)d = f; d += sizeof(double); nn--; } n &= ~(sizeof(double) - 1); while(n) { *d++ = c; n--; } row += dst->pitch; } } else { /* narrow boxes */ for(y = my_dstrect.h; y; y--) { Uint8 *d = row; Uint8 c = color; int n = x; while(n) { *d++ = c; n--; } row += dst->pitch; } } } else#endif /* __powerpc__ */ { for(y = my_dstrect.h; y; y--) { memset(row, color, x); row += dst->pitch; } } } } else { switch (dst->format->BytesPerPixel) { case 2: for ( y=my_dstrect.h; y; --y ) { Uint16 *pixels = (Uint16 *)row; Uint16 c = color; Uint32 cc = (Uint32)c << 16 | c; int n = my_dstrect.w; if((unsigned long)pixels & 3) { *pixels++ = c; n--; } if(n >> 1) GAL_memset4(pixels, cc, n >> 1); if(n & 1) pixels[n - 1] = c; row += dst->pitch; } break; case 3: if(GAL_BYTEORDER == GAL_BIG_ENDIAN) color <<= 8; for ( y=my_dstrect.h; y; --y ) { Uint8 *pixels = row; for ( x=my_dstrect.w; x; --x ) { memcpy(pixels, &color, 3); pixels += 3; } row += dst->pitch; } break; case 4: for(y = my_dstrect.h; y; --y) { GAL_memset4(row, color, my_dstrect.w); row += dst->pitch; } break; } }#if 0 GAL_UnlockSurface(dst);#endif /* We're done! */ return(0);}/* * Calculate the pad-aligned box sizew in a surface */Uint32 GAL_GetBoxSize (GAL_Surface *surface, Uint32 w, Uint32 h, Uint32* pitch_p){ Uint32 pitch; /* Box should be 4-byte aligned for speed */ pitch = w * surface->format->BytesPerPixel; switch (surface->format->BitsPerPixel) { case 1: pitch = (pitch+7)/8; break; case 4: pitch = (pitch+1)/2; break; default: break; } pitch = (pitch + 3) & ~3; /* 4-byte aligning */ if (pitch_p) *pitch_p = pitch; return pitch * h;}/* * This function performs a fast HW -> SW box copying. */int GAL_GetBox (GAL_Surface *src, const GAL_Rect *rect, BITMAP* box){ Sint32 dst_x, dst_y, off_x, off_y, y; Uint8 *srcrow, *dstrow; Uint32 linelen; GAL_Rect srcrect = {0, 0, src->w, src->h}; if (rect->h <= 0 || rect->w <= 0) return -1; box->bmType = BMP_TYPE_NORMAL; box->bmBitsPerPixel = src->format->BitsPerPixel; box->bmBytesPerPixel = src->format->BytesPerPixel; box->bmWidth = rect->w; box->bmHeight = rect->h; box->bmAlphaPixelFormat = NULL; dst_x = rect->x; dst_y = rect->y; /* Perform clipping */ if (!GAL_IntersectRect (rect, &srcrect, &srcrect)) { return 0; } off_x = srcrect.x - dst_x; off_y = srcrect.y - dst_y; if ((box->bmPitch == 0) || (box->bmBits == NULL)) { box->bmBits = malloc (GAL_GetBoxSize (src, box->bmWidth, box->bmHeight, &box->bmPitch)); if (box->bmBits == NULL) { GAL_OutOfMemory (); return -1; } } linelen = srcrect.w * box->bmBytesPerPixel; srcrow = (Uint8 *)src->pixels + srcrect.y * src->pitch + srcrect.x * src->format->BytesPerPixel; dstrow = box->bmBits + off_y * box->bmPitch + off_x * box->bmBytesPerPixel;#if 0 /* Perform software box copying */ if ( GAL_LockSurface (src) != 0 ) { return(-1); }#endif switch (box->bmBytesPerPixel) { case 1: if (((DWORD)srcrow & 3) || ((DWORD)dstrow & 3) || (linelen & 3) || (box->bmPitch & 3) || (src->pitch & 3)) goto slow_copy; else { int n = linelen >> 2; for (y = srcrect.h; y; --y) { GAL_memcpy4 (dstrow, srcrow, n); srcrow += src->pitch; dstrow += box->bmPitch; } } break; case 2: if ((((DWORD)srcrow & 3) != ((DWORD)dstrow & 3)) || (box->bmPitch & 3) || (src->pitch & 3)) goto slow_copy; for (y = srcrect.h; y; --y) { Uint16 *dstpixels = (Uint16 *)dstrow; Uint16 *srcpixels = (Uint16 *)srcrow; int n = srcrect.w; if ((DWORD)dstpixels & 3) { *dstpixels = *srcpixels; dstpixels++; srcpixels++; n--; } if (n >> 1) GAL_memcpy4 (dstpixels, srcpixels, n >> 1); if (n & 1) dstpixels [n - 1] = srcpixels [n - 1]; srcrow += src->pitch; dstrow += box->bmPitch; } break; case 3: goto slow_copy; case 4: for (y = srcrect.h; y; --y) { GAL_memcpy4 (dstrow, srcrow, srcrect.w); srcrow += src->pitch; dstrow += box->bmPitch; } break; }#if 0 GAL_UnlockSurface (src);#endif return(0);slow_copy: for (y = srcrect.h; y; --y) { GAL_memcpy (dstrow, srcrow, linelen); srcrow += src->pitch; dstrow += box->bmPitch; }#if 0 GAL_UnlockSurface (src);#endif return(0);}/* * This function performs a fast SW -> HW box copying. */// helpers#include "blit.h"static int _PutBoxAlpha (GAL_Surface* dst, BYTE* dstrow, BYTE* srcrow, Uint32 w, Uint32 h, BITMAP* box){ BYTE* dstpixels = dstrow; BYTE* srcpixels = srcrow; GAL_PixelFormat *dstfmt = dst->format; GAL_PixelFormat *srcfmt = box->bmAlphaPixelFormat; int bpp = dstfmt->BytesPerPixel; unsigned alpha = dstfmt->Amask ? GAL_ALPHA_OPAQUE : 0; if (bpp == 1) return -1; while ( h-- ) { dstpixels = dstrow; srcpixels = srcrow; DUFFS_LOOP( { Uint32 pixel; unsigned sR; unsigned sG; unsigned sB; unsigned sA; unsigned dR; unsigned dG; unsigned dB; DISEMBLE_RGBA (srcpixels, bpp, srcfmt, pixel, sR, sG, sB, sA); DISEMBLE_RGB (dstpixels, bpp, dstfmt, pixel, dR, dG, dB); ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB); ASSEMBLE_RGBA (dstpixels, bpp, dstfmt, dR, dG, dB, alpha); dstpixels += bpp; srcpixels += bpp; }, w); srcrow += box->bmPitch; dstrow += dst->pitch; } return 0;}static int _PutBoxAlphaChannel (GAL_Surface* dst, BYTE* dstrow, BYTE* srcrow, Uint32 w, Uint32 h, BITMAP* box){ BYTE* dstpixels = dstrow; BYTE* srcpixels = srcrow; GAL_PixelFormat *dstfmt = dst->format; int bpp = dstfmt->BytesPerPixel; unsigned alpha = box->bmAlpha; if (bpp == 1) return -1; while ( h-- ) { dstpixels = dstrow; srcpixels = srcrow; DUFFS_LOOP( { Uint32 pixel; unsigned sR; unsigned sG; unsigned sB; unsigned dR; unsigned dG; unsigned dB; DISEMBLE_RGB (srcpixels, bpp, dstfmt, pixel, sR, sG, sB); DISEMBLE_RGB (dstpixels, bpp, dstfmt, pixel, dR, dG, dB); ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB); ASSEMBLE_RGBA (dstpixels, bpp, dstfmt, dR, dG, dB, alpha); dstpixels += bpp; srcpixels += bpp; }, w); srcrow += box->bmPitch; dstrow += dst->pitch; } return 0;}static int _PutBoxKeyAlpha (GAL_Surface* dst, BYTE* dstrow, BYTE* srcrow, Uint32 w, Uint32 h, BITMAP* box){ BYTE* dstpixels = dstrow; BYTE* srcpixels = srcrow; Uint32 ckey = box->bmColorKey; GAL_PixelFormat *dstfmt = dst->format; GAL_PixelFormat *srcfmt = box->bmAlphaPixelFormat; int bpp = dstfmt->BytesPerPixel; Uint32 rgbmask = ~srcfmt->Amask; unsigned alpha = dstfmt->Amask ? GAL_ALPHA_OPAQUE : 0; if (bpp == 1) return -1; while ( h-- ) { dstpixels = dstrow; srcpixels = srcrow; DUFFS_LOOP( { Uint32 pixel; unsigned sR; unsigned sG; unsigned sB; unsigned sA; unsigned dR; unsigned dG; unsigned dB; RETRIEVE_RGB_PIXEL (srcpixels, bpp, pixel); if ((pixel & rgbmask) != ckey ) { RGBA_FROM_PIXEL (pixel, srcfmt, sR, sG, sB, sA); DISEMBLE_RGB (dstpixels, bpp, dstfmt, pixel, dR, dG, dB); ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB); ASSEMBLE_RGBA (dstpixels, bpp, dstfmt, dR, dG, dB, alpha); } dstpixels += bpp; srcpixels += bpp; }, w); srcrow += box->bmPitch; dstrow += dst->pitch; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -