FLTK logo

[branch-1.3] 20138be - macOS: Fix color component mixup in gl_draw text rendering #947

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[branch-1.3] 20138be - macOS: Fix color component mixup in gl_draw text rendering #947 "Matthias Melcher" 09:17 Apr 05  
 
commit 20138be66be721405b142d13cab4dbd37c425d4f
Author:     Matthias Melcher <github@matthiasm.com>
AuthorDate: Fri Apr 5 18:02:39 2024 +0200
Commit:     Matthias Melcher <github@matthiasm.com>
CommitDate: Fri Apr 5 18:02:39 2024 +0200

    macOS: Fix color component mixup in gl_draw text rendering #947

 src/gl_draw.cxx | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git src/gl_draw.cxx src/gl_draw.cxx
index 1c120d9..d4914c9 100644
--- src/gl_draw.cxx
+++ src/gl_draw.cxx
@@ -365,6 +365,7 @@ private:
     int width; // its width
     float ratio; // used without rectangle texture
     int scale; // 1 or 2 for low/high resolution
+    Fl_Color color;
   } data;
   data *fifo; // array of pile elements
   int size_; // pile height
@@ -415,7 +416,7 @@ void gl_texture_fifo::display_texture(int rank)
   glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
   glDisable (GL_DEPTH_TEST); // ensure text is not removed by depth buffer test.
   glEnable (GL_BLEND); // for text fading
-  glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto
+  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // ditto
   glDisable(GL_LIGHTING);
   GLfloat pos[4];
   glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
@@ -426,6 +427,10 @@ void gl_texture_fifo::display_texture(int rank)
   glScalef (R/winw, R/winh, 1.0f);
   glTranslatef (-winw/R, -winh/R, 0.0f);
   if (has_texture_rectangle) {
+    // The texture map is already colored, but we still need to apply alpha.
+    GLfloat colors[4];
+    glGetFloatv(GL_CURRENT_COLOR, colors);
+    glColor4f(1.0f, 1.0f, 1.0f, colors[3]);
     glEnable (GL_TEXTURE_RECTANGLE_ARB);
     glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[rank].texName);
     GLint height;
@@ -444,6 +449,8 @@ void gl_texture_fifo::display_texture(int rank)
 
     glTexCoord2f (fifo[rank].width, 0.0f); // draw lower right in world coordinates
     glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
+    // Restore the current color value.
+    glColor4fv(colors);
     glEnd ();
   } else {
     glTranslatef(pos[0]*2/R, pos[1]*2/R, 0.0);
@@ -492,12 +499,19 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
     void *base = NULL;
     if (fl_mac_os_version < 100600) base = calloc(4*fifo[current].width, h);
     CGContextRef save_gc = fl_gc;
-    fl_gc = CGBitmapContextCreate(base, fifo[current].width, h, 8, fifo[current].width*4, lut,
-                                  (CGBitmapInfo)(kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+    // Create our bitmap in RGBA order (no matter what the host byte order is)
+    fl_gc = CGBitmapContextCreate(base, fifo[current].width, h, 8, fifo[current].width*4, lut, kCGImageAlphaPremultipliedLast);
     CGColorSpaceRelease(lut);
+    // Note that glyphs in macOS can be colorful (Emojis, for example). So
+    // instead of caching a mask, we store the text in RGB plus A for
+    // antialiasing. Draw the text in the requested color, but don't apply user
+    // alpha yet. It is applied later at render time so it's mixed correctly
+    // with the background.
     GLfloat colors[4];
     glGetFloatv(GL_CURRENT_COLOR, colors);
-    fl_color((uchar)(colors[0]*255), (uchar)(colors[1]*255), (uchar)(colors[2]*255));
+    Fl_Color color = ((uchar)(colors[0]*255)<<24) | ((uchar)(colors[1]*255)<<16) | ((uchar)(colors[2]*255)<<8);
+    fifo[current].color = color;
+    fl_color(color);
     CGContextTranslateCTM(fl_gc, 0, h - gl_scale*fl_descent());
     CGContextScaleCTM(fl_gc, gl_scale, gl_scale);
     fl_draw(str, n, 0, 0);
@@ -506,7 +520,8 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
     glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[current].texName);
     glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, fifo[current].width);
-    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, fifo[current].width, h, 0,  GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, CGBitmapContextGetData(fl_gc));
+    // Convert the created text bitmap into an RGBA OpenGL texture map.
+    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, fifo[current].width, h, 0,  GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, CGBitmapContextGetData(fl_gc));
     glPopAttrib();
     CGContextRelease(fl_gc);
     fl_gc = save_gc;
@@ -521,9 +536,20 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
 int gl_texture_fifo::already_known(const char *str, int n)
 {
   int rank;
+  GLfloat colors[4];
+  glGetFloatv(GL_CURRENT_COLOR, colors);
+  Fl_Color color = ((uchar)(colors[0]*255)<<24) | ((uchar)(colors[1]*255)<<16) | ((uchar)(colors[2]*255)<<8);
   for ( rank = 0; rank <= last; rank++) {
-    if ( memcmp(str, fifo[rank].utf8, n) == 0 && fifo[rank].utf8[n] == 0 &&
-      fifo[rank].fdesc == gl_fontsize && fifo[rank].scale == gl_scale) return rank;
+    const data &ff = fifo[rank];
+    if (   (ff.fdesc == gl_fontsize)
+        && (ff.scale == gl_scale)
+        && (ff.color == color)
+        && (ff.utf8 != NULL)
+        && (memcmp(str, ff.utf8, n) == 0)
+        && (ff.utf8[n] == 0))
+    {
+      return rank;
+    }
   }
   return -1;
 }
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.