[pango/speed-up-format-filtering: 7/7] Do coverage trimming incrementally




commit f07615c33f4a9311082fb774c6e628ea86c0c8ad
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Aug 22 11:13:35 2020 -0400

    Do coverage trimming incrementally
    
    Some tradeoffs here.
    
    FcFontSetSort returns faster (5.4ms vs 6.75ms),
    but we have much bigger fontset (~ 4k fonts vs ~200),
    and we have to keep extra data around (the charset, and
    the skip table).

 pango/pangofc-fontmap.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 3 deletions(-)
---
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 5f020670..46d8f4c7 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -762,6 +762,12 @@ struct _PangoFcPatterns {
   FcPattern *pattern;
   FcPattern *match;
   FcFontSet *fontset;
+
+  int *skip; /* 0: undetermined, 1: skip: 2: include */
+
+  FcCharSet *cs; /* merged charset of the coverage of the
+                  * non-undetermined fonts.
+                  */
 };
 
 static FcFontSet *
@@ -856,7 +862,7 @@ sort_in_thread (GTask        *task,
   fontset = FcFontSetSort (td->config,
                            &td->fonts, 1,
                            td->pattern,
-                           FcTrue,
+                           FcFalse,
                            NULL,
                            &result);
 
@@ -944,6 +950,9 @@ pango_fc_patterns_unref (PangoFcPatterns *pats)
   if (pats->fontset)
     FcFontSetDestroy (pats->fontset);
 
+  g_clear_pointer (&pats->skip, g_free);
+  g_clear_pointer (&pats->cs, FcCharSetDestroy);
+
   g_cond_clear (&pats->cond);
   g_mutex_clear (&pats->mutex);
 
@@ -1062,10 +1071,40 @@ pango_fc_patterns_get_font_pattern (PangoFcPatterns *pats, int i, gboolean *prep
 
   if (fontset)
     {
-      if (i < fontset->nfont)
+      int f, k;
+
+      /* Find the i'th fontset skipping the ones that are
+       * not adding coverage.
+       */
+
+      if (!pats->skip)
+        {
+          pats->skip = g_new0 (int, fontset->nfont);
+          pats->cs = FcCharSetCreate ();
+        }
+
+      for (f = 0, k = 0; f < fontset->nfont && k < i; f++)
+        {
+          if (pats->skip[f] == 0) /* calculate whether to skip */
+            {
+              FcCharSet *fcs;
+              FcBool added = FcFalse;
+
+              FcPatternGetCharSet (fontset->fonts[f], "charset", 0, &fcs);
+
+              FcCharSetMerge (pats->cs, fcs, &added);
+
+              pats->skip[f] = added ? 2 : 1;
+            }
+
+          if (pats->skip[f] == 2) /* don't skip */
+            k++;
+        }
+
+      if (f < fontset->nfont)
         {
           *prepare = TRUE;
-          return fontset->fonts[i];
+          return fontset->fonts[f];
         }
     }
 


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