From 70e59beb9862f48e08c364c48f4d93356402a162 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 11 Jul 2019 21:47:52 -0400 Subject: Turn PangoCoverage into an object Make PangoCoverage a GObject, and subclass it in pangofcfontmap.c. This lets us use the FcCharSet without copying the data. --- pango/pango-coverage-private.h | 65 ++++++++++++++++++++++ pango/pango-coverage.c | 113 ++++++++++++++++++++++--------------- pango/pangofc-fontmap.c | 123 +++++++++++++++++++++++++++-------------- 3 files changed, 215 insertions(+), 86 deletions(-) create mode 100644 pango/pango-coverage-private.h diff --git a/pango/pango-coverage-private.h b/pango/pango-coverage-private.h new file mode 100644 index 00000000..806a012b --- /dev/null +++ b/pango/pango-coverage-private.h @@ -0,0 +1,65 @@ +/* Pango + * pango-coverage-private.h: Coverage sets for fonts + * + * Copyright (C) 2000 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGO_COVERAGE_PRIVATE_H__ +#define __PANGO_COVERAGE_PRIVATE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define PANGO_TYPE_COVERAGE (pango_coverage_get_type ()) +#define PANGO_COVERAGE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_COVERAGE, PangoCoverage)) +#define PANGO_IS_COVERAGE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_COVERAGE)) +#define PANGO_COVERAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_COVERAGE, PangoCoverageClass)) +#define PANGO_IS_COVERAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_COVERAGE)) +#define PANGO_COVERAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_COVERAGE, PangoCoverageClass)) + +typedef struct _PangoCoverageClass PangoCoverageClass; +typedef struct _PangoCoveragePrivate PangoCoveragePrivate; + +struct _PangoCoverage +{ + GObject parent_instance; + + hb_set_t *chars; +}; + +struct _PangoCoverageClass +{ + GObjectClass parent_class; + + PangoCoverageLevel (* get) (PangoCoverage *coverage, + int index); + void (* set) (PangoCoverage *coverage, + int index, + PangoCoverageLevel level); + PangoCoverage * (* copy) (PangoCoverage *coverage); +}; + +PANGO_AVAILABLE_IN_ALL +GType pango_coverage_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* __PANGO_COVERAGE_PRIVATE_H__ */ diff --git a/pango/pango-coverage.c b/pango/pango-coverage.c index fa6fb731..41943720 100644 --- a/pango/pango-coverage.c +++ b/pango/pango-coverage.c @@ -32,14 +32,72 @@ #include "config.h" #include -#include "pango-coverage.h" +#include "pango-coverage-private.h" -struct _PangoCoverage +G_DEFINE_TYPE (PangoCoverage, pango_coverage, G_TYPE_OBJECT) + +static void +pango_coverage_init (PangoCoverage *coverage) +{ +} + +static void +pango_coverage_finalize (GObject *object) +{ + PangoCoverage *coverage = PANGO_COVERAGE (object); + + if (coverage->chars) + hb_set_destroy (coverage->chars); + + G_OBJECT_CLASS (pango_coverage_parent_class)->finalize (object); +} + +static PangoCoverageLevel +pango_coverage_real_get (PangoCoverage *coverage, + int index) +{ + if (hb_set_has (coverage->chars, (hb_codepoint_t)index)) + return PANGO_COVERAGE_EXACT; + else + return PANGO_COVERAGE_NONE; +} + +static void +pango_coverage_real_set (PangoCoverage *coverage, + int index, + PangoCoverageLevel level) +{ + if (level != PANGO_COVERAGE_NONE) + hb_set_add (coverage->chars, (hb_codepoint_t)index); + else + hb_set_del (coverage->chars, (hb_codepoint_t)index); +} + +static PangoCoverage * +pango_coverage_real_copy (PangoCoverage *coverage) +{ + PangoCoverage *copy; + + g_return_val_if_fail (coverage != NULL, NULL); + + copy = g_object_new (PANGO_TYPE_COVERAGE, NULL); + hb_set_destroy (copy->chars); + copy->chars = hb_set_reference (coverage->chars); + + return copy; +} + +static void +pango_coverage_class_init (PangoCoverageClass *class) { - guint ref_count; + GObjectClass *object_class = G_OBJECT_CLASS (class); - hb_set_t *chars; -}; + object_class->finalize = pango_coverage_finalize; + + class->get = pango_coverage_real_get; + class->set = pango_coverage_real_set; + class->copy = pango_coverage_real_copy; +} /** * pango_coverage_new: @@ -54,13 +112,7 @@ struct _PangoCoverage PangoCoverage * pango_coverage_new (void) { - PangoCoverage *coverage = g_slice_new (PangoCoverage); - - coverage->ref_count = 1; - - coverage->chars = hb_set_create (); - - return coverage; + return g_object_new (PANGO_TYPE_COVERAGE, NULL); } /** @@ -77,17 +129,7 @@ pango_coverage_new (void) PangoCoverage * pango_coverage_copy (PangoCoverage *coverage) { - PangoCoverage *copy; - - g_return_val_if_fail (coverage != NULL, NULL); - - copy = g_slice_new (PangoCoverage); - - copy->ref_count = 1; - - copy->chars = hb_set_reference (coverage->chars); - - return copy; + return PANGO_COVERAGE_GET_CLASS (coverage)->copy (coverage); } /** @@ -101,11 +143,7 @@ pango_coverage_copy (PangoCoverage *coverage) PangoCoverage * pango_coverage_ref (PangoCoverage *coverage) { - g_return_val_if_fail (coverage != NULL, NULL); - - g_atomic_int_inc ((int *) &coverage->ref_count); - - return coverage; + return g_object_ref (coverage); } /** @@ -118,14 +156,7 @@ pango_coverage_ref (PangoCoverage *coverage) void pango_coverage_unref (PangoCoverage *coverage) { - g_return_if_fail (coverage != NULL); - g_return_if_fail (coverage->ref_count > 0); - - if (g_atomic_int_dec_and_test ((int *) &coverage->ref_count)) - { - hb_set_destroy (coverage->chars); - g_slice_free (PangoCoverage, coverage); - } + g_object_unref (coverage); } /** @@ -141,10 +172,7 @@ PangoCoverageLevel pango_coverage_get (PangoCoverage *coverage, int index) { - if (hb_set_has (coverage->chars, (hb_codepoint_t)index)) - return PANGO_COVERAGE_EXACT; - - return PANGO_COVERAGE_NONE; + return PANGO_COVERAGE_GET_CLASS (coverage)->get (coverage, index); } /** @@ -160,10 +188,7 @@ pango_coverage_set (PangoCoverage *coverage, int index, PangoCoverageLevel level) { - if (level != PANGO_COVERAGE_NONE) - hb_set_add (coverage->chars, (hb_codepoint_t)index); - else - hb_set_del (coverage->chars, (hb_codepoint_t)index); + PANGO_COVERAGE_GET_CLASS (coverage)->set (coverage, index, level); } /** diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index d90e78c3..20ef6c04 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -51,6 +51,7 @@ #include "pangofc-private.h" #include "pango-impl-utils.h" #include "pango-enum-types.h" +#include "pango-coverage-private.h" /* Overview: @@ -1978,6 +1979,82 @@ _pango_fc_font_map_get_cmap_cache (PangoFcFontMap *fcfontmap, return _pango_fc_cmap_cache_ref (data->cmap_cache); } +typedef struct { + PangoCoverage parent_instance; + + FcCharSet *charset; +} PangoFcCoverage; + +typedef struct { + PangoCoverageClass parent_class; +} PangoFcCoverageClass; + +GType pango_fc_coverage_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (PangoFcCoverage, pango_fc_coverage, PANGO_TYPE_COVERAGE) + +static void +pango_fc_coverage_init (PangoFcCoverage *coverage) +{ +} + +static PangoCoverageLevel +pango_fc_coverage_real_get (PangoCoverage *coverage, + int index) +{ + PangoFcCoverage *fc_coverage = (PangoFcCoverage*)coverage; + + return FcCharSetHasChar (fc_coverage->charset, index); +} + +static void +pango_fc_coverage_real_set (PangoCoverage *coverage, + int index, + PangoCoverageLevel level) +{ + PangoFcCoverage *fc_coverage = (PangoFcCoverage*)coverage; + + if (level == PANGO_COVERAGE_NONE) + FcCharSetDelChar (fc_coverage->charset, index); + else + FcCharSetAddChar (fc_coverage->charset, index); +} + +static PangoCoverage * +pango_fc_coverage_real_copy (PangoCoverage *coverage) +{ + PangoFcCoverage *fc_coverage = (PangoFcCoverage*)coverage; + PangoFcCoverage *copy; + + copy = g_object_new (pango_fc_coverage_get_type (), NULL); + copy->charset = FcCharSetCopy (fc_coverage->charset); + + return (PangoCoverage *)copy; +} + +static void +pango_fc_coverage_finalize (GObject *object) +{ + PangoFcCoverage *fc_coverage = (PangoFcCoverage*)object; + + FcCharSetDestroy (fc_coverage->charset); + + G_OBJECT_CLASS (pango_fc_coverage_parent_class)->finalize (object); +} + +static void +pango_fc_coverage_class_init (PangoFcCoverageClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + PangoCoverageClass *coverage_class = PANGO_COVERAGE_CLASS (class); + + object_class->finalize = pango_fc_coverage_finalize; + + coverage_class->get = pango_fc_coverage_real_get; + coverage_class->set = pango_fc_coverage_real_set; + coverage_class->copy = pango_fc_coverage_real_copy; +} + PangoCoverage * _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, PangoFcFont *fcfont) @@ -2016,50 +2093,12 @@ _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, PangoCoverage * _pango_fc_font_map_fc_to_coverage (FcCharSet *charset) { - PangoCoverage *coverage; - FcChar32 ucs4, pos; - FcChar32 map[FC_CHARSET_MAP_SIZE]; - int i; + PangoFcCoverage *coverage; - /* - * Convert an Fc CharSet into a pango coverage structure. Sure - * would be nice to just use the Fc structure in place... - */ - coverage = pango_coverage_new (); - for (ucs4 = FcCharSetFirstPage (charset, map, &pos); - ucs4 != FC_CHARSET_DONE; - ucs4 = FcCharSetNextPage (charset, map, &pos)) - { - for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) - { - FcChar32 bits = map[i]; - FcChar32 base = ucs4 + i * 32; - int b = 0; - - while (bits) - { - if (bits & 1) - pango_coverage_set (coverage, base + b, PANGO_COVERAGE_EXACT); - - bits >>= 1; - b++; - } - } - } - - /* Awful hack so Hangul Tone marks get rendered with the same - * font and in the same run as other Hangul characters. If a font - * covers the first composed Hangul glyph, then it is declared to cover - * the Hangul tone marks. This hack probably needs to be formalized - * by choosing fonts for scripts rather than individual code points. - */ - if (pango_coverage_get (coverage, 0xac00) == PANGO_COVERAGE_EXACT) - { - pango_coverage_set (coverage, 0x302e, PANGO_COVERAGE_EXACT); - pango_coverage_set (coverage, 0x302f, PANGO_COVERAGE_EXACT); - } + coverage = g_object_new (pango_fc_coverage_get_type (), NULL); + coverage->charset = FcCharSetCopy (charset); - return coverage; + return (PangoCoverage *)coverage; } /** -- cgit v1.2.1