diff options
-rw-r--r-- | NEWS | 9 | ||||
-rwxr-xr-x | make-release.sh | 11 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | pango/break.c | 22 | ||||
-rw-r--r-- | pango/pango-bidi-type.c | 12 | ||||
-rw-r--r-- | pango/pango-context.c | 15 | ||||
-rw-r--r-- | pango/pango-emoji.c | 124 | ||||
-rw-r--r-- | pango/pango-impl-utils.h | 3 | ||||
-rw-r--r-- | pango/pangofc-fontmap.c | 38 | ||||
-rw-r--r-- | pango/pangofc-shape.c | 27 |
10 files changed, 146 insertions, 117 deletions
@@ -1,3 +1,12 @@ +Overview of changes in 1.48.4 +============================= +- Include docs in the dist tarball +- Include gi-docgen in the dist tarball, too +- win32: Fix 'Cursive' fallback +- Fix placement of marks in vertical text +- Cache metrics for the current font +- Improve letterspacing with combining marks + Overview of changes in 1.48.3 ============================= - Miscellaneous introspection fixes diff --git a/make-release.sh b/make-release.sh index 8e3108a9..c29771e7 100755 --- a/make-release.sh +++ b/make-release.sh @@ -9,15 +9,14 @@ if [ -d ${release_build_dir} ]; then exit 1 fi +# make sure included subprojects are current +meson subprojects update gi-docgen + # make the release tarball -meson setup --force-fallback-for gi-docgen ${release_build_dir} || exit +meson setup -Dgtk_doc=true --force-fallback-for gi-docgen ${release_build_dir} || exit +meson compile -C${release_build_dir} || exit meson dist -C${release_build_dir} --include-subprojects || exit -# now build the docs -meson configure -Dgtk_doc=true ${release_build_dir} || exit -ninja -C${release_build_dir} || exit - -tar cf ${release_build_dir}/meson-dist/pango-docs-${version}.tar.xz -C${release_build_dir} docs/ echo -e "\n\nPango ${version} release on branch ${branch} in ./${release_build_dir}/:\n" diff --git a/meson.build b/meson.build index 894c6071..b52a55fc 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('pango', 'c', 'cpp', - version: '1.48.3', + version: '1.48.4', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized', diff --git a/pango/break.c b/pango/break.c index 35b947c0..6b8e5c01 100644 --- a/pango/break.c +++ b/pango/break.c @@ -362,12 +362,15 @@ pango_default_break (const gchar *text, case G_UNICODE_PARAGRAPH_SEPARATOR: attrs[i].is_white = TRUE; break; - default: + case G_UNICODE_CONTROL: if (wc == '\t' || wc == '\n' || wc == '\r' || wc == '\f') attrs[i].is_white = TRUE; else attrs[i].is_white = FALSE; break; + default: + attrs[i].is_white = FALSE; + break; } /* Just few spaces have variable width. So explicitly mark them. @@ -502,9 +505,7 @@ pango_default_break (const gchar *text, else if (GB_type == GB_InHangulSyllable) is_grapheme_boundary = FALSE; /* Rules GB6, GB7, GB8 */ else if (GB_type == GB_Extend) - { - is_grapheme_boundary = FALSE; /* Rule GB9 */ - } + is_grapheme_boundary = FALSE; /* Rule GB9 */ else if (GB_type == GB_ZWJ) is_grapheme_boundary = FALSE; /* Rule GB9 */ else if (GB_type == GB_SpacingMark) @@ -641,14 +642,12 @@ pango_default_break (const gchar *text, if (wc >= 0x24B6 && wc <= 0x24E9) /* Other_Alphabetic */ goto Alphabetic; - if (G_UNLIKELY(wc >=0x1F1E6 && wc <=0x1F1FF)) + if (G_UNLIKELY(wc >= 0x1F1E6 && wc <= 0x1F1FF)) { - if (prev_WB_type == WB_RI_Odd) - WB_type = WB_RI_Even; - else if (prev_WB_type == WB_RI_Even) - WB_type = WB_RI_Odd; - else - WB_type = WB_RI_Odd; + if (prev_WB_type == WB_RI_Odd) + WB_type = WB_RI_Even; + else + WB_type = WB_RI_Odd; } break; @@ -1563,7 +1562,6 @@ pango_default_break (const gchar *text, attrs[i].is_line_break = TRUE; /* Rule LB3 */ attrs[0].is_line_break = FALSE; /* Rule LB2 */ - } static gboolean diff --git a/pango/pango-bidi-type.c b/pango/pango-bidi-type.c index b86affba..01da86d3 100644 --- a/pango/pango-bidi-type.c +++ b/pango/pango-bidi-type.c @@ -273,8 +273,8 @@ resolved: * * This function is useful to categorize characters into left-to-right * letters, right-to-left letters, and everything else. If full Unicode - * bidirectional type of a character is needed, [type_func@Pango.BidiType.for_unichar] - * can be used instead. + * bidirectional type of a character is needed, + * [type_func@Pango.BidiType.for_unichar] can be used instead. * * Return value: the direction of the character. */ @@ -305,12 +305,12 @@ pango_unichar_direction (gunichar ch) * * Mirror characters are determined by the Unicode mirrored property. * - * Use g_unichar_get_mirror_char() instead; the docs for that function - * provide full details. - * * Return value: %TRUE if @ch has a mirrored character and @mirrored_ch is * filled in, %FALSE otherwise - **/ + * + * Deprecated: Use g_unichar_get_mirror_char() instead; the docs for that function + * provide full details. + */ gboolean pango_get_mirror_char (gunichar ch, gunichar *mirrored_ch) diff --git a/pango/pango-context.c b/pango/pango-context.c index ccaa1bac..90952add 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -910,6 +910,9 @@ width_iter_is_upright (gunichar ch) int st = 0; int ed = max; + if (ch < upright[0][0]) + return FALSE; + while (st <= ed) { int mid = (st + ed) / 2; @@ -926,7 +929,7 @@ width_iter_is_upright (gunichar ch) } static void -width_iter_next(PangoWidthIter* iter) +width_iter_next (PangoWidthIter *iter) { gboolean met_joiner = FALSE; iter->start = iter->end; @@ -958,9 +961,9 @@ width_iter_next(PangoWidthIter* iter) } /* for variation selector, tag and emoji modifier. */ - if (G_UNLIKELY(ch == 0xFE0EU || ch == 0xFE0FU - || (ch >= 0xE0020 && ch <= 0xE007F) - || (ch >= 0x1F3FB && ch <= 0x1F3FF))) + if (G_UNLIKELY (ch == 0xFE0EU || ch == 0xFE0FU || + (ch >= 0xE0020 && ch <= 0xE007F) || + (ch >= 0x1F3FB && ch <= 0x1F3FF))) { iter->end = g_utf8_next_char (iter->end); continue; @@ -968,6 +971,7 @@ width_iter_next(PangoWidthIter* iter) if (width_iter_is_upright (ch) != iter->upright) break; + iter->end = g_utf8_next_char (iter->end); } } @@ -1000,7 +1004,6 @@ itemize_state_init (ItemizeState *state, PangoAttrIterator *cached_iter, const PangoFontDescription *desc) { - state->context = context; state->text = text; state->end = text + start_index + length; @@ -1576,7 +1579,7 @@ pango_itemize_with_base_dir (PangoContext *context, g_return_val_if_fail (length >= 0, NULL); g_return_val_if_fail (length == 0 || text != NULL, NULL); - if (length == 0 || g_utf8_strlen (text + start_index, length) == 0) + if (length == 0 || g_utf8_get_char (text + start_index) == '\0') return NULL; itemize_state_init (&state, context, text, base_dir, start_index, length, diff --git a/pango/pango-emoji.c b/pango/pango-emoji.c index e316b370..0abb8783 100644 --- a/pango/pango-emoji.c +++ b/pango/pango-emoji.c @@ -52,40 +52,37 @@ #include "pango-emoji-private.h" #include "pango-emoji-table.h" - -static int -interval_compare (const void *key, const void *elt) +static inline gboolean +bsearch_interval (gunichar c, + const struct Interval table[], + guint n) { - gunichar c = GPOINTER_TO_UINT (key); - struct Interval *interval = (struct Interval *)elt; - - if (c < interval->start) - return -1; - if (c > interval->end) - return +1; - - return 0; + guint lower = 0; + guint upper = n - 1; + + while (lower <= upper) + { + int mid = (lower + upper) / 2; + + if (c < table[mid].start) + upper = mid - 1; + else if (c > table[mid].end) + lower = mid + 1; + else + return TRUE; + } + + return FALSE; } #define DEFINE_pango_Is_(name) \ -static gboolean \ +static inline gboolean \ _pango_Is_##name (gunichar ch) \ { \ - /* bsearch() is declared attribute(nonnull(1)) so we can't validly search \ - * for a NULL key */ \ - /* \ - if (G_UNLIKELY (ch == 0)) \ - return FALSE; \ - */ \ - \ - if (bsearch (GUINT_TO_POINTER (ch), \ - _pango_##name##_table, \ - G_N_ELEMENTS (_pango_##name##_table), \ - sizeof _pango_##name##_table[0], \ - interval_compare)) \ - return TRUE; \ - \ - return FALSE; \ + return ch >= _pango_##name##_table[0].start && \ + bsearch_interval (ch, \ + _pango_##name##_table, \ + G_N_ELEMENTS (_pango_##name##_table)); \ } DEFINE_pango_Is_(Emoji) @@ -106,36 +103,36 @@ _pango_Is_Emoji_Extended_Pictographic (gunichar ch) return _pango_Is_Extended_Pictographic (ch); } -static gboolean +static inline gboolean _pango_Is_Emoji_Text_Default (gunichar ch) { return _pango_Is_Emoji (ch) && !_pango_Is_Emoji_Presentation (ch); } -static gboolean +static inline gboolean _pango_Is_Emoji_Emoji_Default (gunichar ch) { return _pango_Is_Emoji_Presentation (ch); } -static gboolean +static inline gboolean _pango_Is_Emoji_Keycap_Base (gunichar ch) { return (ch >= '0' && ch <= '9') || ch == '#' || ch == '*'; } -static gboolean +static inline gboolean _pango_Is_Regional_Indicator (gunichar ch) { return (ch >= 0x1F1E6 && ch <= 0x1F1FF); } -const gunichar kCombiningEnclosingCircleBackslashCharacter = 0x20E0; -const gunichar kCombiningEnclosingKeycapCharacter = 0x20E3; -const gunichar kVariationSelector15Character = 0xFE0E; -const gunichar kVariationSelector16Character = 0xFE0F; -const gunichar kZeroWidthJoinerCharacter = 0x200D; +#define kCombiningEnclosingCircleBackslashCharacter 0x20E0 +#define kCombiningEnclosingKeycapCharacter 0x20E3 +#define kVariationSelector15Character 0xFE0E +#define kVariationSelector16Character 0xFE0F +#define kZeroWidthJoinerCharacter 0x200D enum PangoEmojiScannerCategory { EMOJI = 0, @@ -157,27 +154,41 @@ enum PangoEmojiScannerCategory { kMaxEmojiScannerCategory = 16 }; -static unsigned char +static inline unsigned char _pango_EmojiSegmentationCategory (gunichar codepoint) { /* Specific ones first. */ - if (codepoint == kCombiningEnclosingKeycapCharacter) - return COMBINING_ENCLOSING_KEYCAP; - if (codepoint == kCombiningEnclosingCircleBackslashCharacter) - return COMBINING_ENCLOSING_CIRCLE_BACKSLASH; - if (codepoint == kZeroWidthJoinerCharacter) - return ZWJ; - if (codepoint == kVariationSelector15Character) - return VS15; - if (codepoint == kVariationSelector16Character) - return VS16; - if (codepoint == 0x1F3F4) - return TAG_BASE; - if ((codepoint >= 0xE0030 && codepoint <= 0xE0039) || - (codepoint >= 0xE0061 && codepoint <= 0xE007A)) + if (('a' <= codepoint && codepoint <= 'z') || + ('A' <= codepoint && codepoint <= 'Z') || + codepoint == ' ') + return kMaxEmojiScannerCategory; + + if ('0' <= codepoint && codepoint <= '9') + return KEYCAP_BASE; + + switch (codepoint) + { + case kCombiningEnclosingKeycapCharacter: + return COMBINING_ENCLOSING_KEYCAP; + case kCombiningEnclosingCircleBackslashCharacter: + return COMBINING_ENCLOSING_CIRCLE_BACKSLASH; + case kZeroWidthJoinerCharacter: + return ZWJ; + case kVariationSelector15Character: + return VS15; + case kVariationSelector16Character: + return VS16; + case 0x1F3F4: + return TAG_BASE; + case 0xE007F: + return TAG_TERM; + default: ; + } + + if ((0xE0030 <= codepoint && codepoint <= 0xE0039) || + (0xE0061 <= codepoint && codepoint <= 0xE007A)) return TAG_SEQUENCE; - if (codepoint == 0xE007F) - return TAG_TERM; + if (_pango_Is_Emoji_Modifier_Base (codepoint)) return EMOJI_MODIFIER_BASE; if (_pango_Is_Emoji_Modifier (codepoint)) @@ -186,13 +197,10 @@ _pango_EmojiSegmentationCategory (gunichar codepoint) return REGIONAL_INDICATOR; if (_pango_Is_Emoji_Keycap_Base (codepoint)) return KEYCAP_BASE; - if (_pango_Is_Emoji_Emoji_Default (codepoint)) return EMOJI_EMOJI_PRESENTATION; - if (_pango_Is_Emoji_Text_Default (codepoint)) - return EMOJI_TEXT_PRESENTATION; if (_pango_Is_Emoji (codepoint)) - return EMOJI; + return EMOJI_TEXT_PRESENTATION; /* Ragel state machine will interpret unknown category as "any". */ return kMaxEmojiScannerCategory; diff --git a/pango/pango-impl-utils.h b/pango/pango-impl-utils.h index d2420321..bbeca994 100644 --- a/pango/pango-impl-utils.h +++ b/pango/pango-impl-utils.h @@ -163,6 +163,9 @@ pango_get_ignorable (gunichar ch) for (i = 0; i < G_N_ELEMENTS (ignorables); i++) { + if (ch < ignorables[i].ch) + return NULL; + if (ch == ignorables[i].ch) return ignorables[i].nick; } diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index 16f10747..813b6c78 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -106,7 +106,7 @@ */ static GMutex fc_init_mutex; static GCond fc_init_cond; -static gboolean fc_initialized; +static int fc_initialized = 0; typedef struct _PangoFcFontFaceData PangoFcFontFaceData; @@ -1357,8 +1357,28 @@ init_in_thread (GTask *task, pango_trace_mark (before, "FcInit", NULL); g_mutex_lock (&fc_init_mutex); - fc_initialized = TRUE; - g_cond_signal (&fc_init_cond); + fc_initialized = 2; + g_cond_broadcast (&fc_init_cond); + g_mutex_unlock (&fc_init_mutex); +} + +static void +start_init_in_thread (PangoFcFontMap *fcfontmap) +{ + g_mutex_lock (&fc_init_mutex); + + if (fc_initialized == 0) + { + GTask *task; + + fc_initialized = 1; + + task = g_task_new (fcfontmap, NULL, NULL, NULL); + g_task_set_name (task, "[pango] FcInit"); + g_task_run_in_thread (task, init_in_thread); + g_object_unref (task); + } + g_mutex_unlock (&fc_init_mutex); } @@ -1369,7 +1389,7 @@ wait_for_fc_init (void) gboolean waited = FALSE; g_mutex_lock (&fc_init_mutex); - while (!fc_initialized) + while (fc_initialized < 2) { waited = TRUE; g_cond_wait (&fc_init_cond, &fc_init_mutex); @@ -1411,15 +1431,7 @@ pango_fc_font_map_init (PangoFcFontMap *fcfontmap) NULL); priv->dpi = -1; - if (!fc_initialized) - { - GTask *task; - - task = g_task_new (fcfontmap, NULL, NULL, NULL); - g_task_set_name (task, "[pango] FcInit"); - g_task_run_in_thread (task, init_in_thread); - g_object_unref (task); - } + start_init_in_thread (fcfontmap); } static void diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c index 5c716b24..0a5ce7f9 100644 --- a/pango/pangofc-shape.c +++ b/pango/pangofc-shape.c @@ -151,18 +151,10 @@ pango_hb_font_get_nominal_glyph (hb_font_t *font, { PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - if ((context->show_flags & PANGO_SHOW_IGNORABLES) != 0) + if (context->show_flags != 0) { - if (pango_get_ignorable (unicode)) - { - *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); - return TRUE; - } - } - - if ((context->show_flags & PANGO_SHOW_SPACES) != 0) - { - if (g_unichar_type (unicode) == G_UNICODE_SPACE_SEPARATOR) + if ((context->show_flags & PANGO_SHOW_SPACES) != 0 && + g_unichar_type (unicode) == G_UNICODE_SPACE_SEPARATOR) { /* Replace 0x20 by visible space, since we * don't draw a hex box for 0x20 @@ -173,11 +165,16 @@ pango_hb_font_get_nominal_glyph (hb_font_t *font, *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); return TRUE; } - } - if ((context->show_flags & PANGO_SHOW_LINE_BREAKS) != 0) - { - if (unicode == 0x2028) + if ((context->show_flags & PANGO_SHOW_IGNORABLES) != 0 && + pango_get_ignorable (unicode)) + { + *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); + return TRUE; + } + + if ((context->show_flags & PANGO_SHOW_LINE_BREAKS) != 0 && + unicode == 0x2028) { /* Always mark LS as unknown. If it ends up * at the line end, PangoLayout takes care of |