[pango/pango2] Redo the cairo font code




commit 6a21d3456ee61b0b1adb8f1ce8b30c3772fcc0d7
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Jun 27 07:20:13 2022 -0400

    Redo the cairo font code
    
    It turns out that the harfbuzz code that gives us
    native font objects is questionable, so instead
    use cairo-ft on all platforms.
    
    We still use native font enumeration APIs and
    the harfbuzz support for creating hb objects from
    native font objects.

 meson.build                       |  8 +---
 pango2/meson.build                | 12 -----
 pango2/pangocairo-coretext-font.c | 51 --------------------
 pango2/pangocairo-dwrite-font.cpp | 51 --------------------
 pango2/pangocairo-font.c          | 22 +--------
 pango2/pangocairo-ft-font.c       | 99 ++++++++++++++++++++++++++++++++++++++-
 pango2/pangocairo-private.h       | 12 -----
 7 files changed, 100 insertions(+), 155 deletions(-)
---
diff --git a/meson.build b/meson.build
index 24a220b6e..217f5ae8a 100644
--- a/meson.build
+++ b/meson.build
@@ -297,8 +297,6 @@ else
   fontconfig_dep = disabler()
 endif
 
-cairo_pkg = 'cairo-ft'
-
 if host_system == 'darwin'
   if not cc.links('''#include <CoreText/CoreText.h>
                               int main (void) {
@@ -313,8 +311,6 @@ if host_system == 'darwin'
   pango_conf.set('HAVE_CORE_TEXT', 1)
 
   pango_deps += dependency('appleframeworks', modules: [ 'CoreFoundation', 'ApplicationServices' ])
-
-  cairo_pkg = 'cairo-quartz-font'
 endif
 
 if host_system == 'windows'
@@ -324,8 +320,6 @@ if host_system == 'windows'
     cc.find_library('gdi32'),
     cc.find_library('dwrite'),
   ]
-
-  cairo_pkg = 'cairo-win32-dwrite-font'
 endif
 
 if get_option('cairo').disabled()
@@ -333,7 +327,7 @@ if get_option('cairo').disabled()
   cairo_xlib_dep = disabler()
   cairo_ft_dep = disabler()
 else
-  cairo_dep = dependency(cairo_pkg, version: cairo_req_version,
+  cairo_dep = dependency('cairo-ft', version: cairo_req_version,
                          fallback: ['cairo', 'libcairo_dep'], required: get_option('cairo'))
   cairo_xlib_dep = dependency('cairo-xlib', required: false)
   cairo_ft_dep = dependency('cairo-ft', required: false)
diff --git a/pango2/meson.build b/pango2/meson.build
index 0a3e8d323..fd49884e6 100644
--- a/pango2/meson.build
+++ b/pango2/meson.build
@@ -154,12 +154,6 @@ if host_system == 'darwin'
     'pangocoretext-fontmap.c',
   ]
 
-  if cairo_dep.found()
-    pango_sources += [
-      'pangocairo-coretext-font.c',
-    ]
-  endif
-
   pango_features_conf.set('PANGO2_HAS_CORE_TEXT_FONTMAP', 1)
 endif
 
@@ -172,12 +166,6 @@ if host_system == 'windows'
     'pangodwrite-fontmap.cpp',
   ]
 
-  if cairo_dep.found()
-    pango_sources += [
-      'pangocairo-dwrite-font.cpp',
-    ]
-  endif
-
   pango_features_conf.set('PANGO2_HAS_DIRECT_WRITE_FONTMAP', 1)
 endif
 
diff --git a/pango2/pangocairo-font.c b/pango2/pangocairo-font.c
index b9103d977..156df3f13 100644
--- a/pango2/pangocairo-font.c
+++ b/pango2/pangocairo-font.c
@@ -66,30 +66,10 @@ _pango2_cairo_font_private_scaled_font_data_destroy (Pango2CairoFontPrivateScale
 static cairo_font_face_t *
 create_cairo_font_face (Pango2Font *font)
 {
-  cairo_font_face_t *cairo_face;
-
   if (PANGO2_IS_USER_FONT (font))
     return create_cairo_user_font_face (font);
 
-#ifdef HAVE_CORE_TEXT
-  cairo_face = create_cairo_core_text_font_face (font);
-  if (cairo_face)
-    return cairo_face;
-#endif
-
-#ifdef HAVE_DIRECT_WRITE
-  cairo_face = create_cairo_dwrite_font_face (font);
-  if (cairo_face)
-    return cairo_face;
-#endif
-
-#ifdef CAIRO_HAS_FT_FONT
-  cairo_face = create_cairo_ft_font_face (font);
-  if (cairo_face)
-    return cairo_face;
-#endif
-
-  return NULL;
+  return create_cairo_ft_font_face (font);
 }
 
 static cairo_scaled_font_t *
diff --git a/pango2/pangocairo-ft-font.c b/pango2/pangocairo-ft-font.c
index f8595ac0b..8083193eb 100644
--- a/pango2/pangocairo-ft-font.c
+++ b/pango2/pangocairo-ft-font.c
@@ -32,6 +32,101 @@
 #include <cairo-ft.h>
 #include <freetype/ftmm.h>
 
+/* Get the font data as a blob. Either, the hb_face_t was
+ * created from a blob to begin with, or we receate one using
+ * hb_face_builder_create(). Unfortunately we can't rely on
+ * hb_face_get_table_tags(), so we just have to list all possible
+ * OpenType tables here and try them all.
+ *
+ * This is not ideal from a memory perspective, but cairo does
+ * not have a scaled font implementation that takes individual
+ * tables.
+ */
+static hb_blob_t *
+face_get_blob (hb_face_t *face)
+{
+  hb_blob_t *blob;
+  hb_face_t *builder;
+  hb_tag_t tables[] = {
+    HB_TAG ('a','v','a','r'),
+    HB_TAG ('B','A','S','E'),
+    HB_TAG ('C','B','D','T'),
+    HB_TAG ('C','B','L','C'),
+    HB_TAG ('C','F','F',' '),
+    HB_TAG ('C','F','F','2'),
+    HB_TAG ('c','m','a','p'),
+    HB_TAG ('C','O','L','R'),
+    HB_TAG ('C','P','A','L'),
+    HB_TAG ('c','v','a','r'),
+    HB_TAG ('c','v','t',' '),
+    HB_TAG ('D','S','I','G'),
+    HB_TAG ('E','B','D','T'),
+    HB_TAG ('E','B','L','C'),
+    HB_TAG ('E','B','S','C'),
+    HB_TAG ('f','p','g','m'),
+    HB_TAG ('f','v','a','r'),
+    HB_TAG ('g','a','s','p'),
+    HB_TAG ('G','D','E','F'),
+    HB_TAG ('g','l','y','f'),
+    HB_TAG ('G','P','O','S'),
+    HB_TAG ('G','S','U','B'),
+    HB_TAG ('g','v','a','r'),
+    HB_TAG ('h','d','m','x'),
+    HB_TAG ('h','e','a','d'),
+    HB_TAG ('h','h','e','a'),
+    HB_TAG ('h','m','t','x'),
+    HB_TAG ('H','V','A','R'),
+    HB_TAG ('J','S','T','F'),
+    HB_TAG ('k','e','r','n'),
+    HB_TAG ('l','o','c','a'),
+    HB_TAG ('L','T','S','H'),
+    HB_TAG ('M','A','T','H'),
+    HB_TAG ('m','a','x','p'),
+    HB_TAG ('M','E','R','G'),
+    HB_TAG ('m','e','t','a'),
+    HB_TAG ('M','V','A','R'),
+    HB_TAG ('n','a','m','e'),
+    HB_TAG ('O','S','/','2'),
+    HB_TAG ('P','C','L','T'),
+    HB_TAG ('p','o','s','t'),
+    HB_TAG ('p','r','e','p'),
+    HB_TAG ('s','b','i','x'),
+    HB_TAG ('S','T','A','T'),
+    HB_TAG ('S','V','G',' '),
+    HB_TAG ('V','D','M','X'),
+    HB_TAG ('v','h','e','a'),
+    HB_TAG ('v','m','t','x'),
+    HB_TAG ('V','O','R','G'),
+    HB_TAG ('V','V','A','R'),
+  };
+
+  blob = hb_face_reference_blob (face);
+
+  if (blob != hb_blob_get_empty ())
+    return blob;
+
+  builder = hb_face_builder_create ();
+
+  for (unsigned int i = 0; i < G_N_ELEMENTS (tables); i++)
+    {
+      hb_blob_t *table;
+
+      table = hb_face_reference_table (face, tables[i]);
+
+      if (table != hb_blob_get_empty ())
+        {
+          hb_face_builder_add_table (builder, tables[i], table);
+          hb_blob_destroy (table);
+        }
+    }
+
+  blob = hb_face_reference_blob (builder);
+
+  hb_face_destroy (builder);
+
+  return blob;
+}
+
 cairo_font_face_t *
 create_cairo_ft_font_face (Pango2Font *font)
 {
@@ -43,6 +138,7 @@ create_cairo_ft_font_face (Pango2Font *font)
   unsigned int blob_length;
   FT_Face ft_face;
   hb_font_t *hb_font;
+  hb_face_t *hbface;
   unsigned int num_coords;
   const int *coords;
   cairo_font_face_t *cairo_face;
@@ -58,7 +154,8 @@ create_cairo_ft_font_face (Pango2Font *font)
     }
 
   hb_font = pango2_font_get_hb_font (font);
-  blob = hb_face_reference_blob (hb_font_get_face (hb_font));
+  hbface = hb_font_get_face (hb_font);
+  blob = face_get_blob (hbface);
   blob_data = hb_blob_get_data (blob, &blob_length);
 
   if ((error = FT_New_Memory_Face (ft_library,
diff --git a/pango2/pangocairo-private.h b/pango2/pangocairo-private.h
index be9fa8cf9..b8339c245 100644
--- a/pango2/pangocairo-private.h
+++ b/pango2/pangocairo-private.h
@@ -69,19 +69,7 @@ const cairo_font_options_t *
 cairo_font_face_t *
 create_cairo_user_font_face (Pango2Font *font);
 
-#ifdef CAIRO_HAS_FT_FONT
 cairo_font_face_t *
 create_cairo_ft_font_face (Pango2Font *font);
-#endif
-
-#ifdef HAVE_CORE_TEXT
-cairo_font_face_t *
-create_cairo_core_text_font_face (Pango2Font *font);
-#endif
-
-#ifdef HAVE_DIRECT_WRITE
-cairo_font_face_t *
-create_cairo_dwrite_font_face (Pango2Font *font);
-#endif
 
 G_END_DECLS


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