Clip text surface to texture bounds on fast upload
This commit is contained in:
parent
19c30e3ddd
commit
751b9c3ae5
|
@ -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…
Reference in New Issue