summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-08-20 01:32:23 -0400
committerMatthias Clasen <mclasen@redhat.com>2020-08-20 01:32:23 -0400
commit9ce5d00c801bd9b44317e81a213ad9b6fb3c1ffe (patch)
tree2eaab32bf2efcd87908ce02ec4219a2674e9f038
parentf26b61331403a337a4753b512df25f154891c237 (diff)
downloadpango-no-more-FcFontSort.tar.gz
Use FcFontSetMatchNextno-more-FcFontSort
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.
-rw-r--r--pango/pangofc-fontmap.c77
1 files 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);
}