[pango/no-more-FcFontSort] Use FcFontSetMatchNext




commit 9ce5d00c801bd9b44317e81a213ad9b6fb3c1ffe
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Aug 20 01:32:23 2020 -0400

    Use FcFontSetMatchNext
    
    Instead of calling FcFontSetMatch for the first result
    and FcFontSetSort for all the rest, call the new
    FcFontSetMatchNext to produce matches as needed.
    
    FcFontSetMatchNext is roughly as fast as FcFontSetMatch.

 pango/pangofc-fontmap.c | 77 +++++++++++++++++++++++--------------------------
 1 file changed, 36 insertions(+), 41 deletions(-)
---
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 4c2aa094..f0b9ab42 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -743,8 +743,10 @@ struct _PangoFcPatterns {
   PangoFcFontMap *fontmap;
 
   FcPattern *pattern;
-  FcPattern *match;
-  FcFontSet *fontset;
+
+  FcBool *skips[2];
+  FcCharSet *cs;
+  GPtrArray *matches;
 };
 
 static PangoFcPatterns *
@@ -765,6 +767,10 @@ pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap)
   FcPatternReference (pat);
   pats->pattern = pat;
 
+  pats->matches = g_ptr_array_new_with_free_func ((GDestroyNotify)FcPatternDestroy);
+  pats->skips[0] = pats->skips[1] = NULL;
+  pats->cs = FcCharSetCreate ();
+
   g_hash_table_insert (fontmap->priv->patterns_hash,
                       pats->pattern, pats);
 
@@ -801,11 +807,12 @@ pango_fc_patterns_unref (PangoFcPatterns *pats)
   if (pats->pattern)
     FcPatternDestroy (pats->pattern);
 
-  if (pats->match)
-    FcPatternDestroy (pats->match);
+  g_ptr_array_free (pats->matches, TRUE);
 
-  if (pats->fontset)
-    FcFontSetDestroy (pats->fontset);
+  g_free (pats->skips[0]);
+  g_free (pats->skips[1]);
+
+  FcCharSetDestroy (pats->cs);
 
   g_slice_free (PangoFcPatterns, pats);
 }
@@ -843,6 +850,9 @@ filter_fontset_by_format (FcFontSet *fontset)
   FcFontSet *result;
   int i;
 
+  if (fontset == NULL)
+    return NULL;
+
   result = FcFontSetCreate ();
 
   for (i = 0; i < fontset->nfont; i++)
@@ -860,50 +870,35 @@ filter_fontset_by_format (FcFontSet *fontset)
 static FcPattern *
 pango_fc_patterns_get_font_pattern (PangoFcPatterns *pats, int i, gboolean *prepare)
 {
-  if (i == 0)
-    {
-      FcResult result;
-      if (!pats->match && !pats->fontset)
-       pats->match = FcFontMatch (pats->fontmap->priv->config, pats->pattern, &result);
+  FcFontSet *sets[2];
+  int nsets;
+  int j;
+  FcConfig *config = pats->fontmap->priv->config;
 
-      if (pats->match && pango_fc_is_supported_font_format (pats->match))
-       {
-         *prepare = FALSE;
-         return pats->match;
-       }
+  sets[0] = filter_fontset_by_format (FcConfigGetFonts (config, 0));
+  sets[1] = filter_fontset_by_format (FcConfigGetFonts (config, 1));
+  nsets = sets[1] ? 2 : (sets[0] ? 1 : 0);
+
+  for (j = 0; j < nsets; j++)
+    {
+      if (!pats->skips[j])
+        pats->skips[j] = g_malloc0 (sizeof(FcBool) * sets[j]->nfont);
     }
 
-  if (!pats->fontset)
+  while (i >= pats->matches->len)
     {
       FcResult result;
-      FcFontSet *filtered[2] = { NULL, };
-      int i, n = 0;
-
-      for (i = 0; i < 2; i++)
-        {
-          FcFontSet *fonts = FcConfigGetFonts (pats->fontmap->priv->config, i);
-          if (fonts)
-            filtered[n++] = filter_fontset_by_format (fonts);
-        }
-
-      pats->fontset = FcFontSetSort (pats->fontmap->priv->config, filtered, n, pats->pattern, FcTrue, NULL, 
&result);
-
-      for (i = 0; i < n; i++)
-        FcFontSetDestroy (filtered[i]);
+      FcPattern *best;
 
+      best = FcFontSetMatchNext (config, sets, nsets, pats->skips, pats->cs, pats->pattern, &result);
 
-      if (pats->match)
-        {
-          FcPatternDestroy (pats->match);
-          pats->match = NULL;
-        }
+      if (best)
+        g_ptr_array_add (pats->matches, best);
     }
 
-  *prepare = TRUE;
-  if (pats->fontset && i < pats->fontset->nfont)
-    return pats->fontset->fonts[i];
-  else
-    return NULL;
+  *prepare = FALSE;
+
+  return g_ptr_array_index (pats->matches, i);
 }
 
 


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