public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ibus] autotool: Delete ibus-xx-emoji-harfbuzz.patch
@ 2026-05-31  2:06 Takao Fujiwara
  0 siblings, 0 replies; only message in thread
From: Takao Fujiwara @ 2026-05-31  2:06 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/ibus
Branch : autotool
Commit : 3bca2d162b45cec3bdd1ff0fa31c98d8442f0bba
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date   : 2018-06-20T19:09:12+09:00
Stats  : +0/-1764 in 1 file(s)
URL    : https://src.fedoraproject.org/rpms/ibus/c/3bca2d162b45cec3bdd1ff0fa31c98d8442f0bba?branch=autotool

Log:
Delete ibus-xx-emoji-harfbuzz.patch

---
diff --git a/ibus-xx-emoji-harfbuzz.patch b/ibus-xx-emoji-harfbuzz.patch
deleted file mode 100644
index 15d1a05..0000000
--- a/ibus-xx-emoji-harfbuzz.patch
+++ /dev/null
@@ -1,1764 +0,0 @@
-From 631ef573ebdd4f3fad8f036fcb33929e04372ab2 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Thu, 1 Mar 2018 16:05:04 +0900
-Subject: [PATCH] Integrate custom rendering to use HarfBuzz glyph info
-
-IBusFontSet offers FcFontSet, glyph info with HarfBuzz and rendering
-on Cairo context.
-Now the most issues in Pango were fixed and I appreciate the changes [1].
-However the latest changes in Pango, Fontconfig prevent users from
-setting emoji fonts with GtkFontChooser.
-This patch can enable the selected emoji font to draw emoji chars
-on Emojier.
-It's under the considerations if the font setting is deleted from ibus-setup.
-Need configure --enable-harfbuzz-for-emoji option to enable this feature.
-
-[1]: https://bugzilla.gnome.org/show_bug.cgi?id=780669
-     https://bugzilla.gnome.org/show_bug.cgi?id=781123
----
- bindings/vala/IBusFontSet-1.0.metadata |    1 +
- bindings/vala/Makefile.am              |   83 +++
- bindings/vala/ibus-fontset-1.0.deps    |    1 +
- configure.ac                           |   29 +
- ui/gtk3/Makefile.am                    |   36 ++
- ui/gtk3/emojier.vala                   |  111 ++++
- ui/gtk3/ibusfontset.c                  | 1030 ++++++++++++++++++++++++++++++++
- ui/gtk3/ibusfontset.h                  |  302 ++++++++++
- 8 files changed, 1593 insertions(+)
- create mode 100644 bindings/vala/IBusFontSet-1.0.metadata
- create mode 100644 bindings/vala/ibus-fontset-1.0.deps
- create mode 100644 ui/gtk3/ibusfontset.c
- create mode 100644 ui/gtk3/ibusfontset.h
-
-diff --git a/bindings/vala/IBusFontSet-1.0.metadata b/bindings/vala/IBusFontSet-1.0.metadata
-new file mode 100644
-index 00000000..73037d7f
---- /dev/null
-+++ b/bindings/vala/IBusFontSet-1.0.metadata
-@@ -0,0 +1 @@
-+IBusFontSet cheader_filename="ibusfontset.h"
-diff --git a/bindings/vala/Makefile.am b/bindings/vala/Makefile.am
-index fc8e2f01..f7b9e97a 100644
---- a/bindings/vala/Makefile.am
-+++ b/bindings/vala/Makefile.am
-@@ -83,8 +83,10 @@ EXTRA_DIST =                                    \
-     IBus-1.0.metadata                           \
-     IBus-1.0-custom.vala                        \
-     IBusEmojiDialog-1.0.metadata                \
-+    IBusFontSet-1.0.metadata                    \
-     ibus-1.0.deps                               \
-     ibus-emoji-dialog-1.0.deps                  \
-+    ibus-fontset-1.0.deps                       \
-     config.vapi                                 \
-     xi.vapi                                     \
-     $(NULL)
-@@ -131,6 +133,15 @@ libibus_emoji_dialog_1_0_la_LDFLAGS =           \
- 	if test ! -f $@ ; then                                              \
- 	    $(LN_S) $(top_srcdir)/ui/gtk3/$@ .;                             \
- 	fi;
-+ibusfontset.c: $(ibus_vapi) ibusfontset.h
-+	if test ! -f $@ ; then                                              \
-+	    $(LN_S) $(top_srcdir)/ui/gtk3/$@ .;                             \
-+	fi;
-+ibusfontset.h: $(ibus_vapi)
-+	if test ! -f $@ ; then                                              \
-+	    $(LN_S) $(top_srcdir)/ui/gtk3/$@ .;                             \
-+	fi;
-+
- 
- MAINTAINERCLEANFILES += $(libibus_emoji_dialog_1_0_la_SOURCES)
- DISTCLEANFILES += $(libibus_emoji_dialog_1_0_la_SOURCES)
-@@ -184,6 +195,78 @@ DISTCLEANFILES += $(ibus_emoji_dialog_vapi)
- 
- endif
- #end of HAVE_INTROSPECTION
-+
-+
-+if ENABLE_HARFBUZZ_FOR_EMOJI
-+libibus_fontset = libibus-fontset-1.0.la
-+noinst_LTLIBRARIES += $(libibus_fontset)
-+
-+libibus_fontset_1_0_la_SOURCES =                \
-+    ibusfontset.c                               \
-+    $(NULL)
-+libibus_fontset_1_0_la_CFLAGS =                 \
-+    $(AM_CFLAGS)                                \
-+    @CAIRO_CFLAGS@                              \
-+    @FONTCONFIG_CFLAGS@                         \
-+    @GLIB2_CFLAGS@                              \
-+    @HARFBUZZ_CFLAGS@                           \
-+    @PANGO_CFLAGS@                              \
-+    $(NULL)
-+libibus_fontset_1_0_la_LIBADD =                 \
-+    @CAIRO_LIBS@                                \
-+    @FONTCONFIG_LIBS@                           \
-+    @GLIB2_LIBS@                                \
-+    @HARFBUZZ_LIBS@                             \
-+    @PANGO_LIBS@                                \
-+    $(NULL)
-+libibus_fontset_1_0_la_LDFLAGS =                \
-+    -no-undefined                               \
-+    -export-symbols-regex "ibus_.*"             \
-+    $(NULL)
-+
-+MAINTAINERCLEANFILES += ibusfontset.c ibusfontset.h
-+DISTCLEANFILES += ibusfontset.c ibusfontset.h
-+
-+if HAVE_INTROSPECTION
-+IBusFontSet-1.0.gir: $(libibus_fontset) Makefile
-+IBusFontSet_1_0_gir_SCANNERFLAGS =              \
-+    --pkg-export=ibus-1.0                       \
-+    --pkg=cairo                                 \
-+    --pkg=fontconfig                            \
-+    --pkg=harfbuzz                              \
-+    $(IBUS_GIR_SCANNERFLAGS)                    \
-+    $(NULL)
-+IBusFontSet_1_0_gir_LIBS = $(libibus_fontset) $(libibus)
-+IBusFontSet_1_0_gir_INCLUDES = cairo-1.0 GLib-2.0 GObject-2.0
-+IBusFontSet_1_0_gir_FILES =                     \
-+    ibusfontset.h                               \
-+    $(NULL)
-+IBusFontSet_1_0_gir_CFLAGS =                    \
-+    -I$(srcdir)                                 \
-+    -I$(builddir)                               \
-+    -I$(top_srcdir)/src                         \
-+    $(NULL)
-+ibus_fontset_gir = IBusFontSet-1.0.gir
-+INTROSPECTION_GIRS += $(ibus_fontset_gir)
-+noinst_DATA += $(ibus_fontset_gir)
-+EXTRA_DIST += $(ibus_fontset_gir)
-+MAINTAINERCLEANFILES += $(ibus_fontset_gir)
-+DISTCLEANFILES += $(ibus_fontset_gir)
-+
-+ibus-fontset-1.0.vapi: $(ibus_fontset_gir) IBusFontSet-1.0.metadata
-+ibus_fontset_vapi = ibus-fontset-1.0.vapi
-+ibus_fontset_1_0_vapi_METADATADIRS = $(srcdir)
-+ibus_fontset_1_0_vapi_FILES = IBusFontSet-1.0.gir
-+VAPIGEN_VAPIS += $(ibus_fontset_vapi)
-+noinst_DATA += $(ibus_fontset_vapi)
-+EXTRA_DIST += $(ibus_fontset_vapi)
-+MAINTAINERCLEANFILES += $(ibus_fontset_vapi)
-+DISTCLEANFILES += $(ibus_fontset_vapi)
-+
-+endif
-+# end of HAVE_INTROSPECTION
-+endif
-+# end of ENABLE_HARFBUZZ_FOR_EMOJI
- endif
- # end of ENABLE_EMOJI_DICT
- 
-diff --git a/bindings/vala/ibus-fontset-1.0.deps b/bindings/vala/ibus-fontset-1.0.deps
-new file mode 100644
-index 00000000..129fe166
---- /dev/null
-+++ b/bindings/vala/ibus-fontset-1.0.deps
-@@ -0,0 +1 @@
-+cairo
-diff --git a/configure.ac b/configure.ac
-index bd41069b..243396ff 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -688,6 +688,34 @@ the UCD files from https://www.unicode.org/Public/UNIDATA/)
-     enable_unicode_dict="yes (enabled, use --disable-unicode-dict to disable)"
- fi
- 
-+AC_ARG_ENABLE(harfbuzz-for-emoji,
-+    AS_HELP_STRING([--enable-harfbuzz-for-emoji],
-+                   [Enable HarBuzz to draw emoji characters.
-+                    Current Pango has a problem to draw emoji variants and
-+                    this way enables to use HarfBuzz directly in GtkLabel.]),
-+    [enable_harfbuzz_for_emoji=$enableval],
-+    [enable_harfbuzz_for_emoji=no]
-+)
-+AM_CONDITIONAL([ENABLE_HARFBUZZ_FOR_EMOJI],
-+               [test x"$enable_harfbuzz_for_emoji" = x"yes"])
-+
-+if test x"$enable_harfbuzz_for_emoji" = x"yes"; then
-+    PKG_CHECK_MODULES(CAIRO, [
-+        cairo
-+    ])
-+    PKG_CHECK_MODULES(FONTCONFIG, [
-+        fontconfig
-+    ])
-+    PKG_CHECK_MODULES(HARFBUZZ, [
-+        harfbuzz
-+    ])
-+    PKG_CHECK_MODULES(PANGO, [
-+        pango
-+    ])
-+else
-+    enable_harfbuzz_for_emoji="no (disabled, use --enable-harfbuzz-for-emoji to enable)"
-+fi
-+
- # Check iso-codes.
- PKG_CHECK_MODULES(ISOCODES, [
-     iso-codes
-@@ -780,6 +808,7 @@ Build options:
-   CLDR annotation directory     $EMOJI_ANNOTATION_DIR
-   Enable Unicode dict           $enable_unicode_dict
-   UCD directory                 $UCD_DIR
-+  Enable HarfBuzz for Emoji     $enable_harfbuzz_for_emoji
-   Run test cases                $enable_tests
- ])
- 
-diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
-index bf9f98d7..388f80f9 100644
---- a/ui/gtk3/Makefile.am
-+++ b/ui/gtk3/Makefile.am
-@@ -159,6 +159,8 @@ EXTRA_DIST =                            \
-     extension.vala                      \
-     gtkextension.xml.in                 \
-     gtkpanel.xml.in                     \
-+    ibusfontset.c                       \
-+    ibusfontset.h                       \
-     notification-item.xml               \
-     notification-watcher.xml            \
-     ibus-ui-emojier.desktop.in.in       \
-@@ -249,6 +251,40 @@ panelbinding.o: $(srcdir)/panelbinding.c
- 	$(AM_V_CC_no)$(COMPILE) -c -o $@ $<
- 	$(NULL)
- 
-+if ENABLE_HARFBUZZ_FOR_EMOJI
-+ibus_ui_gtk3_SOURCES +=                         \
-+    ibusfontset.c                               \
-+    $(NULL)
-+
-+ibus_ui_emojier_SOURCES +=                      \
-+    ibusfontset.c                               \
-+    $(NULL)
-+
-+ibus_extension_gtk3_SOURCES +=                  \
-+    ibusfontset.c                               \
-+    $(NULL)
-+
-+AM_CFLAGS += \
-+    @CAIRO_CFLAGS@                              \
-+    @FONTCONFIG_CFLAGS@                         \
-+    @HARFBUZZ_CFLAGS@                           \
-+    $(NULL)
-+
-+AM_LDADD += \
-+    @CAIRO_LIBS@                                \
-+    @FONTCONFIG_LIBS@                           \
-+    @HARFBUZZ_LIBS@                             \
-+    $(NULL)
-+
-+AM_VALAFLAGS += \
-+    -D ENABLE_HARFBUZZ_FOR_EMOJI                \
-+    --pkg=cairo                                 \
-+    --pkg=ibus-fontset-1.0                      \
-+    $(NULL)
-+
-+endif
-+# end of ENABLE_HARFBUZZ_FOR_EMOJI
-+
- man_seven_files = $(man_seven_in_files:.7.in=.7)
- man_seven_DATA =$(man_seven_files:.7=.7.gz)
- man_sevendir = $(mandir)/man7
-diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
-index 8707e432..49619d1c 100644
---- a/ui/gtk3/emojier.vala
-+++ b/ui/gtk3/emojier.vala
-@@ -99,16 +99,103 @@ public class IBusEmojier : Gtk.ApplicationWindow {
-         }
-     }
-     private class EWhiteLabel : Gtk.Label {
-+#if ENABLE_HARFBUZZ_FOR_EMOJI
-+        private IBus.RequisitionEx m_requisition;
-+#else
-         private int m_minimum_width = 0;
-         private int m_natural_width = 0;
-         private int m_minimum_height = 0;
-         private int m_natural_height = 0;
-+#endif
-         public EWhiteLabel(string text) {
-             GLib.Object(
-                 name : "IBusEmojierWhiteLabel"
-             );
-             set_label(text);
-         }
-+#if ENABLE_HARFBUZZ_FOR_EMOJI
-+        private void get_preferred_size_with_hb(out int minimum_width,
-+                                                out int natural_width,
-+                                                out int minimum_height,
-+                                                out int natural_height) {
-+            minimum_width = 0;
-+            natural_width = 0;
-+            minimum_height = 0;
-+            natural_height = 0;
-+            var text = this.get_text();
-+            GLib.return_if_fail (text != null);
-+            if (text == "")
-+                return;
-+            var context = this.get_pango_context();
-+            var language = context.get_language();
-+            update_fontset(language);
-+            Cairo.RectangleInt widest = Cairo.RectangleInt();
-+            m_requisition = m_fontset.get_preferred_size_hb(text, out widest);
-+            minimum_width = widest.width;
-+            natural_width = widest.width;
-+            minimum_height = widest.height;
-+            natural_height = widest.height;
-+            if (minimum_width <= minimum_height)
-+                natural_width = minimum_width = minimum_height;
-+            if (text.length == 1) {
-+                switch(text.get_char()) {
-+                case '\t':
-+                    natural_width = minimum_width = minimum_height;
-+                    break;
-+                case '\v':
-+                    natural_height = minimum_height = minimum_width;
-+                    break;
-+                }
-+            }
-+        }
-+        public override void get_preferred_width(out int minimum_width,
-+                                                 out int natural_width) {
-+            get_preferred_size_with_hb(out minimum_width,
-+                                       out natural_width,
-+                                       null, null);
-+        }
-+        public override void get_preferred_height(out int minimum_height,
-+                                                  out int natural_height) {
-+            get_preferred_size_with_hb(null, null,
-+                                       out minimum_height,
-+                                       out natural_height);
-+        }
-+        public override bool draw(Cairo.Context cr) {
-+            var style_context = get_style_context();
-+            Gtk.Allocation allocation;
-+            get_allocation(out allocation);
-+            style_context.render_background(cr,
-+                                            0, 0,
-+                                            allocation.width,
-+                                            allocation.height);
-+            if (m_fontset == null)
-+                return true;
-+            if (m_requisition == null)
-+                return true;
-+            if (m_requisition.cairo_lines == null)
-+                return true;
-+            Gdk.RGBA *normal_fg = null;
-+            style_context.get(Gtk.StateFlags.NORMAL,
-+                              "color",
-+                              out normal_fg);
-+            cr.set_operator(Cairo.Operator.OVER);
-+            cr.set_source_rgba(normal_fg.red, normal_fg.green, normal_fg.blue,
-+                               normal_fg.alpha);
-+            cr.save();
-+            double x = 0.0;
-+            double y = 0.0;
-+            if (allocation.width > m_requisition.width)
-+                x = (allocation.width - m_requisition.width) / 2.0;
-+            if (allocation.height > m_requisition.height)
-+                y = (allocation.height - m_requisition.height) / 2.0;
-+            cr.translate(x, y);
-+            m_fontset.draw_cairo_with_requisition_ex(cr, m_requisition);
-+            cr.restore();
-+            normal_fg.free();
-+            normal_fg = null;
-+            return true;
-+        }
-+#else
-         public override void get_preferred_width(out int minimum_width,
-                                                  out int natural_width) {
-             if (m_minimum_height == 0 && m_natural_height == 0) {
-@@ -161,6 +248,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
-             m_minimum_height = minimum_height;
-             m_natural_height = natural_height;
-         }
-+#endif
-     }
-     private class ESelectedLabel : EWhiteLabel {
-         public ESelectedLabel(string text) {
-@@ -313,6 +401,9 @@ public class IBusEmojier : Gtk.ApplicationWindow {
-     private static bool m_show_unicode = false;
-     private static LoadProgressObject m_unicode_progress_object;
-     private static bool m_loaded_unicode = false;
-+#if ENABLE_HARFBUZZ_FOR_EMOJI
-+    private static IBus.FontSet m_fontset;
-+#endif
- 
-     private ThemedRGBA m_rgba;
-     private Gtk.Box m_vbox;
-@@ -2116,6 +2207,22 @@ public class IBusEmojier : Gtk.ApplicationWindow {
-     }
- 
- 
-+#if ENABLE_HARFBUZZ_FOR_EMOJI
-+    private static void update_fontset(Pango.Language language) {
-+        if (m_fontset != null) {
-+            m_fontset.set_family(m_emoji_font_family);
-+            m_fontset.set_size(m_emoji_font_size);
-+            m_fontset.set_language(language.to_string());
-+            m_fontset.update_fcfontset();
-+        } else {
-+            m_fontset = new IBus.FontSet.with_font(
-+                    m_emoji_font_family,
-+                    m_emoji_font_size,
-+                    language.to_string());
-+        }
-+    }
-+#endif
-+
-     public static bool has_loaded_emoji_dict() {
-         if (m_emoji_to_data_dict == null)
-             return false;
-@@ -2146,6 +2253,10 @@ public class IBusEmojier : Gtk.ApplicationWindow {
-         int font_size = font_desc.get_size() / Pango.SCALE;
-         if (font_size != 0)
-             m_emoji_font_size = font_size;
-+#if ENABLE_HARFBUZZ_FOR_EMOJI
-+        var widget = new Gtk.Label("");
-+        update_fontset(widget.get_pango_context().get_language());
-+#endif
-     }
- 
- 
-diff --git a/ui/gtk3/ibusfontset.c b/ui/gtk3/ibusfontset.c
-new file mode 100644
-index 00000000..16ceef05
---- /dev/null
-+++ b/ui/gtk3/ibusfontset.c
-@@ -0,0 +1,1030 @@
-+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
-+/* vim:set et sts=4: */
-+/* ibus - The Input Bus
-+ * Copyright (C) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2017 Red Hat, Inc.
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
-+ * USA
-+ */
-+
-+#include <cairo-ft.h>
-+#include <fontconfig/fontconfig.h>
-+#include <ft2build.h>
-+#include FT_FREETYPE_H
-+#include <glib.h>
-+#include <hb-ot.h>
-+#include <pango/pango.h>
-+
-+#include "ibusfontset.h"
-+
-+#define XPAD 2
-+#define YPAD 2
-+#define UNKNOWN_FONT_SIZE 7
-+#define IBUS_FONTSET_GET_PRIVATE(o)  \
-+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_FONTSET, IBusFontSetPrivate))
-+#define MONOSPACE "monospace"
-+#define SERIF     "serif"
-+#define SANS      "sans"
-+
-+typedef struct _FcFontSetEx {
-+    int                 nfont;
-+    int                 sfont;
-+    FcPattern         **fonts;
-+    FT_Face            *ft_faces;
-+} FcFontSetEx;
-+
-+static gboolean         m_color_supported;
-+static FT_Library       m_ftlibrary;
-+static FcFontSetEx     *m_fcfontset;
-+static gchar           *m_family;
-+static guint            m_size;
-+static gchar           *m_language;
-+static GHashTable      *m_font_index_per_char_table;
-+static GHashTable      *m_scaled_font_table;
-+static GHashTable      *m_hb_font_table;
-+
-+enum {
-+    PROP_0,
-+    PROP_FAMILY,
-+    PROP_SIZE,
-+    PROP_LANGUAGE
-+};
-+
-+typedef struct {
-+    gunichar   ch;
-+    FcPattern *fcfont;
-+} FontPerChar;
-+
-+struct _IBusFontSetPrivate {
-+    gchar     *family;
-+    guint      size;
-+    gchar     *language;
-+};
-+
-+static GObject * ibus_fontset_constructor   (GType                  type,
-+                                             guint                  n,
-+                                             GObjectConstructParam *args);
-+static void      ibus_fontset_destroy       (IBusFontSet           *fontset);
-+static void      ibus_fontset_set_property  (IBusFontSet           *fontset,
-+                                             guint                  prop_id,
-+                                             const GValue          *value,
-+                                             GParamSpec            *pspec);
-+static void      ibus_fontset_get_property  (IBusFontSet           *fontset,
-+                                             guint                  prop_id,
-+                                             GValue                *value,
-+                                             GParamSpec            *pspec);
-+static cairo_scaled_font_t *
-+                 ibus_fontset_cairo_scaled_font_new_with_font
-+                                            (const gchar           *family,
-+                                             guint                  size,
-+                                             gboolean               has_color);
-+
-+G_DEFINE_BOXED_TYPE (IBusCairoLine,
-+                     ibus_cairo_line,
-+                     ibus_cairo_line_copy,
-+                     ibus_cairo_line_free);
-+G_DEFINE_BOXED_TYPE (IBusRequisitionEx,
-+                     ibus_requisition_ex,
-+                     ibus_requisition_ex_copy,
-+                     ibus_requisition_ex_free);
-+G_DEFINE_TYPE (IBusFontSet, ibus_fontset, IBUS_TYPE_OBJECT)
-+
-+static void
-+ibus_fontset_class_init (IBusFontSetClass *class)
-+{
-+    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-+    IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
-+    cairo_glyph_t dummy;
-+    IBusGlyph dummy2;
-+
-+    m_color_supported = (FcGetVersion () >=  21205);
-+    gobject_class->constructor = ibus_fontset_constructor;
-+    gobject_class->get_property =
-+            (GObjectGetPropertyFunc) ibus_fontset_get_property;
-+    gobject_class->set_property =
-+            (GObjectSetPropertyFunc) ibus_fontset_set_property;
-+    object_class->destroy = (IBusObjectDestroyFunc) ibus_fontset_destroy;
-+
-+    /* install properties */
-+    /**
-+     * IBusFontSet:family:
-+     *
-+     * Font family of this IBusFontSet.
-+     */
-+    g_object_class_install_property (gobject_class,
-+                    PROP_FAMILY,
-+                    g_param_spec_string ("family",
-+                        "family",
-+                        "family",
-+                        "",
-+                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-+
-+    /**
-+     * IBusFontSet:size:
-+     *
-+     * Font size of this IBusFontSet.
-+     */
-+    g_object_class_install_property (gobject_class,
-+                    PROP_SIZE,
-+                    g_param_spec_uint ("size",
-+                        "size",
-+                        "size",
-+                        0, G_MAXUINT16, 0,
-+                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-+
-+    /**
-+     * IBusFontSet:language:
-+     *
-+     * Font language of this IBusFontSet.
-+     */
-+    g_object_class_install_property (gobject_class,
-+                    PROP_LANGUAGE,
-+                    g_param_spec_string ("language",
-+                        "language",
-+                        "language",
-+                        "",
-+                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-+
-+    g_type_class_add_private (class, sizeof (IBusFontSetPrivate));
-+    FT_Init_FreeType (&m_ftlibrary);
-+    m_scaled_font_table = g_hash_table_new_full (
-+            g_str_hash, g_str_equal,
-+            g_free,
-+            (GDestroyNotify) cairo_scaled_font_destroy);
-+    m_hb_font_table = g_hash_table_new_full (
-+            g_str_hash, g_str_equal,
-+            g_free,
-+            (GDestroyNotify) hb_font_destroy);
-+
-+    /* hb_glyph_t is not available in Vala so override it with IBusGlyph. */
-+    g_assert (sizeof (dummy) == sizeof (dummy2));
-+    g_assert (sizeof (dummy.index) == sizeof (dummy2.index));
-+    g_assert (sizeof (dummy.x) == sizeof (dummy2.x));
-+    g_assert (sizeof (dummy.y) == sizeof (dummy2.y));
-+}
-+
-+static void
-+ibus_fontset_init (IBusFontSet *fontset)
-+{
-+    fontset->priv = IBUS_FONTSET_GET_PRIVATE (fontset);
-+}
-+
-+
-+static GObject *
-+ibus_fontset_constructor (GType                   type,
-+                          guint                   n,
-+                          GObjectConstructParam  *args)
-+{
-+    GObject *object;
-+    IBusFontSet *fontset;
-+    const gchar *family;
-+    guint size;
-+
-+    object = G_OBJECT_CLASS (ibus_fontset_parent_class)->constructor (
-+            type, n ,args);
-+    fontset = IBUS_FONTSET (object);
-+    family = ibus_fontset_get_family (fontset);
-+    size = ibus_fontset_get_size (fontset);
-+    ibus_fontset_update_fcfontset (fontset);
-+    if (family != NULL && size > 0) {
-+        /* cache the font */
-+        ibus_fontset_cairo_scaled_font_new_with_font (family,
-+                                                      size,
-+                                                      TRUE);
-+    }
-+    return object;
-+}
-+
-+static void
-+ibus_fontset_destroy (IBusFontSet *fontset)
-+{
-+    g_clear_pointer (&fontset->priv->family, g_free);
-+    g_clear_pointer (&fontset->priv->language, g_free);
-+}
-+
-+static void
-+ibus_fontset_set_property (IBusFontSet  *fontset,
-+                           guint         prop_id,
-+                           const GValue *value,
-+                           GParamSpec   *pspec)
-+{
-+    switch (prop_id) {
-+    case PROP_FAMILY:
-+        ibus_fontset_set_family (fontset, g_value_get_string (value));
-+        break;
-+    case PROP_SIZE:
-+        ibus_fontset_set_size (fontset, g_value_get_uint (value));
-+        break;
-+    case PROP_LANGUAGE:
-+        ibus_fontset_set_language (fontset, g_value_get_string (value));
-+        break;
-+    default:
-+        G_OBJECT_WARN_INVALID_PROPERTY_ID (fontset, prop_id, pspec);
-+    }
-+}
-+
-+static void
-+ibus_fontset_get_property (IBusFontSet *fontset,
-+                           guint          prop_id,
-+                           GValue        *value,
-+                           GParamSpec    *pspec)
-+{
-+    switch (prop_id) {
-+    case PROP_FAMILY:
-+        g_value_set_string (value, ibus_fontset_get_family (fontset));
-+        break;
-+    case PROP_SIZE:
-+        g_value_set_uint (value, ibus_fontset_get_size (fontset));
-+        break;
-+    case PROP_LANGUAGE:
-+        g_value_set_string (value, ibus_fontset_get_language (fontset));
-+        break;
-+    default:
-+        G_OBJECT_WARN_INVALID_PROPERTY_ID (fontset, prop_id, pspec);
-+    }
-+}
-+
-+static cairo_scaled_font_t *
-+ibus_fontset_cairo_scaled_font_new_with_font (const gchar *family,
-+                                              guint        size,
-+                                              gboolean     has_color)
-+{
-+    gchar *font_name;
-+    cairo_scaled_font_t *scaled_font = NULL;
-+    FcPattern *pattern, *resolved;
-+    FcResult result;
-+    cairo_font_options_t *font_options;
-+    double pixel_size = 0.;
-+    FcMatrix fc_matrix, *fc_matrix_val;
-+    cairo_font_face_t *cairo_face = NULL;
-+    cairo_matrix_t font_matrix;
-+    cairo_matrix_t ctm;
-+    int i;
-+
-+    g_return_val_if_fail (family != NULL, NULL);
-+    g_return_val_if_fail (m_scaled_font_table != NULL, NULL);
-+
-+    if (m_color_supported) {
-+        font_name = g_strdup_printf ("%s %u:color=%s",
-+                                     family, size,
-+                                     has_color ? "TRUE" : "FALSE");
-+    } else {
-+        font_name = g_strdup_printf ("%s %u", family, size);
-+    }
-+    scaled_font = g_hash_table_lookup (m_scaled_font_table, font_name);
-+    if (scaled_font != NULL) {
-+        g_free (font_name);
-+        return scaled_font;
-+    }
-+    pattern = FcPatternCreate ();
-+    FcPatternAddString (pattern, FC_FAMILY, (FcChar8*) family);
-+    FcPatternAddDouble (pattern, FC_SIZE, (double) size);
-+/* FC_VERSION is for the build check of FC_COLOR and m_color_supported is
-+ * for the runtime check.
-+ */
-+#if FC_VERSION >=  21205
-+    if (m_color_supported)
-+        FcPatternAddBool (pattern, FC_COLOR, has_color);
-+#endif
-+    FcPatternAddDouble (pattern, FC_DPI, 96);
-+    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
-+    font_options = cairo_font_options_create ();
-+    cairo_ft_font_options_substitute (font_options, pattern);
-+    FcDefaultSubstitute (pattern);
-+    resolved = FcFontMatch (NULL, pattern, &result);
-+    FcPatternDestroy (pattern);
-+    FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size);
-+    if (pixel_size == 0.)
-+        g_warning ("Failed to scaled the font: %s %u", family, size);
-+    cairo_face = cairo_ft_font_face_create_for_pattern (resolved);
-+    FcMatrixInit (&fc_matrix);
-+    for (i = 0;
-+         FcPatternGetMatrix (resolved, FC_MATRIX, i, &fc_matrix_val)
-+                 == FcResultMatch;
-+         i++) {
-+        FcMatrixMultiply (&fc_matrix, &fc_matrix, fc_matrix_val);
-+    }
-+    FcPatternDestroy (resolved);
-+    cairo_matrix_init (&font_matrix,
-+                       fc_matrix.xx, -fc_matrix.yx,
-+                       -fc_matrix.xy, fc_matrix.yy,
-+                       0., 0.);
-+    if (pixel_size != 0.)
-+        cairo_matrix_scale (&font_matrix, pixel_size, pixel_size);
-+    cairo_matrix_init_identity (&ctm);
-+    scaled_font = cairo_scaled_font_create (cairo_face,
-+                                            &font_matrix, &ctm,
-+                                            font_options);
-+    cairo_font_face_destroy (cairo_face);
-+    if (font_name)
-+        g_hash_table_insert(m_scaled_font_table, font_name, scaled_font);
-+
-+    return scaled_font;
-+}
-+
-+static hb_font_t *
-+ibus_fontset_hb_font_new_with_font_path (const gchar *font_path)
-+{
-+    hb_font_t *hb_font;
-+    GError *error = NULL;
-+    GMappedFile *mf;
-+    char *font_data = NULL;
-+    gsize len;
-+    hb_blob_t *hb_blob;
-+    hb_face_t *hb_face;
-+
-+    g_return_val_if_fail (font_path != NULL, NULL);
-+    g_return_val_if_fail (m_hb_font_table != NULL, NULL);
-+
-+    hb_font = g_hash_table_lookup (m_hb_font_table, font_path);
-+    if (hb_font != NULL)
-+        return hb_font;
-+
-+    mf = g_mapped_file_new (font_path, FALSE, &error);
-+    if (mf == NULL) {
-+        g_warning ("Not found font %s", font_path);
-+        return NULL;
-+    }
-+    font_data = g_mapped_file_get_contents (mf);
-+    len = g_mapped_file_get_length (mf);
-+    if (len == 0) {
-+        g_warning ("zero size font %s", font_path);
-+        g_mapped_file_unref (mf);
-+        return NULL;
-+    }
-+    hb_blob = hb_blob_create (font_data, len,
-+                              HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
-+                              mf, (hb_destroy_func_t)g_mapped_file_unref);
-+    hb_face = hb_face_create (hb_blob, 0);
-+    hb_blob_destroy (hb_blob);
-+    hb_font = hb_font_create (hb_face);
-+    unsigned int upem = hb_face_get_upem (hb_face);
-+    hb_font_set_scale (hb_font, upem, upem);
-+    hb_face_destroy (hb_face);
-+    hb_ot_font_set_funcs (hb_font);
-+    g_hash_table_insert (m_hb_font_table, g_strdup (font_path), hb_font);
-+
-+    return hb_font;
-+}
-+
-+static void
-+get_font_extents_with_scaled_font (cairo_scaled_font_t *scaled_font,
-+                                   PangoRectangle      *font_rect)
-+{
-+    cairo_font_extents_t font_extents;
-+
-+    g_assert (scaled_font != NULL && font_rect != NULL);
-+
-+    cairo_scaled_font_extents (scaled_font, &font_extents);
-+    font_rect->x = 0;
-+    font_rect->y = - pango_units_from_double (font_extents.ascent);
-+    font_rect->width = 0;
-+    font_rect->height = pango_units_from_double (
-+            font_extents.ascent + font_extents.descent);
-+}
-+
-+static void
-+get_glyph_extents_with_scaled_hb_font (const gchar          *str,
-+                                       cairo_scaled_font_t  *scaled_font,
-+                                       hb_font_t            *hb_font,
-+                                       PangoRectangle       *font_rect,
-+                                       IBusCairoLine       **cairo_lines,
-+                                       FcChar8              *fallback_family)
-+{
-+    gboolean has_unknown_glyph = FALSE;
-+    hb_buffer_t *hb_buffer;
-+    unsigned int len, n, i;
-+    hb_glyph_info_t *info;
-+    hb_glyph_position_t *pos;
-+    double x;
-+    cairo_glyph_t *glyph;
-+    cairo_text_extents_t text_extents = { 0, };
-+
-+    g_return_if_fail (str != NULL);
-+
-+    hb_buffer = hb_buffer_create ();
-+    hb_buffer_add_utf8 (hb_buffer, str, -1, 0, -1);
-+    hb_buffer_guess_segment_properties (hb_buffer);
-+    for (n = 0; *cairo_lines && (*cairo_lines)[n].scaled_font; n++);
-+    if (n == 0)
-+        *cairo_lines = g_new0 (IBusCairoLine, 2);
-+    else
-+        *cairo_lines = g_renew (IBusCairoLine, *cairo_lines, n + 2);
-+    (*cairo_lines)[n + 1].scaled_font = NULL;
-+    (*cairo_lines)[n + 1].num_glyphs = 0;
-+    (*cairo_lines)[n + 1].glyphs = NULL;
-+    hb_shape (hb_font, hb_buffer, NULL, 0);
-+    len = hb_buffer_get_length (hb_buffer);
-+    info = hb_buffer_get_glyph_infos (hb_buffer, NULL);
-+    pos = hb_buffer_get_glyph_positions (hb_buffer, NULL);
-+    (*cairo_lines)[n].scaled_font = scaled_font;
-+    (*cairo_lines)[n].num_glyphs = len;
-+    (*cairo_lines)[n].glyphs = (IBusGlyph*) cairo_glyph_allocate (len + 1);
-+    x = 0.;
-+    for (i = 0; i < len; i++) {
-+        hb_codepoint_t c = info[i].codepoint;
-+        if (c) {
-+            (*cairo_lines)[n].glyphs[i].index = info[i].codepoint;
-+            (*cairo_lines)[n].glyphs[i].x = x;
-+            (*cairo_lines)[n].glyphs[i].y = -font_rect->y / PANGO_SCALE;
-+            glyph = (cairo_glyph_t *) &((*cairo_lines)[n].glyphs[i]);
-+            cairo_scaled_font_glyph_extents (scaled_font, glyph,
-+                                             1, &text_extents);
-+            x += text_extents.width;
-+        } else {
-+            has_unknown_glyph = TRUE;
-+            c = g_utf8_get_char (str);
-+            (*cairo_lines)[n].glyphs[i].index = PANGO_GET_UNKNOWN_GLYPH (c);
-+            (*cairo_lines)[n].glyphs[i].x = x;
-+            (*cairo_lines)[n].glyphs[i].y = -font_rect->y / PANGO_SCALE;
-+            glyph = (cairo_glyph_t *) &((*cairo_lines)[n].glyphs[i]);
-+            cairo_scaled_font_glyph_extents (scaled_font, glyph,
-+                                             1, &text_extents);
-+            x += 10;
-+        }
-+    }
-+    (*cairo_lines)[n].glyphs[i].index = -1;
-+    (*cairo_lines)[n].glyphs[i].x = 0;
-+    (*cairo_lines)[n].glyphs[i].y = 0;
-+    glyph = (cairo_glyph_t *) (*cairo_lines)[n].glyphs;
-+    cairo_scaled_font_glyph_extents (scaled_font, glyph,
-+                                     len, &text_extents);
-+    if (text_extents.width) {
-+        font_rect->width = pango_units_from_double (text_extents.width);
-+    } else {
-+        font_rect->width = font_rect->height;
-+    }
-+    if (has_unknown_glyph && fallback_family != NULL) {
-+        cairo_scaled_font_t  *unknown_font;
-+        unknown_font = ibus_fontset_cairo_scaled_font_new_with_font (
-+            (const gchar *) fallback_family,
-+            UNKNOWN_FONT_SIZE,
-+            FALSE);
-+        (*cairo_lines)[n].scaled_font = unknown_font;
-+    }
-+    hb_buffer_destroy (hb_buffer);
-+}
-+
-+static void
-+get_string_extents_with_font (const gchar            *str,
-+                              FontPerChar            *buff,
-+                              cairo_rectangle_int_t  *rect,
-+                              IBusCairoLine         **cairo_lines)
-+{
-+    FcChar8 *family = NULL;
-+    FcChar8 *font_path = NULL;
-+    gboolean has_color = TRUE;
-+    guint size = 0;
-+    cairo_scaled_font_t *scaled_font = NULL;
-+    PangoRectangle font_rect = { 0, };
-+    hb_font_t *hb_font;
-+
-+    g_return_if_fail (str != NULL);
-+    g_return_if_fail (buff != NULL && buff->fcfont != NULL);
-+
-+    FcPatternGetString (buff->fcfont, FC_FAMILY, 0, &family);
-+    g_return_if_fail (family != NULL);
-+#if FC_VERSION >=  21205
-+    if (m_color_supported)
-+        FcPatternGetBool (buff->fcfont, FC_COLOR, 0, &has_color);
-+#endif
-+    size = m_size;
-+    if (size == 0) {
-+        g_warning ("Font size is not right for font %s.", family);
-+        size = 14;
-+    }
-+    scaled_font = ibus_fontset_cairo_scaled_font_new_with_font (
-+            (const gchar *) family,
-+            size,
-+            has_color);
-+    g_return_if_fail (scaled_font != NULL);
-+    get_font_extents_with_scaled_font (scaled_font, &font_rect);
-+
-+    FcPatternGetString (buff->fcfont, FC_FILE, 0, &font_path);
-+    g_return_if_fail (font_path != NULL);
-+    hb_font = ibus_fontset_hb_font_new_with_font_path (
-+            (const gchar *) font_path);
-+    if (hb_font == NULL)
-+        return;
-+    get_glyph_extents_with_scaled_hb_font (str,
-+                                           scaled_font,
-+                                           hb_font,
-+                                           &font_rect,
-+                                           cairo_lines,
-+                                           family);
-+    rect->width += font_rect.width / PANGO_SCALE;
-+    rect->height += font_rect.height / PANGO_SCALE;
-+}
-+
-+static FT_Face
-+ibus_fontset_get_ftface_from_fcfont (IBusFontSet *fontset,
-+                                     FcPattern   *fcfont)
-+{
-+    FcChar8 *font_file = NULL;
-+    FT_Face ft_face;
-+    guint size = ibus_fontset_get_size (fontset);
-+
-+    g_return_val_if_fail (IBUS_IS_FONTSET (fontset), NULL);
-+    g_return_val_if_fail (fcfont != NULL, NULL);
-+
-+    size = ibus_fontset_get_size (fontset);
-+    FcPatternGetString (fcfont, FC_FILE, 0, &font_file);
-+    FT_New_Face (m_ftlibrary, (const gchar *) font_file, 0, &ft_face);
-+    FT_Set_Pixel_Sizes (ft_face, size, size);
-+    return ft_face;
-+}
-+
-+static void
-+_cairo_show_unknown_glyphs (cairo_t             *cr,
-+                            const cairo_glyph_t *glyphs,
-+                            guint                num_glyphs,
-+                            guint                width,
-+                            guint                height)
-+{
-+    gunichar ch;
-+    gboolean invalid_input;
-+    int rows = 2;
-+    int cols;
-+    int row, col;
-+    char buf[7];
-+    double cx = 0.;
-+    double cy;
-+    const double box_descent = 3.;
-+    double x0;
-+    double y0;
-+    const double digit_width = 5.;
-+    const double digit_height= 6.;
-+    char hexbox_string[2] = {0, 0};
-+
-+    g_assert (glyphs != NULL);
-+    g_assert (num_glyphs > 0);
-+
-+    ch = glyphs[0].index & ~PANGO_GLYPH_UNKNOWN_FLAG;
-+    invalid_input = G_UNLIKELY (glyphs[0].index == PANGO_GLYPH_INVALID_INPUT ||
-+                                ch > 0x10FFFF);
-+    if (G_UNLIKELY (invalid_input)) {
-+      g_warning ("Unsupported U+%06X",  ch);
-+      return;
-+    }
-+
-+    cairo_save (cr);
-+
-+    cols = (ch > 0xffff ? 6 : 4) / rows;
-+    g_snprintf (buf, sizeof(buf), (ch > 0xffff) ? "%06X" : "%04X", ch);
-+    cy = (double) height;
-+    x0 = cx + box_descent + XPAD / 2;
-+    y0 = cy - box_descent - YPAD / 2;
-+
-+    for (row = 0; row < rows; row++) {
-+        double y = y0 - (rows - 1 - row) * (digit_height + YPAD);
-+        for (col = 0; col < cols; col++) {
-+            double x = x0 + col * (digit_width + XPAD);
-+            cairo_move_to (cr, x, y);
-+            hexbox_string[0] = buf[row * cols + col];
-+            cairo_show_text (cr, hexbox_string);
-+        }
-+    }
-+    cairo_move_to (cr, XPAD, YPAD);
-+    cairo_line_to (cr, width - XPAD, YPAD);
-+    cairo_line_to (cr, width - XPAD,
-+                       height - YPAD);
-+    cairo_line_to (cr, XPAD, height - YPAD);
-+    cairo_line_to (cr, XPAD, YPAD);
-+    cairo_set_line_width (cr, 1.);
-+    cairo_stroke (cr);
-+
-+    cairo_restore (cr);
-+}
-+
-+static void
-+ibus_fcfontset_destroy_ex (FcFontSetEx *fcfontset_ex)
-+{
-+    FcFontSet *fcfontset = NULL;
-+    int i;
-+
-+    g_return_if_fail (fcfontset_ex != NULL);
-+
-+    for (i = 0; i < fcfontset_ex->nfont; i++)
-+        FT_Done_Face (fcfontset_ex->ft_faces[i]);
-+    fcfontset = FcFontSetCreate ();
-+    fcfontset->nfont = fcfontset_ex->nfont;
-+    fcfontset->sfont = fcfontset_ex->sfont;
-+    fcfontset->fonts = fcfontset_ex->fonts;
-+    FcFontSetDestroy (fcfontset);
-+    g_free (fcfontset_ex->ft_faces);
-+    g_free (fcfontset_ex);
-+}
-+
-+IBusCairoLine *
-+ibus_cairo_line_copy (IBusCairoLine *cairo_lines)
-+{
-+    IBusCairoLine *ret;
-+    guint n, i, j, num_glyphs;
-+    if (!cairo_lines)
-+        return NULL;
-+
-+    for (n = 0; cairo_lines[n].scaled_font; n++);
-+    ret = g_new0 (IBusCairoLine, n + 1);
-+    for (i = 0; i < n; i++) {
-+        ret[i].scaled_font = cairo_lines[i].scaled_font;
-+        num_glyphs = cairo_lines[i].num_glyphs;
-+        ret[i].num_glyphs = num_glyphs;
-+        ret[i].glyphs = (IBusGlyph *) cairo_glyph_allocate (num_glyphs + 1);
-+        for (j = 0; j < num_glyphs; j++) {
-+            ret[i].glyphs[j] = cairo_lines[i].glyphs[j];
-+        }
-+        ret[i].glyphs[j].index = -1;
-+        ret[i].glyphs[j].x = 0;
-+        ret[i].glyphs[j].y = 0;
-+    }
-+    ret[i].scaled_font = NULL;
-+    ret[i].num_glyphs = 0;
-+    ret[i].glyphs = NULL;
-+    return ret;
-+}
-+
-+void
-+ibus_cairo_line_free (IBusCairoLine *cairo_lines)
-+{
-+    guint i;
-+    if (!cairo_lines)
-+        return;
-+    for (i = 0; cairo_lines[i].scaled_font; i++) {
-+        g_free (cairo_lines[i].glyphs);
-+    }
-+    g_free (cairo_lines);
-+}
-+
-+IBusRequisitionEx *
-+ibus_requisition_ex_copy (IBusRequisitionEx *req)
-+{
-+    IBusRequisitionEx *ret;
-+    if (!req)
-+        return NULL;
-+    ret = g_new0 (IBusRequisitionEx, 1);
-+    ret->width = req->width;
-+    ret->height = req->height;
-+    ret->cairo_lines = ibus_cairo_line_copy (req->cairo_lines);
-+    return ret;
-+}
-+
-+void
-+ibus_requisition_ex_free (IBusRequisitionEx *req)
-+{
-+    if (!req)
-+        return;
-+    g_clear_pointer (&req->cairo_lines, ibus_cairo_line_free);
-+    g_free (req);
-+}
-+
-+IBusFontSet *
-+ibus_fontset_new (const gchar *first_property_name, ...)
-+{
-+    va_list var_args;
-+    IBusFontSet *fontset;
-+
-+    g_assert (first_property_name);
-+
-+    va_start (var_args, first_property_name);
-+    fontset = (IBusFontSet *)g_object_new_valist (IBUS_TYPE_FONTSET,
-+                                                  first_property_name,
-+                                                  var_args);
-+    va_end (var_args);
-+    g_assert (fontset->priv->family);
-+    g_assert (fontset->priv->language);
-+    return fontset;
-+}
-+
-+IBusFontSet *
-+ibus_fontset_new_with_font (const gchar *family,
-+                            guint        size,
-+                            const gchar *language)
-+{
-+    return ibus_fontset_new ("family", family,
-+                             "size", size,
-+                             "language", language,
-+                             NULL);
-+}
-+
-+void
-+ibus_fontset_exit ()
-+{
-+    g_clear_pointer (&m_ftlibrary, FT_Done_FreeType);
-+}
-+
-+const gchar *
-+ibus_fontset_get_family (IBusFontSet *fontset)
-+{
-+    g_return_val_if_fail (IBUS_IS_FONTSET (fontset), NULL);
-+    return fontset->priv->family;
-+}
-+
-+void
-+ibus_fontset_set_family (IBusFontSet *fontset,
-+                         const gchar   *family)
-+{
-+    g_return_if_fail (IBUS_IS_FONTSET (fontset));
-+    g_free (fontset->priv->family);
-+    fontset->priv->family = g_strdup (family);
-+}
-+
-+guint
-+ibus_fontset_get_size (IBusFontSet *fontset)
-+{
-+    g_return_val_if_fail (IBUS_IS_FONTSET (fontset), 0);
-+    return fontset->priv->size;
-+}
-+
-+void
-+ibus_fontset_set_size (IBusFontSet *fontset,
-+                       guint          size)
-+{
-+    g_return_if_fail (IBUS_IS_FONTSET (fontset));
-+    fontset->priv->size = size;
-+}
-+
-+const gchar *
-+ibus_fontset_get_language (IBusFontSet *fontset)
-+{
-+    g_return_val_if_fail (IBUS_IS_FONTSET (fontset), NULL);
-+    return fontset->priv->language;
-+}
-+
-+void
-+ibus_fontset_set_language (IBusFontSet *fontset,
-+                           const gchar *language)
-+{
-+    g_return_if_fail (IBUS_IS_FONTSET (fontset));
-+    g_free (fontset->priv->language);
-+    fontset->priv->language = g_strdup (language);
-+}
-+
-+gboolean
-+ibus_fontset_update_fcfontset (IBusFontSet *fontset)
-+{
-+    FcPattern *pattern;
-+    const gchar *family;
-+    guint size;
-+    const gchar *language;
-+    gboolean update_fontset = FALSE;
-+    FcFontSet *fcfontset = NULL;
-+    FcResult result;
-+
-+    g_return_val_if_fail (IBUS_IS_FONTSET (fontset), FALSE);
-+
-+    pattern = FcPatternCreate ();
-+    family = fontset->priv->family;
-+    size = fontset->priv->size;
-+    language = fontset->priv->language;
-+
-+    if (g_strcmp0 (m_family, family)) {
-+        g_free (m_family);
-+        m_family = g_strdup (family);
-+        update_fontset = TRUE;
-+    }
-+    if (m_size != size) {
-+        m_size = size;
-+        update_fontset = TRUE;
-+    }
-+    if (g_strcmp0 (m_language, language)) {
-+        g_free (m_language);
-+        m_language = g_strdup (language);
-+        update_fontset = TRUE;
-+    }
-+    if (!update_fontset && m_fcfontset != NULL)
-+        return FALSE;
-+
-+    if (m_font_index_per_char_table)
-+        g_hash_table_destroy (m_font_index_per_char_table);
-+    if (m_fcfontset)
-+        g_clear_pointer (&m_fcfontset, ibus_fcfontset_destroy_ex);
-+
-+    m_font_index_per_char_table = g_hash_table_new (g_direct_hash,
-+                                                    g_direct_equal);
-+    if (g_strcmp0 (family, ""))
-+        FcPatternAddString (pattern, FC_FAMILY, (const FcChar8*) family);
-+    if (size > 0)
-+        FcPatternAddDouble (pattern, FC_SIZE, (double) size);
-+    if (g_strcmp0 (language, ""))
-+        FcPatternAddString (pattern, FC_LANG, (const FcChar8*) language);
-+    FcPatternAddInteger (pattern, FC_WEIGHT, FC_WEIGHT_NORMAL);
-+    FcPatternAddInteger (pattern, FC_WIDTH, FC_WIDTH_NORMAL);
-+    FcPatternAddInteger (pattern, FC_DPI, 96);
-+#if FC_VERSION >=  21205
-+    if (m_color_supported &&
-+        (!g_ascii_strncasecmp (family, MONOSPACE, strlen (MONOSPACE)) ||
-+         !g_ascii_strncasecmp (family, SERIF, strlen (SERIF)) ||
-+         !g_ascii_strncasecmp (family, SANS, strlen (SANS)))) {
-+        FcPatternAddBool (pattern, FC_COLOR, TRUE);
-+    }
-+#endif
-+    FcConfigSubstitute (NULL, pattern, FcMatchPattern);
-+    FcConfigSubstitute (NULL, pattern, FcMatchFont);
-+    FcDefaultSubstitute (pattern);
-+    fcfontset = FcFontSort (NULL, pattern, FcTrue, NULL, &result);
-+    FcPatternDestroy (pattern);
-+    if (result == FcResultNoMatch || fcfontset->nfont == 0) {
-+        g_warning ("No FcFontSet for %s", family ? family : "(null)");
-+        return FALSE;
-+    }
-+    m_fcfontset = g_new0 (FcFontSetEx, 1);
-+    m_fcfontset->nfont = fcfontset->nfont;
-+    m_fcfontset->sfont = fcfontset->sfont;
-+    m_fcfontset->fonts = fcfontset->fonts;
-+    m_fcfontset->ft_faces = g_new0 (FT_Face, fcfontset->nfont);
-+    fcfontset->nfont = 0;
-+    fcfontset->sfont = 0;
-+    fcfontset->fonts = NULL;
-+    FcFontSetDestroy (fcfontset);
-+    return TRUE;
-+}
-+
-+void
-+ibus_fontset_unref (IBusFontSet *fontset)
-+{
-+    g_object_unref (fontset);
-+}
-+
-+IBusRequisitionEx *
-+ibus_fontset_get_preferred_size_hb (IBusFontSet          *fontset,
-+                                    const gchar           *text,
-+                                    cairo_rectangle_int_t *widest)
-+{
-+    gchar *copied_text;
-+    gchar *p;
-+    FontPerChar *buff;
-+    IBusCairoLine *cairo_lines = NULL;
-+    IBusRequisitionEx *req = NULL;
-+    GString *str = NULL;
-+    int text_length;
-+    int i, n = 0;
-+
-+    g_return_val_if_fail (IBUS_IS_FONTSET (fontset), NULL);
-+    g_return_val_if_fail (m_fcfontset != NULL, NULL);
-+
-+    copied_text = g_strdup (text);
-+    text_length =  g_utf8_strlen (text, -1);
-+    buff = g_slice_alloc0 (sizeof (FontPerChar) * text_length);
-+    str = g_string_new (NULL);
-+
-+    for (p = copied_text; *p != '\0'; p = g_utf8_next_char (p)) {
-+        gunichar c = g_utf8_get_char (p);
-+        gboolean has_glyphs = FALSE;
-+        buff[n].ch = c;
-+        if ((c == 0xfe0eu || c == 0xfe0fu) && n > 0) {
-+            buff[n].fcfont = buff[n-1].fcfont;
-+            ++n;
-+            continue;
-+        }
-+        i = GPOINTER_TO_INT (g_hash_table_lookup (m_font_index_per_char_table,
-+                                                  GINT_TO_POINTER (c)));
-+        if (i > 0) {
-+            i--;
-+            if (i >= m_fcfontset->nfont) {
-+                g_warning ("i:%d >= m_fcfontset->nfont:%d",
-+                           i, m_fcfontset->nfont);
-+            } else {
-+                buff[n].fcfont = m_fcfontset->fonts[i];
-+                has_glyphs = TRUE;
-+            }
-+        }
-+        for (; i < m_fcfontset->nfont; i++) {
-+            if (!has_glyphs && g_unichar_iscntrl (c) && !g_unichar_isspace (c))
-+                break;
-+            FT_Face ft_face = m_fcfontset->ft_faces[i];
-+            if (!has_glyphs && ft_face == 0) {
-+               ft_face = ibus_fontset_get_ftface_from_fcfont (
-+                       fontset,
-+                       m_fcfontset->fonts[i]);
-+               m_fcfontset->ft_faces[i] = ft_face;
-+            }
-+            if (has_glyphs || FT_Get_Char_Index (ft_face, c) != 0) {
-+                FcChar8 *font_file = NULL;
-+                FcPatternGetString (m_fcfontset->fonts[i], FC_FILE, 0, &font_file);
-+                buff[n].fcfont = m_fcfontset->fonts[i];
-+                if (!has_glyphs) {
-+                    g_hash_table_insert (m_font_index_per_char_table,
-+                                         GINT_TO_POINTER (c),
-+                                         GINT_TO_POINTER (i + 1));
-+                }
-+                if (n > 0 && buff[n - 1].fcfont != buff[n].fcfont) {
-+                    get_string_extents_with_font (str->str,
-+                                                  &buff[n - 1],
-+                                                  widest,
-+                                                  &cairo_lines);
-+                    g_string_free (str, TRUE);
-+                    str = g_string_new (NULL);
-+                    g_string_append_unichar (str, c);
-+                } else {
-+                    g_string_append_unichar (str, c);
-+                }
-+                ++n;
-+                has_glyphs = TRUE;
-+                break;
-+            }
-+        }
-+        if (!has_glyphs) {
-+            if (n > 0) {
-+                buff[n].fcfont = buff[n - 1].fcfont;
-+            } else {
-+                /* Search a font for non-glyph char to draw the code points
-+                 * likes Pango.
-+                 */
-+                for (i = 0; i < m_fcfontset->nfont; i++) {
-+                    FT_Face ft_face = m_fcfontset->ft_faces[i];
-+                    if (ft_face == 0) {
-+                        ft_face = ibus_fontset_get_ftface_from_fcfont (
-+                                fontset,
-+                                m_fcfontset->fonts[i]);
-+                        m_fcfontset->ft_faces[i] = ft_face;
-+                    }
-+                    /* Check alphabets instead of space or digits
-+                     * because 'Noto Emoji Color' font's digits are
-+                     * white color and cannot change the font color.
-+                     * the font does not have alphabets.
-+                     */
-+                    if (FT_Get_Char_Index (ft_face, 'A') != 0) {
-+                        FcChar8 *font_file = NULL;
-+                        FcPatternGetString (m_fcfontset->fonts[i], FC_FILE, 0, &font_file);
-+                        buff[n].fcfont = m_fcfontset->fonts[i];
-+                        g_hash_table_insert (m_font_index_per_char_table,
-+                                             GINT_TO_POINTER (c),
-+                                             GINT_TO_POINTER (i + 1));
-+                        has_glyphs = TRUE;
-+                        break;
-+                    }
-+                }
-+                if (!has_glyphs) {
-+                    buff[n].fcfont = m_fcfontset->fonts[0];
-+                    g_hash_table_insert (m_font_index_per_char_table,
-+                                         GINT_TO_POINTER (c),
-+                                         GINT_TO_POINTER (1));
-+                    g_warning ("Not found fonts for unicode %04X at %d in %s",
-+                               c, n, text);
-+                }
-+            }
-+            n++;
-+            g_string_append_unichar (str, c);
-+        }
-+    }
-+    if (str->str) {
-+        get_string_extents_with_font (str->str,
-+                                      &buff[n - 1],
-+                                      widest,
-+                                      &cairo_lines);
-+        g_string_free (str, TRUE);
-+    }
-+    g_slice_free1 (sizeof (FontPerChar) * text_length, buff);
-+    g_free (copied_text);
-+    widest->width += XPAD * 2;
-+    widest->height += YPAD * 2;
-+    req = g_new0 (IBusRequisitionEx, 1);
-+    req->width = widest->width;
-+    req->height = widest->height;
-+    req->cairo_lines = cairo_lines;
-+    return req;
-+}
-+
-+void
-+ibus_fontset_draw_cairo_with_requisition_ex (IBusFontSet       *fontset,
-+                                             cairo_t           *cr,
-+                                             IBusRequisitionEx *ex)
-+{
-+    IBusCairoLine *cairo_lines;
-+    int i;
-+
-+    g_return_if_fail (IBUS_IS_FONTSET (fontset));
-+    g_return_if_fail (cr != NULL);
-+    g_return_if_fail (ex != NULL);
-+
-+    cairo_lines = ex->cairo_lines;
-+    g_return_if_fail (cairo_lines != NULL);
-+
-+    for (i = 0; cairo_lines[i].scaled_font; i++) {
-+        const cairo_glyph_t *glyphs = (cairo_glyph_t *) cairo_lines[i].glyphs;
-+        guint num_glyphs = cairo_lines[i].num_glyphs;
-+
-+        cairo_ft_scaled_font_lock_face (cairo_lines[i].scaled_font);
-+        cairo_set_scaled_font (cr, cairo_lines[i].scaled_font);
-+        if (num_glyphs > 0 && glyphs[0].index & PANGO_GLYPH_UNKNOWN_FLAG) {
-+            _cairo_show_unknown_glyphs (cr, glyphs, num_glyphs,
-+                                        ex->width, ex->height);
-+        } else {
-+            cairo_show_glyphs (cr, glyphs, num_glyphs);
-+        }
-+        cairo_ft_scaled_font_unlock_face (cairo_lines[i].scaled_font);
-+    }
-+}
-diff --git a/ui/gtk3/ibusfontset.h b/ui/gtk3/ibusfontset.h
-new file mode 100644
-index 00000000..efcaa286
---- /dev/null
-+++ b/ui/gtk3/ibusfontset.h
-@@ -0,0 +1,302 @@
-+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
-+/* vim:set et sts=4: */
-+/* ibus - The Input Bus
-+ * Copyright (C) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2017 Red Hat, Inc.
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
-+ * USA
-+ */
-+
-+#ifndef __IBUS_HARFBUZZ_H_
-+#define __IBUS_HARFBUZZ_H_
-+
-+/**
-+ * SECTION: ibusfontset
-+ * @short_description: Object for HarfBuzz and Fontconfig.
-+ * @title: IBusFontSet
-+ * @stability: Unstable
-+ *
-+ * IBusFontSet offers FcFontSet, glyph info with HarfBuzz and rendering
-+ * on Cairo context.
-+ * Current Pango changes fonts by emoji variants and draws the separated
-+ * glyphs [1] but actually the emoji characters with variants can be drawn
-+ * as one glyph so this class  manages Fontconfig fontsets to select a font,
-+ * HarfBuzz to get glyphs for emoji variants, Cairo to draw glyphs.
-+ *
-+ * [1]: https://bugzilla.gnome.org/show_bug.cgi?id=780669
-+ *      https://bugzilla.gnome.org/show_bug.cgi?id=781123
-+ */
-+
-+#include <ibus.h>
-+#include <cairo.h>
-+
-+#define IBUS_TYPE_CAIRO_LINE (ibus_cairo_line_get_type ())
-+#define IBUS_TYPE_REQUISITION_EX (ibus_requisition_ex_get_type ())
-+#define IBUS_TYPE_FONTSET (ibus_fontset_get_type ())
-+#define IBUS_FONTSET(obj) (G_TYPE_CHECK_INSTANCE_CAST (\
-+        (obj), \
-+        IBUS_TYPE_FONTSET, \
-+        IBusFontSet))
-+#define IBUS_FONTSET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (\
-+        (klass), \
-+        IBUS_TYPE_FONTSET, \
-+        IBusFontSetClass))
-+#define IBUS_IS_FONTSET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (\
-+        (obj), \
-+        IBUS_TYPE_FONTSET))
-+#define IBUS_IS_FONTSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE (\
-+        (klass), \
-+        IBUS_TYPE_FONTSET))
-+#define IBUS_FONTSET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS (\
-+        (obj), \
-+        IBUS_TYPE_FONTSET, \
-+        IBusFontSetClass))
-+
-+G_BEGIN_DECLS
-+
-+typedef struct _IBusGlyph IBusGlyph;
-+typedef struct _IBusCairoLine IBusCairoLine;
-+typedef struct _IBusRequisitionEx IBusRequisitionEx;
-+typedef struct _IBusFontSet IBusFontSet;
-+typedef struct _IBusFontSetPrivate IBusFontSetPrivate;
-+typedef struct _IBusFontSetClass IBusFontSetClass;
-+
-+struct _IBusGlyph {
-+    unsigned long index;
-+    double               x;
-+    double               y;
-+};
-+
-+struct _IBusCairoLine {
-+    IBusGlyph           *glyphs;
-+    guint                num_glyphs;
-+    cairo_scaled_font_t *scaled_font;
-+    gpointer             pdummy[5];
-+};
-+
-+struct _IBusRequisitionEx {
-+    guint                width;
-+    guint                height;
-+    IBusCairoLine       *cairo_lines;
-+    gpointer             pdummy[5];
-+};
-+
-+struct _IBusFontSet {
-+    IBusObject           parent_instance;
-+    IBusFontSetPrivate  *priv;
-+};
-+
-+struct _IBusFontSetClass {
-+    IBusObjectClass parent_class;
-+    /* signals */
-+    /*< private >*/
-+    /* padding */
-+    gpointer        pdummy[10];
-+};
-+
-+GType           ibus_cairo_line_get_type        (void) G_GNUC_CONST;
-+
-+/**
-+ * ibus_cairo_line_copy:
-+ * @cairo_lines: #IBusCairoLine
-+ *
-+ * Creates a copy of @cairo_liens, which should be freed with
-+ * ibus_cairo_line_free(). Primarily used by language bindings,
-+ * not that useful otherwise (since @req can just be copied
-+ * by assignment in C).
-+ *
-+ * Returns: the newly allocated #IBusCairoLine, which should
-+ *          be freed with ibus_cairo_line_free(), or %NULL
-+ *          if @cairo_lines was %NULL.
-+ **/
-+IBusCairoLine * ibus_cairo_line_copy            (IBusCairoLine *cairo_lines);
-+
-+/**
-+ * ibus_cairo_line_free:
-+ * @cairo_lines: #IBusCairoLine
-+ *
-+ * Free an #IBusCairoLine.
-+ */
-+void            ibus_cairo_line_free            (IBusCairoLine *cairo_lines);
-+
-+
-+GType           ibus_requisition_ex_get_type    (void) G_GNUC_CONST;
-+
-+/**
-+ * ibus_requisition_ex_copy:
-+ * @req: #IBusRequisitionEx
-+ *
-+ * Creates a copy of @req, which should be freed with
-+ * ibus_requisition_ex_free(). Primarily used by language bindings,
-+ * not that useful otherwise (since @req can just be copied
-+ * by assignment in C).
-+ *
-+ * Returns: the newly allocated #IBusRequisitionEx, which should
-+ *          be freed with ibus_requisition_ex_free(), or %NULL
-+ *          if @req was %NULL.
-+ **/
-+IBusRequisitionEx *
-+                ibus_requisition_ex_copy        (IBusRequisitionEx *req);
-+
-+/**
-+ * ibus_requisition_ex_free:
-+ * @req: #IBusRequisitionEx
-+ *
-+ * Free an #IBusRequisitionEx.
-+ */
-+void            ibus_requisition_ex_free        (IBusRequisitionEx *req);
-+
-+
-+GType           ibus_fontset_get_type           (void);
-+
-+/**
-+ * ibus_fontset_new:
-+ * @first_property_name: 
-+ *
-+ * Creates a new #IBusFcFontSet.
-+ *
-+ * Returns: (transfer full): A newly allocated #IBusFontSet and includes
-+ * #FcFontSet internally. E.g. ibus_fontset_new ("family",
-+ * "Noto Emoji Color", "size", 16, "language", "ja-jp");
-+ */
-+IBusFontSet *   ibus_fontset_new                (const gchar
-+                                                           *first_property_name,
-+                                                                 ...);
-+
-+/**
-+ * ibus_fontset_new_with_font:
-+ * @family: font family
-+ * @size: font size
-+ * @language: font language
-+ *
-+ * Creates  a new #IBusFcFontSet.
-+ *
-+ * Returns: (transfer full): A newly allocated #IBusFcFontSet and includes
-+ * #FcFontSet internally.
-+ */
-+IBusFontSet *   ibus_fontset_new_with_font      (const gchar    *family,
-+                                                 guint           size,
-+                                                 const gchar    *language);
-+/**
-+ * ibus_fontset_get_family:
-+ * @fontset: #IBusFcFontSet
-+ *
-+ * Return the base font family of #FcFontSet
-+ *
-+ * Returns: Base font family of #FcFontSet
-+ */
-+const gchar *   ibus_fontset_get_family         (IBusFontSet    *fontset);
-+
-+/**
-+ * ibus_fontset_set_family:
-+ * @fontset: #IBusFcFontSet
-+ * @family: base font family for #FcFontSet
-+ *
-+ * Set the base font family for #FcFontSet
-+ */
-+void            ibus_fontset_set_family         (IBusFontSet    *fontset,
-+                                                 const gchar    *family);
-+/**
-+ * ibus_fontset_get_size:
-+ * @fontset: #IBusFcFontSet
-+ *
-+ * Return the font size of #FcFontSet
-+ *
-+ * Returns: Font size of #FcFontSet
-+ */
-+guint           ibus_fontset_get_size           (IBusFontSet    *fontset);
-+
-+/**
-+ * ibus_fontset_set_size:
-+ * @fontset: #IBusFcFontSet
-+ * @size: font size for #FcFontSet
-+ *
-+ * Set the font size for #FcFontSet
-+ */
-+void            ibus_fontset_set_size           (IBusFontSet    *fontset,
-+                                                 guint           size);
-+/**
-+ * ibus_fontset_get_language:
-+ * @fontset: #IBusFcFontSet
-+ *
-+ * Return the font language of #FcFontSet
-+ *
-+ * Returns: Font language of #FcFontSet
-+ */
-+const gchar *   ibus_fontset_get_language       (IBusFontSet    *fontset);
-+
-+/**
-+ * ibus_fontset_set_language:
-+ * @fontset: #IBusFcFontSet
-+ * @language: font langauge for #FcFontSet
-+ *
-+ * Set the font language for #FcFontSet
-+ */
-+void            ibus_fontset_set_language       (IBusFontSet    *fontset,
-+                                                 const gchar    *language);
-+
-+/**
-+ * ibus_fontset_update_fcfontset:
-+ * @fontset: #IBusFcFontSet
-+ *
-+ * Update #FcFontSet from font family, size and langauge of @fontset.
-+ * Returns: %TRUE if #FcFontSet is updated. %FALSE otherwise.
-+ */
-+gboolean        ibus_fontset_update_fcfontset   (IBusFontSet    *fontset);
-+
-+/**
-+ * ibus_fontset_get_preferred_size_hb:
-+ * @fontset: #IBusFcFontSet
-+ * @text: a string to be calculate the preferred rectangle size.
-+ * @widest: (out): #cairo_rectangle_int_t is updated.
-+ *
-+ * Calculate @widest for @text.
-+ *
-+ * Returns: #IBusRequisitionEx which includes the glyphs and coordinates.
-+ */
-+IBusRequisitionEx *
-+                ibus_fontset_get_preferred_size_hb
-+                                                (IBusFontSet    *fontset,
-+                                                 const gchar    *text,
-+                                                 cairo_rectangle_int_t
-+                                                                *widest);
-+
-+/**
-+ * ibus_fontset_draw_cairo_lines:
-+ * @fontset: #IBusFcFontSet
-+ * @cr: #cairo_t in #GtkWidget.draw().
-+ * @ex: #IBusRequisitionEx which includes glyph, x, y values, char width
-+ *      and height.
-+ *
-+ * Draw glyphs in @ex using cairo @cr.
-+ */
-+void            ibus_fontset_draw_cairo_with_requisition_ex
-+                                                (IBusFontSet    *fontset,
-+                                                 cairo_t        *cr,
-+                                                 IBusRequisitionEx
-+                                                                *ex);
-+
-+/**
-+ * ibus_fontset_unref:
-+ * @fontset: #IBusFcFontSet
-+ *
-+ * Call g_object_unref().
-+ * FIXME: Seems Vala needs this API.
-+ */
-+void            ibus_fontset_unref              (IBusFontSet    *fontset);
-+
-+G_END_DECLS
-+#endif
--- 
-2.14.3
-

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-31  2:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-31  2:06 [rpms/ibus] autotool: Delete ibus-xx-emoji-harfbuzz.patch Takao Fujiwara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox