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);
 

Reply via email to