pulled from downstream bzflag. apply sf patch 2210898 (Fix for some potential FTGL issues) from Matt Handley (applmak) where he adds some asserts that check for the conditions that provoke glTexSubImage2D to return GL_INVALID_VALUE. this is being provoked by ftgl during Advance when the font size (0-2) is smaller than the hard-coded default font padding size (3).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/src/FTGlyph/FTTextureGlyph.cpp b/src/FTGlyph/FTTextureGlyph.cpp
index a9cf2e8..af2d1d4 100644
--- a/src/FTGlyph/FTTextureGlyph.cpp
+++ b/src/FTGlyph/FTTextureGlyph.cpp
@@ -33,12 +33,29 @@
#include "FTInternals.h"
#include "FTTextureGlyphImpl.h"
+#define FTGL_ASSERTS_SHOULD_SOFT_FAIL
+
+#ifdef FTGL_ASSERTS_SHOULD_SOFT_FAIL
+ #define FTASSERT(x) \
+ if (!(x)) \
+ { \
+ fprintf(stderr,"ASSERTION FAILED (%s:%d)(soft): %s\n",__FILE__,__LINE__,#x); \
+ }
+#else
+ #define FTASSERT(x) \
+ if (!(x)) \
+ { \
+ fprintf(stderr,"ASSERTION FAILED (%s:%d): %s\n",__FILE__,__LINE__,#x); \
+ int *a = (int*)0x0; \
+ *a = 0xD15EA5ED; \
+ }
+#endif
+
//
// FTGLTextureGlyph
//
-
FTTextureGlyph::FTTextureGlyph(FT_GlyphSlot glyph, int id, int xOffset,
int yOffset, int width, int height) :
FTGlyph(new FTTextureGlyphImpl(glyph, id, xOffset, yOffset, width, height))
@@ -60,7 +77,6 @@ const FTPoint& FTTextureGlyph::Render(const FTPoint& pen, int renderMode)
// FTGLTextureGlyphImpl
//
-
GLint FTTextureGlyphImpl::activeTextureID = 0;
FTTextureGlyphImpl::FTTextureGlyphImpl(FT_GlyphSlot glyph, int id, int xOffset,
@@ -87,15 +103,37 @@ FTTextureGlyphImpl::FTTextureGlyphImpl(FT_GlyphSlot glyph, int id, int xOffset,
if(destWidth && destHeight)
{
- glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- glBindTexture(GL_TEXTURE_2D, glTextureID);
- glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer);
-
- glPopClientAttrib();
+ glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); {
+
+ glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glBindTexture(GL_TEXTURE_2D, glTextureID);
+ GLint w,h;
+ glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&w);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&h);
+
+ FTASSERT(xOffset >= 0);
+ FTASSERT(yOffset >= 0);
+ FTASSERT(destWidth >= 0);
+ FTASSERT(destHeight >= 0);
+ FTASSERT(xOffset+destWidth <= w);
+ FTASSERT(yOffset+destHeight <= h);
+
+ if (yOffset+destHeight > h)
+ {
+ //We'll only get here if we are soft-failing our asserts. In that case,
+ //since the data we're trying to put into our texture is too long,
+ //we'll only copy a portion of the image.
+ destHeight = h-yOffset;
+ }
+ if (destHeight >= 0)
+ {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer);
+ }
+
+ } glPopClientAttrib();
}