Package: libftgl2 Version: 2.1.3~rc5-4+nmu1 Severity: normal Tags: upstream patch
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=589601 and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=742469 Since bug reports against stable seem to be generally ignored, I'm reporting this again for the version in unstable. (I don't actually use it, but since the version there is unchanged (except for an unrelated NMU), the bugs are obviously still there.) I don't know what more I could do: - I provided a detailed description and analysis of the problems. - I supplied patches, ready to apply, and tested. (The patches are included in the original reports, but I'm attaching a combined patch again, just in case.) - It's been more than 5 years since the original report (#531489), in which time I've been using ftgl with my patch and had no problems with it, and there hasn't been even a single reply to the bug reports (other that the automatic acknowledgement from the server) in all this time. - I'm mailing both the Debian BTS and the listed contact addresses for ftgl. So could you please apply my patches now, before another major release goes by with the bugs included? Otherwise I really wonder why I should report bugs at all. If I have to keep separate patched versions anyway, I can stop wasting my time trying to help other users who may experience the same problems, and keep my patches to myself. That's not my idea how free software should work, but neither is tracking simple changes for years with no response at all.
--- src/FTGlyph/FTPolygonGlyph.cpp.orig 2008-06-09 14:52:41.000000000 +0200 +++ src/FTGlyph/FTPolygonGlyph.cpp 2010-07-17 07:00:27.000000000 +0200 @@ -64,6 +64,7 @@ FTPolygonGlyphImpl::FTPolygonGlyphImpl(FT_GlyphSlot glyph, float _outset, bool useDisplayList) : FTGlyphImpl(glyph), + vectoriser(0), glList(0) { if(ft_glyph_format_outline != glyph->format) --- src/FTGlyph/FTOutlineGlyph.cpp.orig 2010-07-17 06:59:51.000000000 +0200 +++ src/FTGlyph/FTOutlineGlyph.cpp 2010-07-17 06:59:55.000000000 +0200 @@ -64,6 +64,7 @@ FTOutlineGlyphImpl::FTOutlineGlyphImpl(FT_GlyphSlot glyph, float _outset, bool useDisplayList) : FTGlyphImpl(glyph), + vectoriser(0), glList(0) { if(ft_glyph_format_outline != glyph->format) --- src/FTGlyph/FTBitmapGlyphImpl.h.orig 2008-06-09 14:49:52.000000000 +0200 +++ src/FTGlyph/FTBitmapGlyphImpl.h 2010-07-17 07:48:40.000000000 +0200 @@ -32,6 +32,7 @@ class FTBitmapGlyphImpl : public FTGlyphImpl { friend class FTBitmapGlyph; + friend class FTPixmapGlyph; protected: FTBitmapGlyphImpl(FT_GlyphSlot glyph); --- src/FTGL/FTPixmapGlyph.h.orig 2008-05-05 16:51:52.000000000 +0200 +++ src/FTGL/FTPixmapGlyph.h 2010-07-17 07:29:06.000000000 +0200 @@ -41,6 +41,8 @@ */ class FTGL_EXPORT FTPixmapGlyph : public FTGlyph { + static FTGlyphImpl *NewImpl(FT_GlyphSlot glyph); + public: /** * Constructor --- src/FTGlyph/FTPixmapGlyph.cpp.orig 2008-06-09 14:52:35.000000000 +0200 +++ src/FTGlyph/FTPixmapGlyph.cpp 2010-07-17 07:40:10.000000000 +0200 @@ -32,6 +32,7 @@ #include "FTInternals.h" #include "FTPixmapGlyphImpl.h" +#include "FTBitmapGlyphImpl.h" // @@ -40,7 +41,7 @@ FTPixmapGlyph::FTPixmapGlyph(FT_GlyphSlot glyph) : - FTGlyph(new FTPixmapGlyphImpl(glyph)) + FTGlyph(NewImpl(glyph)) {} @@ -48,10 +49,22 @@ {} +FTGlyphImpl *FTPixmapGlyph::NewImpl(FT_GlyphSlot glyph) +{ + FTPixmapGlyphImpl *Impl = new FTPixmapGlyphImpl(glyph); + if (Impl->destWidth && Impl->destHeight) + return Impl; + return new FTBitmapGlyphImpl(glyph); +} + + const FTPoint& FTPixmapGlyph::Render(const FTPoint& pen, int renderMode) { FTPixmapGlyphImpl *myimpl = dynamic_cast<FTPixmapGlyphImpl *>(impl); - return myimpl->RenderImpl(pen, renderMode); + if (myimpl) + return myimpl->RenderImpl(pen, renderMode); + FTBitmapGlyphImpl *myimpl_bitmap = dynamic_cast<FTBitmapGlyphImpl *>(impl); + return myimpl_bitmap->RenderImpl(pen, renderMode); } @@ -67,7 +80,7 @@ data(0) { err = FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL); - if(err || ft_glyph_format_bitmap != glyph->format) + if(err || ft_glyph_format_bitmap != glyph->format || glyph->bitmap.num_grays == 1) { return; } --- src/FTFont/FTBitmapFont.cpp.orig 2008-06-09 14:51:51.000000000 +0200 +++ src/FTFont/FTBitmapFont.cpp 2010-07-17 07:52:32.000000000 +0200 @@ -77,7 +77,7 @@ glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glDisable(GL_BLEND); + // glDisable(GL_BLEND); FTPoint tmp = FTFontImpl::Render(string, len, position, spacing, renderMode); --- src/FTGlyph/FTTextureGlyph.cpp.orig 2008-06-09 14:52:43.000000000 +0200 +++ src/FTGlyph/FTTextureGlyph.cpp 2010-07-17 08:22:23.000000000 +0200 @@ -92,8 +92,33 @@ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + unsigned char *data = bitmap.buffer; + if(bitmap.num_grays == 1) + { + bBox = FTBBox(0, 0, 0, destWidth, destHeight, 0); + data = new unsigned char[destWidth * destHeight]; + memset(data, 0, destWidth * destHeight); + unsigned char* dest = data; + for(int y = 0; y < destHeight; ++y) + { + unsigned char* src = bitmap.pitch < 0 + ? bitmap.buffer + (y - destHeight + 1) * bitmap.pitch + : bitmap.buffer + y * bitmap.pitch; + unsigned char c; + for(int x = 0; x < destWidth; ++x) + { + if (x % 8 == 0) + c = *src++; + *dest++ = ((c >> (7 - (x % 8))) & 1) * 255; + } + } + } + glBindTexture(GL_TEXTURE_2D, glTextureID); - glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, data); + + if (data != bitmap.buffer) + delete [] data; glPopClientAttrib(); } --- src/FTContour.cpp.orig 2008-06-09 14:53:56.000000000 +0200 +++ src/FTContour.cpp 2010-07-18 05:40:08.000000000 +0200 @@ -110,6 +110,13 @@ // FTPoint FTContour::ComputeOutsetPoint(FTPoint A, FTPoint B, FTPoint C) { + // If the angle between 'ab' and 'bc' approaches 180 degrees, + // the outset point goes to infinity, giving an invalid result. + // Even for angles near 180 degrees, the point will be quite + // far away from A, B and C. To avoid ugly results, limit + // its distance to 64.0 * OutsetMax. + static const FTGL_DOUBLE OutsetMax = 5; + /* Build the rotation matrix from 'ba' vector */ FTPoint ba = (A - B).Normalise(); FTPoint bc = C - B; @@ -120,7 +127,11 @@ /* Compute the vector bisecting 'abc' */ FTGL_DOUBLE norm = sqrt(tmp.X() * tmp.X() + tmp.Y() * tmp.Y()); - FTGL_DOUBLE dist = 64.0 * sqrt((norm - tmp.X()) / (norm + tmp.X())); + FTGL_DOUBLE dist; + if (norm - tmp.X() > (norm + tmp.X()) * OutsetMax * OutsetMax) + dist = 64.0 * OutsetMax; + else + dist = 64.0 * sqrt((norm - tmp.X()) / (norm + tmp.X())); tmp.X(tmp.Y() < 0.0 ? dist : -dist); tmp.Y(64.0); --- src/FTInternals.h.orig 2008-06-09 14:50:28.000000000 +0200 +++ src/FTInternals.h 2014-03-24 03:16:39.000000000 +0100 @@ -47,6 +47,7 @@ #define FT_RENDER_MODE_NORMAL ft_render_mode_normal #endif +#define GL_GLEXT_PROTOTYPES #ifdef WIN32 --- src/FTFont/FTBufferFont.cpp.orig 2008-06-12 11:52:03.000000000 +0200 +++ src/FTFont/FTBufferFont.cpp 2014-03-24 03:00:49.000000000 +0100 @@ -238,7 +238,7 @@ glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // Search whether the string is already in a texture we uploaded for(int n = 0; n < BUFFER_CACHE_SIZE; n++) --- src/FTFont/FTOutlineFont.cpp.orig 2008-06-09 14:52:07.000000000 +0200 +++ src/FTFont/FTOutlineFont.cpp 2014-03-24 03:01:05.000000000 +0100 @@ -101,7 +101,7 @@ glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); FTPoint tmp = FTFontImpl::Render(string, len, position, spacing, renderMode); --- src/FTFont/FTPixmapFont.cpp.orig 2008-06-09 14:52:09.000000000 +0200 +++ src/FTFont/FTPixmapFont.cpp 2014-03-24 03:01:16.000000000 +0100 @@ -92,7 +92,7 @@ glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); --- src/FTFont/FTTextureFont.cpp.orig 2014-03-24 03:01:25.000000000 +0100 +++ src/FTFont/FTTextureFont.cpp 2014-03-24 03:01:31.000000000 +0100 @@ -235,7 +235,7 @@ glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D);