//剪切(以得到原图的局部) void Sprite::Clip( int x, int y, int wid, int hei ) { if( m_spr == NULL ) { return; } SDL_Rect rect; rect.x = x; rect.y = y; rect.w = wid; rect.h = hei; Uint32 rmask = m_spr->format->Rmask; Uint32 gmask = m_spr->format->Gmask; Uint32 bmask = m_spr->format->Bmask; Uint32 amask = m_spr->format->Amask; int depth = m_spr->format->BitsPerPixel; if( depth < 24 ) { depth = 24; } //创建新表面 SDL_Surface* newFace; newFace = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_SRCALPHA, wid, hei, depth, rmask, gmask, bmask, amask ); //指定区域复制到新表面 if( m_spr->format->BytesPerPixel == 4 ) //有透明色的 { SDL_gfxBlitRGBA( m_spr, &rect, newFace, NULL ); } else //无透明色的 { SDL_BlitSurface( m_spr, &rect, newFace, NULL ); } //删除旧表面 SDL_FreeSurface( m_spr ); m_spr = newFace; }
//#verify #verify #verify !!!!!!!!!! void graphics_text_draw(GContext *ctx, const char *text, const GFont font, const GRect box, const GTextOverflowMode overflow_mode, const GTextAlignment alignment, const GTextLayoutCacheRef layout) { char buffer [256]; //SHIT!! I need to mark the end of the string but I can't use the original parameter... TextWrapper textWrapper=(overflow_mode==GTextOverflowModeWordWrap?wrap_words:wrap_points); int lineHeight=0,usedHeight=0; SDL_Surface* lineSurface,*lineSurfaceTemp; SDL_Surface* textSurface=SDL_CreateRGBSurface (SDL_SWSURFACE|SDL_SRCALPHA,box.size.w,box.size.h,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff); SDL_FillRect (textSurface,0,0); SDL_Surface* pointsSurface=0; //this will only be initalised when it's needed SDL_Rect dstRect,srcRect; SDL_Color color=getColor(ctx->text_color); GPoint topOffset=getTopOffset (); _WrapResult wrap; if (text==0) return; while (*text!=0&&usedHeight<box.size.h) { wrap=textWrapper (text,box.size.w,font); memcpy(buffer,text,wrap.lineLen); buffer[wrap.lineLen]=0; text=wrap.newString; if (wrap.lineLen==0) { usedHeight+=lineHeight; continue; } lineSurfaceTemp=TTF_RenderText_Solid ((TTF_Font*)font,buffer,color); if (lineSurfaceTemp==0) { printf("[WARN] TTF_RenderText_Solid: %s\n",TTF_GetError ()); return; } lineSurface=SDL_ConvertSurface(lineSurfaceTemp,textSurface->format,SDL_SWSURFACE|SDL_SRCALPHA); SDL_FreeSurface(lineSurfaceTemp); if (lineHeight==0) lineHeight=lineSurface->h; //prepare blitting srcRect=((SDL_Rect) { 0,0,lineSurface->w,lineSurface->h }); if (srcRect.h+usedHeight>box.size.h) srcRect.h=box.size.h-usedHeight; dstRect=srcRect; dstRect.y=usedHeight; //set text alignment if (alignment==GTextAlignmentCenter) dstRect.x=box.size.w/2-(dstRect.w+wrap.addPoints)/2; else if (alignment==GTextAlignmentRight) dstRect.x=box.size.w-(dstRect.w+wrap.addPoints); //else // srcRect.x=0; //blit line to text SDL_gfxBlitRGBA(lineSurface,&srcRect,textSurface,&dstRect); SDL_FreeSurface(lineSurface); if (wrap.addPoints>0) { if (pointsSurface==0) { pointsSurface=TTF_RenderText_Solid ((TTF_Font*)font,"...",color); if (pointsSurface==0) { printf("[WARN] TTF_RenderText_Solid: %s\n",TTF_GetError ()); return; } } srcRect.x=0; srcRect.w=pointsSurface->w; dstRect.x+=dstRect.w; dstRect.w=pointsSurface->w; SDL_BlitSurface(pointsSurface,&srcRect,textSurface,&dstRect); } usedHeight+=lineHeight; } srcRect=((SDL_Rect) { 0,0,box.size.w,box.size.h }); dstRect=((SDL_Rect) { box.origin.x+topOffset.x,box.origin.y+topOffset.y,box.size.w,box.size.h }); SDL_gfxBlitRGBA(textSurface,&srcRect,getTopScreen(),&dstRect); SDL_FreeSurface(textSurface); if (pointsSurface!=0) SDL_FreeSurface(pointsSurface); }
void Draw(SDL_Surface *screen) { int rate,x,y,s; SDL_Rect dest,clip; SDL_Surface *texture_image; SDL_Surface *texture_target1; SDL_Surface *texture_target2; FPSmanager fpsm; Uint32 rmask, gmask, bmask, amask; int width_half = screen->w/2; int height_half = screen->h/2; Uint32 text_color = 0xffffffff; /* Define masks for 32bit surface */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif /* Create semi-transparent textured surface */ s=64; texture_image = SDL_DisplayFormatAlpha(SDL_CreateRGBSurface(SDL_SWSURFACE, s, s, 32, rmask, gmask, bmask, amask)); /* Add some color */ boxRGBA(texture_image, 0, 0, s/2, s/2, 255, 0, 0, 255); boxRGBA(texture_image, s/2, 0, s, s/2, 0, 255, 0, 255); boxRGBA(texture_image, 0, s/2, s/2, s, 0, 0, 255, 255); boxRGBA(texture_image, s/2, s/2, s, s, 255, 255, 255, 255); /* Make 75%-transparent */ SDL_gfxSetAlpha(texture_image, 96); /* Set alpha channel use to per-pixel blending */ SDL_SetAlpha(texture_image, SDL_SRCALPHA, 255); /* Create an all transparent surface */ texture_target1 = SDL_DisplayFormatAlpha(SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 256, 32, rmask, gmask, bmask, amask)); /* Make 75%-transparent */ SDL_gfxSetAlpha(texture_target1, 64); /* Set alpha channel use to per-pixel blending */ SDL_SetAlpha(texture_target1, SDL_SRCALPHA, 255); /* Create an all transparent surface (2) */ texture_target2 = SDL_DisplayFormatAlpha(SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 256, 32, rmask, gmask, bmask, amask)); /* Make 75%-transparent */ SDL_gfxSetAlpha(texture_target2, 64); /* Set alpha channel use to per-pixel blending */ SDL_SetAlpha(texture_target2, SDL_SRCALPHA, 255); /* Define clipping region for left box */ clip.x = width_half-256-10 ; clip.y = height_half-256/2 ; clip.w = 256; clip.h = 256; /* Initialize Framerate manager */ SDL_initFramerate(&fpsm); /* Set/switch framerate */ rate=5; SDL_setFramerate(&fpsm,rate); /* --- Drawing loop */ while (1) { /* Event handler */ HandleEvent(); /* Black screen */ ClearScreen(screen); /* Random position of new texture */ x=(rand() % (256+2*s))-s; y=(rand() % (256+2*s))-s; /* Same for comparison texture */ dest.x = x; dest.y = y; dest.w = texture_image->w; dest.h = texture_image->h; SDL_BlitSurface(texture_image, NULL, texture_target1, &dest); /* Blit image into the target using custom Blit function. */ dest.x = x; dest.y = y; dest.w = texture_image->w; dest.h = texture_image->h; SDL_gfxBlitRGBA(texture_image, NULL, texture_target2, &dest); /* Draw comparison target on screen (left) */ dest.x = width_half-256-10; dest.y = height_half-256/2; dest.w = 256; dest.h = 256; SDL_BlitSurface(texture_target1, NULL, screen, &dest); /* Draw combiner target on screen (right) */ dest.x = width_half+10; dest.y = height_half-256/2; dest.w = 256; dest.h = 256; SDL_BlitSurface(texture_target2, NULL, screen, &dest); /* Draw some frames with titles */ rectangleColor(screen, width_half-256-10-1, height_half-256/2-1, width_half-256-10-1+257, height_half-256/2-1+257, text_color); rectangleColor(screen, width_half+10-1, height_half-256/2-1, width_half+10-1+257, height_half-256/2-1+257, text_color); stringColor(screen, width_half-256-10-1, height_half-256/2-1-36, " SDL Standard Blitter ", text_color); stringColor(screen, width_half-256-10-1, height_half-256/2-1-24, "Image --sdlBlit--> Target1", text_color); stringColor(screen, width_half-256-10-1, height_half-256/2-1-12, "Target1 --sdlBlit--> Screen", text_color); stringColor(screen, width_half+10-1, height_half-256/2-1-36, " SDL_gfx Compositing Blitter", text_color); stringColor(screen, width_half+10-1, height_half-256/2-1-24, "Image --gfxBlit--> Target2", text_color); stringColor(screen, width_half+10-1, height_half-256/2-1-12, "Target2 --sdlBlit--> Screen", text_color); stringColor(screen, width_half-256-10-1, height_half-256/2-1-60, "gfxBlitRGBA Demo: Target1/2 A=64 (25%), Image A=96 (37%)", text_color); /* Display by flipping screens */ SDL_Flip(screen); /* Delay to fix rate */ SDL_framerateDelay(&fpsm); } }