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;
 | 
						Vec2i gpTexSize;
 | 
				
			||||||
	gState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize);
 | 
						gState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IntRect drawnRect = posRect;
 | 
						bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool fastBlit = !p->touchesTaintedArea(drawnRect) && txtAlpha == 1.0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fastBlit)
 | 
						if (fastBlit)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (squeeze == 1.0)
 | 
							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::bind(p->tex.tex);
 | 
				
			||||||
				TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_BGRA_EXT);
 | 
									TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_BGRA_EXT);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* Squeezing involved: need to use intermediary TexFBO */
 | 
								/* 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);
 | 
						SDL_FreeSurface(txtSurf);
 | 
				
			||||||
	p->addTaintedArea(drawnRect);
 | 
						p->addTaintedArea(posRect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	modified();
 | 
						modified();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue