[gucharmap] charmap: Improve glyph display



commit 20e88d8f7b220d9b2a455e4603de02eab888b2ec
Author: Christian Persch <chpe src gnome org>
Date:   Mon Mar 12 22:02:37 2018 +0100

    charmap: Improve glyph display
    
    Since it's not possible in the pango or cairo APIs to
    disable using colour glyphs for EmojiPresentation
    characters, resort to a gross hack by using ELF symbol
    interposition to intercept the FT_Load_Glyph function
    and strip the FT_LOAD_COLOR flag before calling the
    original function from libfreetype2.

 configure.ac     |    3 ++
 gucharmap/main.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a3ae9b8..447c953 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,8 @@ AM_MAINTAINER_MODE([enable])
 GNOME_DEBUG_CHECK
 
 AC_PROG_CC
+AC_USE_SYSTEM_EXTENSIONS
+
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 IT_PROG_INTLTOOL([0.40.0])
@@ -115,6 +117,7 @@ PKG_CHECK_MODULES([GTK],[
   glib-2.0 >= $GLIB_REQUIRED
   gio-2.0 >= $GIO_REQUIRED
   gtk+-$GTK_API_VERSION >= $GTK_REQUIRED
+  freetype2
 ])
 
 GLIB_GENMARSHAL="$($PKG_CONFIG --variable=glib_genmarshal glib-2.0)"
diff --git a/gucharmap/main.c b/gucharmap/main.c
index 3e7a870..28aca8d 100644
--- a/gucharmap/main.c
+++ b/gucharmap/main.c
@@ -29,7 +29,69 @@
 #include "gucharmap-window.h"
 
 #define UI_RESOURCE "/org/gnome/charmap/ui/menus.ui"
- 
+
+/* BEGIN HACK
+ *
+ * Gucharmap is a *character map*, not an emoji picker.
+ * Consequently, we want to show character glyphs in black
+ * and white, not colour emojis.
+ *
+ * However, there currently is no way in the pango API to
+ * suppress use of colour fonts.
+ * Internally, cairo *always* (!) calls FT_Load_Glyph with
+ * the FT_LOAD_COLOR flag. Interpose the function and strip
+ * that flag.
+ *
+ * This still doesn't get the desired display since the
+ * emoji colour fonts (Noto Color Emoji) that's hardcoded
+ * (see bug 787365) has greyscale fallback; I see no way
+ * to skip the font altogether.
+ */
+
+#include <dlfcn.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+extern FT_Error
+FT_Load_Glyph(FT_Face face,
+             FT_UInt glyph_index,
+             FT_Int32 load_flags);
+
+extern FT_Error
+FT_Load_Char(FT_Face face,
+            FT_ULong char_code,
+            FT_Int32 load_flags);
+
+FT_Error
+FT_Load_Glyph(FT_Face face,
+             FT_UInt glyph_index,
+             FT_Int32 load_flags)
+{
+  static FT_Error (*original)(FT_Face face,
+                             FT_UInt glyph_index,
+                             FT_Int32 load_flags) = NULL;
+  if (!original)
+    original = dlsym(RTLD_NEXT, "FT_Load_Glyph");
+
+  return original(face, glyph_index, load_flags & ~FT_LOAD_COLOR);
+}
+
+FT_Error
+FT_Load_Char( FT_Face face,
+             FT_ULong char_code,
+             FT_Int32 load_flags)
+{
+  static FT_Error (*original)(FT_Face face,
+                             FT_ULong char_code,
+                             FT_Int32 load_flags) = NULL;
+  if (!original)
+    original = dlsym(RTLD_NEXT, "FT_Load_Char");
+
+  return original(face, char_code, load_flags & ~FT_LOAD_COLOR);
+}
+
+/* END HACK */
+
 static gboolean
 option_version_cb (const gchar *option_name,
                    const gchar *value,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]