diff options
-rw-r--r-- | docs/pango-sections.txt | 2 | ||||
-rw-r--r-- | meson.build | 22 | ||||
-rw-r--r-- | meson_options.txt | 4 | ||||
-rw-r--r-- | pango/meson.build | 10 | ||||
-rw-r--r-- | pango/pango-attributes.c | 102 | ||||
-rw-r--r-- | pango/pango-attributes.h | 8 | ||||
-rw-r--r-- | pango/pangowin32-fontmap.c | 11 | ||||
-rw-r--r-- | tests/test-common.c | 13 | ||||
-rw-r--r-- | tests/test-common.h | 2 | ||||
-rw-r--r-- | tests/testattributes.c | 288 |
10 files changed, 295 insertions, 167 deletions
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index c1a04e79..5050a1f3 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -427,7 +427,9 @@ pango_attr_list_insert_before pango_attr_list_change pango_attr_list_splice pango_attr_list_filter +pango_attr_list_update PangoAttrFilterFunc +pango_attr_list_get_attributes pango_attr_list_get_iterator PangoAttrIterator pango_attr_iterator_copy diff --git a/meson.build b/meson.build index 13d9bbff..d690aec5 100644 --- a/meson.build +++ b/meson.build @@ -259,8 +259,10 @@ if harfbuzz_dep.found() pango_deps += harfbuzz_dep endif -fontconfig_dep = dependency('fontconfig', version: fontconfig_req_version, required: false, - fallback: ['fontconfig', 'fontconfig_dep']) +# Only use FontConfig fallback when required or requested +fontconfig_required = (host_system != 'windows' and host_system != 'darwin') or get_option('use_fontconfig') + +fontconfig_dep = dependency('fontconfig', version: fontconfig_req_version, required: false) if fontconfig_dep.found() fontconfig_pc = 'fontconfig' else @@ -274,6 +276,11 @@ else endif endif +if fontconfig_required and not fontconfig_dep.found() + fontconfig_dep = dependency('fontconfig', version: fontconfig_req_version, + fallback: ['fontconfig', 'fontconfig_dep']) +endif + if fontconfig_dep.found() pango_deps += fontconfig_dep @@ -343,8 +350,7 @@ if host_system == 'darwin' endif cairo_found_type = '' -cairo_dep = dependency('cairo', version: cairo_req_version, required: false, - fallback: ['cairo', 'libcairo_dep']) +cairo_dep = dependency('cairo', version: cairo_req_version, required: false) if cairo_dep.found() cairo_found_type = cairo_dep.type_name() @@ -355,6 +361,14 @@ else endif endif +# Remove once Meson gains capability to declare dependencies +# in a declarative way +if not cairo_dep.found() + cairo_dep = dependency('cairo', version: cairo_req_version, + fallback: ['cairo', 'libcairo_dep']) + cairo_found_type = cairo_dep.type_name() +endif + pango_font_backends = [] pango_cairo_backends = [] diff --git a/meson_options.txt b/meson_options.txt index d2f5f302..7a59fa2b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,3 +10,7 @@ option('install-tests', description : 'Install tests', type: 'boolean', value: 'false') +option('use_fontconfig', + description : 'Force using FontConfig where it is optional, on Windows and macOS. This is ignored on platforms where it is required', + type: 'boolean', + value: 'false') diff --git a/pango/meson.build b/pango/meson.build index 1327ca39..c07b6bde 100644 --- a/pango/meson.build +++ b/pango/meson.build @@ -485,13 +485,21 @@ if cairo_dep.found() sources: pangocairo_dep_sources, ) + # Create pangocairo.pc according to whether we found Cairo + # manually + if ['pkgconfig', 'internal'].contains(cairo_found_type) + pango_cairo_requires = [ 'pango', cairo_pc ] + else + pango_cairo_requires = [ 'pango' ] + endif + pkgconfig.generate(libpangocairo, name: 'Pango Cairo', description: 'Cairo rendering support for Pango', version: meson.project_version(), filebase: 'pangocairo', subdirs: pango_api_name, - requires: [ 'pango', cairo_pc ], + requires: pango_cairo_requires, install_dir: join_paths(pango_libdir, 'pkgconfig'), ) else diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index e522931b..15edfbe8 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -1626,6 +1626,87 @@ pango_attr_list_change (PangoAttrList *list, } /** + * pango_attr_list_update: + * @list: a #PangoAttrList + * @pos: the position of the change + * @remove: the number of removed bytes + * @add: the number of added bytes + * + * Update indices of attributes in @list for + * a change in the text they refer to. + * + * The change that this function applies is + * removing @remove bytes at position @pos + * and inserting @add bytes instead. + * + * Attributes that fall entirely in the + * (@pos, @pos + @remove) range are removed. + * + * Attributes that start or end inside the + * (@pos, @pos + @remove) range are shortened to + * reflect the removal. + * + * Attributes start and end positions are updated + * if they are behind @pos + @remove. + * + * Since: 1.44 + */ +void +pango_attr_list_update (PangoAttrList *list, + int pos, + int remove, + int add) +{ + GSList *l, *prev, *next; + + prev = NULL; + l = list->attributes; + while (l) + { + PangoAttribute *attr = l->data; + next = l->next; + + if (attr->start_index >= pos && + attr->end_index < pos + remove) + { + pango_attribute_destroy (attr); + if (prev == NULL) + list->attributes = next; + else + prev->next = next; + + g_slist_free_1 (l); + } + else + { + prev = l; + + if (attr->start_index >= pos && + attr->start_index < pos + remove) + { + attr->start_index = pos + add; + } + else if (attr->start_index >= pos + remove) + { + attr->start_index += add - remove; + } + + if (attr->end_index >= pos && + attr->end_index < pos + remove) + { + attr->end_index = pos; + } + else if (attr->end_index >= pos + remove) + { + attr->end_index += add - remove; + } + } + + l = next; + } +} + +/** * pango_attr_list_splice: * @list: a #PangoAttrList * @other: another #PangoAttrList @@ -1709,6 +1790,27 @@ pango_attr_list_splice (PangoAttrList *list, } /** + * pango_attr_list_get_attributes: + * @list: a #PangoAttrList + * + * Gets a list of all attributes in @list. + * + * Return value: (element-type Pango.Attribute) (transfer full): + * a list of all attributes in @list. To free this value, call + * pango_attribute_destroy() on each value and g_slist_free() + * on the list. + * + * Since: 1.44 + */ +GSList * +pango_attr_list_get_attributes (PangoAttrList *list) +{ + g_return_val_if_fail (list != NULL, NULL); + + return g_slist_copy_deep (list->attributes, (GCopyFunc)pango_attribute_copy, NULL); +} + +/** * pango_attr_list_get_iterator: * @list: a #PangoAttrList * diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 4249f8f4..f7a0c1cb 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -551,12 +551,20 @@ void pango_attr_list_splice (PangoAttrList *list, PangoAttrList *other, gint pos, gint len); +PANGO_AVAILABLE_IN_1_44 +void pango_attr_list_update (PangoAttrList *list, + int pos, + int remove, + int add); PANGO_AVAILABLE_IN_1_2 PangoAttrList *pango_attr_list_filter (PangoAttrList *list, PangoAttrFilterFunc func, gpointer data); +PANGO_AVAILABLE_IN_1_44 +GSList *pango_attr_list_get_attributes (PangoAttrList *list); + PANGO_AVAILABLE_IN_ALL PangoAttrIterator *pango_attr_list_get_iterator (PangoAttrList *list); diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 130b76e9..976a36cb 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -574,6 +574,17 @@ read_windows_fallbacks (GHashTable *ht_aliases) entry_len = wcslen (entry); } g_free (value_data); + + /* For some reason the default fallback list doesn't cover all of Unicode + * and Windows has additional fonts for certain languages. + * Some of them are listed in + * SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapperFamilyFallback + * but I couldn't find any docs for it. Feel free to improve this */ + g_string_append (line_buffer, + ",gisha,leelawadee,arial unicode ms,browallia new," + "mingliu,simhei,gulimche,ms gothic,sylfaen,kartika," + "latha,mangal,raavi"); + g_string_append (line_buffer, "\""); handle_alias_line (line_buffer, &errstring, ht_aliases); diff --git a/tests/test-common.c b/tests/test-common.c index 83f4d99c..f6286d74 100644 --- a/tests/test-common.c +++ b/tests/test-common.c @@ -180,19 +180,6 @@ print_attributes (GSList *attrs, GString *string) } } -typedef struct -{ - guint ref_count; - GSList *attributes; - GSList *attributes_tail; -} AL; - -GSList * -attr_list_to_list (PangoAttrList *attrs) -{ - return ((AL*)attrs)->attributes; -} - const char * get_script_name (GUnicodeScript s) { diff --git a/tests/test-common.h b/tests/test-common.h index bf48e06e..28a850ae 100644 --- a/tests/test-common.h +++ b/tests/test-common.h @@ -15,8 +15,6 @@ void print_attributes (GSList *attrs, void print_attr_list (PangoAttrList *attrs, GString *string); -GSList *attr_list_to_list (PangoAttrList *attrs); - const char *get_script_name (GUnicodeScript s); diff --git a/tests/testattributes.c b/tests/testattributes.c index 9e666469..3481d01b 100644 --- a/tests/testattributes.c +++ b/tests/testattributes.c @@ -86,11 +86,44 @@ test_attributes_equal (void) } static void +assert_attributes (GSList *attrs, + const char *expected) +{ + GString *s; + + s = g_string_new (""); + print_attributes (attrs, s); + g_assert_cmpstr (s->str, ==, expected); + g_string_free (s, FALSE); +} + +static void +assert_attr_list (PangoAttrList *list, + const char *expected) +{ + GSList *attrs; + + attrs = pango_attr_list_get_attributes (list); + assert_attributes (attrs, expected); + g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); +} + +static void +assert_attr_iterator (PangoAttrIterator *iter, + const char *expected) +{ + GSList *attrs; + + attrs = pango_attr_iterator_get_attrs (iter); + assert_attributes (attrs, expected); + g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); +} + +static void test_list (void) { PangoAttrList *list; PangoAttribute *attr; - GString *s; list = pango_attr_list_new (); @@ -101,13 +134,9 @@ test_list (void) attr = pango_attr_size_new (30); pango_attr_list_insert (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10\n" -"[0,-1]size=20\n" -"[0,-1]size=30\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,-1]size=10\n" + "[0,-1]size=20\n" + "[0,-1]size=30\n"); pango_attr_list_unref (list); list = pango_attr_list_new (); @@ -126,14 +155,10 @@ test_list (void) attr->end_index = 40; pango_attr_list_insert_before (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10\n" -"[0,-1]size=30\n" -"[10,40]size=40\n" -"[10,20]size=20\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,-1]size=10\n" + "[0,-1]size=30\n" + "[10,40]size=40\n" + "[10,20]size=20\n"); pango_attr_list_unref (list); } @@ -142,7 +167,6 @@ test_list_change (void) { PangoAttrList *list; PangoAttribute *attr; - GString *s; list = pango_attr_list_new (); @@ -159,13 +183,9 @@ test_list_change (void) attr->end_index = 30; pango_attr_list_insert (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,10]size=10\n" -"[0,30]weight=700\n" -"[20,30]size=20\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,10]size=10\n" + "[0,30]weight=700\n" + "[20,30]size=20\n"); /* simple insertion with pango_attr_list_change */ attr = pango_attr_variant_new (PANGO_VARIANT_SMALL_CAPS); @@ -173,14 +193,10 @@ test_list_change (void) attr->end_index = 20; pango_attr_list_change (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,10]size=10\n" -"[0,30]weight=700\n" -"[10,20]variant=1\n" -"[20,30]size=20\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,10]size=10\n" + "[0,30]weight=700\n" + "[10,20]variant=1\n" + "[20,30]size=20\n"); /* insertion with splitting */ attr = pango_attr_weight_new (PANGO_WEIGHT_LIGHT); @@ -188,16 +204,12 @@ test_list_change (void) attr->end_index = 20; pango_attr_list_change (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,10]size=10\n" -"[0,15]weight=700\n" -"[10,20]variant=1\n" -"[15,20]weight=300\n" -"[20,30]size=20\n" -"[20,30]weight=700\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,10]size=10\n" + "[0,15]weight=700\n" + "[10,20]variant=1\n" + "[15,20]weight=300\n" + "[20,30]size=20\n" + "[20,30]weight=700\n"); /* insertion with joining */ attr = pango_attr_size_new (20); @@ -205,16 +217,12 @@ test_list_change (void) attr->end_index = 20; pango_attr_list_change (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,5]size=10\n" -"[0,15]weight=700\n" -"[5,30]size=20\n" -"[10,20]variant=1\n" -"[15,20]weight=300\n" -"[20,30]weight=700\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,5]size=10\n" + "[0,15]weight=700\n" + "[5,30]size=20\n" + "[10,20]variant=1\n" + "[15,20]weight=300\n" + "[20,30]weight=700\n"); pango_attr_list_unref (list); } @@ -226,7 +234,6 @@ test_list_splice (void) PangoAttrList *list; PangoAttrList *other; PangoAttribute *attr; - GString *s; base = pango_attr_list_new (); attr = pango_attr_size_new (10); @@ -242,26 +249,18 @@ test_list_splice (void) attr->end_index = 30; pango_attr_list_insert (base, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (base), s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10\n" -"[10,15]weight=700\n" -"[20,30]variant=1\n"); - g_string_free (s, FALSE); + assert_attr_list (base, "[0,-1]size=10\n" + "[10,15]weight=700\n" + "[20,30]variant=1\n"); /* splice in an empty list */ list = pango_attr_list_copy (base); other = pango_attr_list_new (); pango_attr_list_splice (list, other, 11, 5); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10\n" -"[10,20]weight=700\n" -"[25,35]variant=1\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,-1]size=10\n" + "[10,20]weight=700\n" + "[25,35]variant=1\n"); pango_attr_list_unref (list); pango_attr_list_unref (other); @@ -280,16 +279,12 @@ test_list_splice (void) pango_attr_list_splice (list, other, 11, 5); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,11]size=10\n" -"[10,20]weight=700\n" -"[11,14]size=20\n" -"[13,15]stretch=2\n" -"[14,-1]size=10\n" -"[25,35]variant=1\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,11]size=10\n" + "[10,20]weight=700\n" + "[11,14]size=20\n" + "[13,15]stretch=2\n" + "[14,-1]size=10\n" + "[25,35]variant=1\n"); pango_attr_list_unref (list); pango_attr_list_unref (other); @@ -318,7 +313,6 @@ test_list_filter (void) PangoAttrList *list; PangoAttrList *out; PangoAttribute *attr; - GString *s; list = pango_attr_list_new (); attr = pango_attr_size_new (10); @@ -331,13 +325,9 @@ test_list_filter (void) attr->start_index = 20; pango_attr_list_insert (list, attr); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10\n" -"[10,20]stretch=2\n" -"[20,-1]weight=700\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,-1]size=10\n" + "[10,20]stretch=2\n" + "[20,-1]weight=700\n"); out = pango_attr_list_filter (list, never_true, NULL); g_assert_null (out); @@ -345,18 +335,9 @@ test_list_filter (void) out = pango_attr_list_filter (list, just_weight, NULL); g_assert_nonnull (out); - s = g_string_new (""); - print_attributes (attr_list_to_list (list), s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10\n" -"[10,20]stretch=2\n"); - g_string_free (s, FALSE); - - s = g_string_new (""); - print_attributes (attr_list_to_list (out), s); - g_assert_cmpstr (s->str, ==, -"[20,-1]weight=700\n"); - g_string_free (s, FALSE); + assert_attr_list (list, "[0,-1]size=10\n" + "[10,20]stretch=2\n"); + assert_attr_list (out, "[20,-1]weight=700\n"); pango_attr_list_unref (list); pango_attr_list_unref (out); @@ -462,7 +443,6 @@ test_iter_get_font (void) PangoFontDescription *desc2; PangoLanguage *lang; GSList *attrs; - GString *s; list = pango_attr_list_new (); attr = pango_attr_size_new (10 * PANGO_SCALE); @@ -511,12 +491,8 @@ test_iter_get_font (void) desc2 = pango_font_description_from_string ("Times Condensed 10"); g_assert_true (pango_font_description_equal (desc, desc2)); g_assert_null (lang); - s = g_string_new (""); - print_attributes (attrs, s); - g_assert_cmpstr (s->str, ==, -"[20,-1]rise=100\n" -"[20,-1]fallback=0\n"); - g_string_free (s, FALSE); + assert_attributes (attrs, "[20,-1]rise=100\n" + "[20,-1]fallback=0\n"); g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); pango_font_description_free (desc); @@ -532,8 +508,6 @@ test_iter_get_attrs (void) PangoAttrList *list; PangoAttribute *attr; PangoAttrIterator *iter; - GSList *attrs; - GString *s; list = pango_attr_list_new (); attr = pango_attr_size_new (10 * PANGO_SCALE); @@ -556,60 +530,79 @@ test_iter_get_attrs (void) pango_attr_list_insert (list, attr); iter = pango_attr_list_get_iterator (list); - attrs = pango_attr_iterator_get_attrs (iter); - s = g_string_new (""); - print_attributes (attrs, s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10240\n" -"[0,-1]family=Times\n"); - g_string_free (s, FALSE); - g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); + assert_attr_iterator (iter, "[0,-1]size=10240\n" + "[0,-1]family=Times\n"); pango_attr_iterator_next (iter); - attrs = pango_attr_iterator_get_attrs (iter); - s = g_string_new (""); - print_attributes (attrs, s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10240\n" -"[0,-1]family=Times\n" -"[10,30]stretch=2\n" -"[10,20]language=ja-jp\n"); - g_string_free (s, FALSE); - g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); + assert_attr_iterator (iter, "[0,-1]size=10240\n" + "[0,-1]family=Times\n" + "[10,30]stretch=2\n" + "[10,20]language=ja-jp\n"); pango_attr_iterator_next (iter); - attrs = pango_attr_iterator_get_attrs (iter); - s = g_string_new (""); - print_attributes (attrs, s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10240\n" -"[0,-1]family=Times\n" -"[10,30]stretch=2\n" -"[20,-1]rise=100\n" -"[20,-1]fallback=0\n"); - g_string_free (s, FALSE); - g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); + assert_attr_iterator (iter, "[0,-1]size=10240\n" + "[0,-1]family=Times\n" + "[10,30]stretch=2\n" + "[20,-1]rise=100\n" + "[20,-1]fallback=0\n"); pango_attr_iterator_next (iter); - attrs = pango_attr_iterator_get_attrs (iter); - s = g_string_new (""); - print_attributes (attrs, s); - g_assert_cmpstr (s->str, ==, -"[0,-1]size=10240\n" -"[0,-1]family=Times\n" -"[20,-1]rise=100\n" -"[20,-1]fallback=0\n"); - g_string_free (s, FALSE); - g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy); + assert_attr_iterator (iter, "[0,-1]size=10240\n" + "[0,-1]family=Times\n" + "[20,-1]rise=100\n" + "[20,-1]fallback=0\n"); pango_attr_iterator_next (iter); - attrs = pango_attr_iterator_get_attrs (iter); - g_assert_null (attrs); + g_assert_null (pango_attr_iterator_get_attrs (iter)); pango_attr_iterator_destroy (iter); pango_attr_list_unref (list); } +static void +test_list_update (void) +{ + PangoAttrList *list; + PangoAttribute *attr; + + list = pango_attr_list_new (); + attr = pango_attr_size_new (10 * PANGO_SCALE); + attr->start_index = 10; + attr->end_index = 11; + pango_attr_list_insert (list, attr); + attr = pango_attr_rise_new (100); + attr->start_index = 0; + attr->end_index = 200; + pango_attr_list_insert (list, attr); + attr = pango_attr_family_new ("Times"); + attr->start_index = 5; + attr->end_index = 15; + pango_attr_list_insert (list, attr); + attr = pango_attr_fallback_new (FALSE); + attr->start_index = 11; + attr->end_index = 100; + pango_attr_list_insert (list, attr); + attr = pango_attr_stretch_new (PANGO_STRETCH_CONDENSED); + attr->start_index = 30; + attr->end_index = 60; + pango_attr_list_insert (list, attr); + + assert_attr_list (list, "[0,200]rise=100\n" + "[5,15]family=Times\n" + "[10,11]size=10240\n" + "[11,100]fallback=0\n" + "[30,60]stretch=2\n"); + + pango_attr_list_update (list, 8, 10, 20); + + assert_attr_list (list, "[0,210]rise=100\n" + "[5,8]family=Times\n" + "[28,110]fallback=0\n" + "[40,70]stretch=2\n"); + + pango_attr_list_unref (list); +} + int main (int argc, char *argv[]) { @@ -621,6 +614,7 @@ main (int argc, char *argv[]) g_test_add_func ("/attributes/list/change", test_list_change); g_test_add_func ("/attributes/list/splice", test_list_splice); g_test_add_func ("/attributes/list/filter", test_list_filter); + g_test_add_func ("/attributes/list/update", test_list_update); g_test_add_func ("/attributes/iter/basic", test_iter); g_test_add_func ("/attributes/iter/get", test_iter_get); g_test_add_func ("/attributes/iter/get_font", test_iter_get_font); |