Clip text surface to texture bounds on fast upload
This commit is contained in:
		
							parent
							
								
									19c30e3ddd
								
							
						
					
					
						commit
						751b9c3ae5
					
				
					 1 changed files with 54 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -819,18 +819,65 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 | 
			
		|||
	Vec2i gpTexSize;
 | 
			
		||||
	gState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize);
 | 
			
		||||
 | 
			
		||||
	IntRect drawnRect = posRect;
 | 
			
		||||
 | 
			
		||||
	bool fastBlit = !p->touchesTaintedArea(drawnRect) && txtAlpha == 1.0;
 | 
			
		||||
	bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0;
 | 
			
		||||
 | 
			
		||||
	if (fastBlit)
 | 
			
		||||
	{
 | 
			
		||||
		if (squeeze == 1.0)
 | 
			
		||||
		{
 | 
			
		||||
			/* Even faster: upload directly to bitmap texture */
 | 
			
		||||
			/* Even faster: upload directly to bitmap texture.
 | 
			
		||||
			 * We have to make sure the posRect lies within the texture
 | 
			
		||||
			 * boundaries or texSubImage will generate errors.
 | 
			
		||||
			 * If it partly lies outside bounds we have to upload
 | 
			
		||||
			 * the clipped visible part of it. */
 | 
			
		||||
			SDL_Rect btmRect;
 | 
			
		||||
			btmRect.x = btmRect.y = 0;
 | 
			
		||||
			btmRect.w = width();
 | 
			
		||||
			btmRect.h = height();
 | 
			
		||||
 | 
			
		||||
			SDL_Rect txtRect;
 | 
			
		||||
			txtRect.x = posRect.x;
 | 
			
		||||
			txtRect.y = posRect.y;
 | 
			
		||||
			txtRect.w = posRect.w;
 | 
			
		||||
			txtRect.h = posRect.h;
 | 
			
		||||
 | 
			
		||||
			SDL_Rect inters;
 | 
			
		||||
 | 
			
		||||
			/* If we have no intersection at all,
 | 
			
		||||
			 * there's nothing to upload to begin with */
 | 
			
		||||
			if (SDL_IntersectRect(&btmRect, &txtRect, &inters))
 | 
			
		||||
			{
 | 
			
		||||
				if (inters.w != txtRect.w || inters.h != txtRect.h)
 | 
			
		||||
				{
 | 
			
		||||
					/* Clip the text surface */
 | 
			
		||||
					SDL_PixelFormat *form = txtSurf->format;
 | 
			
		||||
					SDL_Surface *clip =
 | 
			
		||||
					        SDL_CreateRGBSurface(0, inters.w, inters.h,
 | 
			
		||||
					                             form->BitsPerPixel,
 | 
			
		||||
					                             form->Rmask,
 | 
			
		||||
					                             form->Gmask,
 | 
			
		||||
					                             form->Bmask,
 | 
			
		||||
					                             form->Amask);
 | 
			
		||||
 | 
			
		||||
					SDL_Rect clipSrc = inters;
 | 
			
		||||
					clipSrc.x -= txtRect.x;
 | 
			
		||||
					clipSrc.y -= txtRect.y;
 | 
			
		||||
 | 
			
		||||
					SDL_BlitSurface(txtSurf, &clipSrc, clip, 0);
 | 
			
		||||
 | 
			
		||||
					posRect.x = inters.x;
 | 
			
		||||
					posRect.y = inters.y;
 | 
			
		||||
					posRect.w = inters.w;
 | 
			
		||||
					posRect.h = inters.h;
 | 
			
		||||
 | 
			
		||||
					SDL_FreeSurface(txtSurf);
 | 
			
		||||
					txtSurf = clip;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				TEX::bind(p->tex.tex);
 | 
			
		||||
				TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_BGRA_EXT);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Squeezing involved: need to use intermediary TexFBO */
 | 
			
		||||
| 
						 | 
				
			
			@ -889,7 +936,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	SDL_FreeSurface(txtSurf);
 | 
			
		||||
	p->addTaintedArea(drawnRect);
 | 
			
		||||
	p->addTaintedArea(posRect);
 | 
			
		||||
 | 
			
		||||
	modified();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue