diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-07-22 16:20:37 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-22 16:20:37 +0000 |
commit | f401cb1789400384aca0e3679e47213148c9403b (patch) | |
tree | b2c949dda55a6199efdd35d0815acf384af8b065 | |
parent | 5319f448a052ab328deefea2a6a697fab2903ddf (diff) | |
parent | 2036d2b6be2254f97f23944b04a58d224bd1409d (diff) | |
download | pango-f401cb1789400384aca0e3679e47213148c9403b.tar.gz |
Merge branch 'better-hyphens' into 'master'
Better hyphens
See merge request GNOME/pango!89
-rw-r--r-- | .gitlab-ci.yml | 1 | ||||
-rw-r--r-- | docs/pango-sections.txt | 2 | ||||
-rw-r--r-- | pango/break.c | 98 | ||||
-rw-r--r-- | pango/pango-attributes.c | 27 | ||||
-rw-r--r-- | pango/pango-attributes.h | 6 | ||||
-rw-r--r-- | pango/pango-break.h | 5 | ||||
-rw-r--r-- | pango/pango-item.h | 12 | ||||
-rw-r--r-- | pango/pango-layout.c | 207 | ||||
-rw-r--r-- | pango/pango-markup.c | 17 | ||||
-rw-r--r-- | pango/pangofc-font.c | 4 | ||||
-rw-r--r-- | pango/pangofc-shape.c | 14 | ||||
-rw-r--r-- | tests/breaks/one.expected | 10 | ||||
-rw-r--r-- | tests/breaks/three.expected | 10 | ||||
-rw-r--r-- | tests/breaks/two.expected | 10 | ||||
-rw-r--r-- | tests/layouts/valid-4.expected | 24 | ||||
-rw-r--r-- | tests/test-break.c | 22 | ||||
-rw-r--r-- | tests/testiter.c | 11 | ||||
-rw-r--r-- | utils/test-hyphens.txt | 4 |
18 files changed, 297 insertions, 187 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a33020b5..a832e53e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,6 +20,7 @@ gnome-runtime-linux: gobject-introspection-devel \ cairo-gobject-devel \ abattis-cantarell-fonts \ + google-droid-sans-fonts \ desktop-file-utils script: - meson _build diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index 11aabcae..5050a1f3 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -6,6 +6,7 @@ PangoItem PangoAnalysis PANGO_ANALYSIS_FLAG_CENTERED_BASELINE PANGO_ANALYSIS_FLAG_IS_ELLIPSIS +PANGO_ANALYSIS_FLAG_NEED_HYPHEN PANGO_TYPE_DIRECTION <SUBSECTION> @@ -407,6 +408,7 @@ pango_attr_gravity_hint_new pango_attr_font_features_new pango_attr_foreground_alpha_new pango_attr_background_alpha_new +pango_attr_allow_breaks_new_ PangoColor PANGO_TYPE_COLOR pango_color_parse diff --git a/pango/break.c b/pango/break.c index 8ed8e8c1..356c5afe 100644 --- a/pango/break.c +++ b/pango/break.c @@ -1578,18 +1578,34 @@ break_script (const char *item_text, int attrs_len); static gboolean -tailor_break (const gchar *text, - gint length, - PangoAnalysis *analysis, - PangoLogAttr *attrs, - int attrs_len) +break_attrs (const char *text, + int length, + GSList *attributes, + int item_offset, + PangoLogAttr *attrs, + int attrs_len); + +static gboolean +tailor_break (const char *text, + int length, + PangoAnalysis *analysis, + int item_offset, + PangoLogAttr *attrs, + int attrs_len) { + gboolean res; + if (length < 0) length = strlen (text); else if (text == NULL) text = ""; - return break_script (text, length, analysis, attrs, attrs_len); + res = break_script (text, length, analysis, attrs, attrs_len); + + if (item_offset >= 0) + res |= break_attrs (text, length, analysis->extra_attrs, item_offset, attrs, attrs_len); + + return res; } /** @@ -1618,7 +1634,7 @@ pango_break (const gchar *text, g_return_if_fail (attrs != NULL); pango_default_break (text, length, analysis, attrs, attrs_len); - tailor_break (text, length, analysis, attrs, attrs_len); + tailor_break (text, length, analysis, -1, attrs, attrs_len); } /** @@ -1726,6 +1742,8 @@ pango_find_paragraph_boundary (const gchar *text, * @text: text to process. Must be valid UTF-8 * @length: length in bytes of @text * @analysis: #PangoAnalysis structure from pango_itemize() for @text + * @offset: Byte offset of @text from the beginning of the + * paragraph, or -1 to ignore attributes from @analysis * @log_attrs: (array length=attrs_len): array with one #PangoLogAttr * per character in @text, plus one extra, to be filled in * @attrs_len: length of @log_attrs array @@ -1733,18 +1751,24 @@ pango_find_paragraph_boundary (const gchar *text, * Apply language-specific tailoring to the breaks in * @log_attrs, which are assumed to have been produced * by pango_default_break(). + * + * If @offset is not -1, it is used to apply attributes + * from @analysis that are relevant to line breaking. + * + * Since: 1.44 */ void pango_tailor_break (const char *text, int length, PangoAnalysis *analysis, + int offset, PangoLogAttr *log_attrs, int log_attrs_len) { PangoLogAttr *start = log_attrs; PangoLogAttr attr_before = *start; - if (tailor_break (text, length, analysis, log_attrs, log_attrs_len)) + if (tailor_break (text, length, analysis, offset, log_attrs, log_attrs_len)) { /* if tailored, we enforce some of the attrs from before * tailoring at the boundary @@ -1773,6 +1797,7 @@ tailor_segment (const char *range_start, pango_tailor_break (range_start, range_end - range_start, analysis, + -1, start, chars_in_range + 1); @@ -1877,3 +1902,60 @@ break_script (const char *item_text, return TRUE; } + +static gboolean +break_attrs (const char *text, + int length, + GSList *attributes, + int offset, + PangoLogAttr *log_attrs, + int log_attrs_len) +{ + PangoAttrList *list; + PangoAttrIterator *iter; + GSList *l; + + list = pango_attr_list_new (); + for (l = attributes; l; l = l->next) + { + PangoAttribute *attr = l->data; + + if (attr->klass->type == PANGO_ATTR_ALLOW_BREAKS) + pango_attr_list_insert (list, (PangoAttribute*)l->data); + } + + iter = pango_attr_list_get_iterator (list); + do { + PangoAttribute *attr; + + attr = pango_attr_iterator_get (iter, PANGO_ATTR_ALLOW_BREAKS); + if (attr && ((PangoAttrInt*)attr)->value == 0) + { + int start, end; + int start_pos, end_pos; + int pos; + + pango_attr_iterator_range (iter, &start, &end); + if (start < offset) + start_pos = 0; + else + start_pos = g_utf8_pointer_to_offset (text, text + start - offset); + if (end >= offset + length) + end_pos = log_attrs_len; + else + end_pos = g_utf8_pointer_to_offset (text, text + end - offset); + + for (pos = start_pos + 1; pos < end_pos; pos++) + { + log_attrs[pos].is_mandatory_break = FALSE; + log_attrs[pos].is_line_break = FALSE; + log_attrs[pos].is_char_break = FALSE; + } + } + } while (pango_attr_iterator_next (iter)); + + pango_attr_iterator_destroy (iter); + pango_attr_list_unref (list); + + return TRUE; +} diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 894555d1..15edfbe8 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -1179,6 +1179,33 @@ pango_attr_background_alpha_new (guint16 alpha) return pango_attr_int_new (&klass, (int)alpha); } +/** + * pango_attr_allow_breaks_new: + * @allow_breaks: %TRUE if we line breaks are allowed + * + * Create a new allow-breaks attribute. + * + * If breaks are disabled, the range will be kept in a + * single run, as far as possible. + * + * Return value: (transfer full): the newly allocated #PangoAttribute, + * which should be freed with pango_attribute_destroy() + * + * Since: 1.44 + */ +PangoAttribute * +pango_attr_allow_breaks_new (gboolean allow_breaks) +{ + static const PangoAttrClass klass = { + PANGO_ATTR_ALLOW_BREAKS, + pango_attr_int_copy, + pango_attr_int_destroy, + pango_attr_int_equal, + }; + + return pango_attr_int_new (&klass, (int)allow_breaks); +} + /* * Attribute List */ diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 6f021c06..f7a0c1cb 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -147,6 +147,7 @@ typedef struct _PangoAttrIterator PangoAttrIterator; * @PANGO_ATTR_FONT_FEATURES: OpenType font features (#PangoAttrString). Since 1.38 * @PANGO_ATTR_FOREGROUND_ALPHA: foreground alpha (#PangoAttrInt). Since 1.38 * @PANGO_ATTR_BACKGROUND_ALPHA: background alpha (#PangoAttrInt). Since 1.38 + * @PANGO_ATTR_ALLOW_BREAKS: whether breaks are allowed (#PangoAttrInt). Since 1.44 * * The #PangoAttrType * distinguishes between different types of attributes. Along with the @@ -182,7 +183,8 @@ typedef enum PANGO_ATTR_GRAVITY_HINT, /* PangoAttrInt */ PANGO_ATTR_FONT_FEATURES, /* PangoAttrString */ PANGO_ATTR_FOREGROUND_ALPHA, /* PangoAttrInt */ - PANGO_ATTR_BACKGROUND_ALPHA /* PangoAttrInt */ + PANGO_ATTR_BACKGROUND_ALPHA, /* PangoAttrInt */ + PANGO_ATTR_ALLOW_BREAKS /* PangoAttrInt */ } PangoAttrType; /** @@ -522,6 +524,8 @@ PANGO_AVAILABLE_IN_1_38 PangoAttribute *pango_attr_foreground_alpha_new (guint16 alpha); PANGO_AVAILABLE_IN_1_38 PangoAttribute *pango_attr_background_alpha_new (guint16 alpha); +PANGO_AVAILABLE_IN_1_44 +PangoAttribute *pango_attr_allow_breaks_new (gboolean allow_breaks); PANGO_AVAILABLE_IN_ALL GType pango_attr_list_get_type (void) G_GNUC_CONST; diff --git a/pango/pango-break.h b/pango/pango-break.h index 4e1db0bc..19698db1 100644 --- a/pango/pango-break.h +++ b/pango/pango-break.h @@ -134,9 +134,10 @@ void pango_default_break (const gchar *text, int attrs_len); PANGO_AVAILABLE_IN_1_44 -void pango_tailor_break (const gchar *text, - int length, +void pango_tailor_break (const char *text, + int length, PangoAnalysis *analysis, + int offset, PangoLogAttr *attrs, int attrs_len); diff --git a/pango/pango-item.h b/pango/pango-item.h index 2a7bcb2a..d4162f90 100644 --- a/pango/pango-item.h +++ b/pango/pango-item.h @@ -51,13 +51,23 @@ typedef struct _PangoItem PangoItem; #define PANGO_ANALYSIS_FLAG_IS_ELLIPSIS (1 << 1) /** + * PANGO_ANALYSIS_FLAG_NEED_HYPHEN: + * + * This flag tells Pango to add a hyphen at the end of the + * run during shaping. + * + * Since: 1.44 + */ +#define PANGO_ANALYSIS_FLAG_NEED_HYPHEN (1 << 2) + +/** * PangoAnalysis: * @shape_engine: unused * @lang_engine: unused * @font: the font for this segment. * @level: the bidirectional level for this segment. * @gravity: the glyph orientation for this segment (A #PangoGravity). - * @flags: boolean flags for this segment (currently only one) (Since: 1.16). + * @flags: boolean flags for this segment (Since: 1.16). * @script: the detected script for this segment (A #PangoScript) (Since: 1.18). * @language: the detected language for this segment. * @extra_attrs: extra attributes for this segment. diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 7735d6f2..414525d7 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -3337,9 +3337,9 @@ shape_run (PangoLayoutLine *line, state->properties.shape_ink_rect, state->properties.shape_logical_rect, glyphs); else - pango_shape_full (layout->text + item->offset, item->length, - layout->text, layout->length, - &item->analysis, glyphs); + pango_shape_full (layout->text + item->offset, item->length, + layout->text, layout->length, + &item->analysis, glyphs); if (state->properties.letter_spacing) { @@ -3396,73 +3396,6 @@ insert_run (PangoLayoutLine *line, } static void -advance_iterator_to (PangoAttrIterator *iter, - int new_index) -{ - int start, end; - - do - { - pango_attr_iterator_range (iter, &start, &end); - if (end > new_index) - break; - } - while (pango_attr_iterator_next (iter)); -} - -static PangoLayoutRun * -create_hyphen_run (PangoLayout *layout, - PangoItem *item) -{ - PangoLayoutRun *run; - GList *items; - const char *hyphen_text = "-"; - int hyphen_len = 1; - PangoAttrList *attrs; - PangoAttrIterator *iter; - GSList *list, *l; - PangoAttrList *run_attrs; - - run_attrs = pango_attr_list_new (); - - attrs = pango_layout_get_effective_attributes (layout); - iter = pango_attr_list_get_iterator (attrs); - - advance_iterator_to (iter, item->offset + item->length); - list = pango_attr_iterator_get_attrs (iter); - for (l = list; l; l = l->next) - { - PangoAttribute *attr = l->data; - attr->start_index = 0; - attr->end_index = G_MAXINT; - pango_attr_list_insert (attrs, attr); - } - g_slist_free (list); - - items = pango_itemize (layout->context, hyphen_text, 0, hyphen_len, attrs, NULL); - g_assert (items->next == NULL); - - run = g_slice_new (PangoGlyphItem); - run->glyphs = pango_glyph_string_new (); - run->item = items->data; - - /* insert after item, use SHY as text */ - run->item->offset = item->offset + item->length; - run->item->length = 2; - run->item->num_chars = 1; - - g_list_free (items); - - pango_shape (hyphen_text, hyphen_len, &run->item->analysis, run->glyphs); - - pango_attr_iterator_destroy (iter); - pango_attr_list_unref (attrs); - pango_attr_list_unref (run_attrs); - - return run; -} - -static void get_need_hyphen (PangoItem *item, const char *text, int *need_hyphen) @@ -3472,8 +3405,37 @@ get_need_hyphen (PangoItem *item, for (i = 0, p = text + item->offset; i < item->num_chars; i++, p = g_utf8_next_char (p)) { - gunichar ch = g_utf8_get_char (p); - need_hyphen[i] = ch == 0xad; + gunichar wc = g_utf8_get_char (p); + switch (g_unichar_type(wc)) + { + case G_UNICODE_SPACE_SEPARATOR: + case G_UNICODE_LINE_SEPARATOR: + case G_UNICODE_PARAGRAPH_SEPARATOR: + need_hyphen[i] = FALSE; + break; + case G_UNICODE_CONTROL: + if (wc == '\t' || wc == '\n' || wc == '\r' || wc == '\f') + need_hyphen[i] = FALSE; + else + need_hyphen[i] = TRUE; + break; + default: + if (wc == '-' || /* Hyphen-minus */ + wc == 0x058a || /* Armenian hyphen */ + wc == 0x1400 || /* Canadian syllabics hyphen */ + wc == 0x1806 || /* Mongolian todo hyphen */ + wc == 0x2010 || /* Hyphen */ + wc == 0x2027 || /* Hyphenation point */ + wc == 0x2e17 || /* Double oblique hyphen */ + wc == 0x2e40 || /* Double hyphen */ + wc == 0x30a0 || /* Katakana-Hiragana double hyphen */ + wc == 0xfe63 || /* Small hyphen-minus */ + wc == 0xff0d) /* Fullwidth hyphen-minus */ + need_hyphen[i] = FALSE; + else + need_hyphen[i] = TRUE; + break; + } } } @@ -3492,22 +3454,36 @@ break_needs_hyphen (PangoLayout *layout, } static int +find_hyphen_width (PangoItem *item) +{ + hb_font_t *hb_font; + hb_codepoint_t glyph; + + /* This is not technically correct, since + * a) we may end up inserting a different hyphen + * b) we should reshape the entire run + * But it is close enough in practice + */ + hb_font = pango_font_get_hb_font (item->analysis.font); + if (hb_font_get_nominal_glyph (hb_font, 0x2010, &glyph) || + hb_font_get_nominal_glyph (hb_font, '-', &glyph)) + return hb_font_get_glyph_h_advance (hb_font, glyph); + + return 0; +} + +static int find_break_extra_width (PangoLayout *layout, ParaBreakState *state, int pos) { - PangoItem *item = state->items->data; - /* Check whether to insert a hyphen */ if (break_needs_hyphen (layout, state, pos)) { if (state->hyphen_width < 0) { - PangoLayoutRun *run; - - run = create_hyphen_run (layout, item); - state->hyphen_width = pango_glyph_string_get_width (run->glyphs); - pango_glyph_item_free (run); + PangoItem *item = state->items->data; + state->hyphen_width = find_hyphen_width (item); } return state->hyphen_width; @@ -3516,23 +3492,6 @@ find_break_extra_width (PangoLayout *layout, return 0; } -static void -insert_hyphen_after (PangoLayoutLine *line, - ParaBreakState *state, - PangoItem *item) -{ - PangoLayout *layout = line->layout; - PangoLayoutRun *run; - - /* Use the SHY as text for the hyphen run */ - item->num_chars -= 1; - item->length -= 2; - run = create_hyphen_run (layout, item); - line->runs = g_slist_prepend (line->runs, run); - - state->remaining_width -= pango_glyph_string_get_width (run->glyphs); -} - #if 0 # define DEBUG debug void @@ -3713,10 +3672,9 @@ process_item (PangoLayout *layout, if (break_num_chars == item->num_chars) { - gboolean insert_hyphen = break_needs_hyphen (layout, state, break_num_chars); + if (break_needs_hyphen (layout, state, break_num_chars)) + item->analysis.flags |= PANGO_ANALYSIS_FLAG_NEED_HYPHEN; insert_run (line, state, item, TRUE); - if (insert_hyphen) - insert_hyphen_after (line, state, item); return BREAK_ALL_FIT; } @@ -3727,26 +3685,24 @@ process_item (PangoLayout *layout, else { PangoItem *new_item; - gboolean insert_hyphen = break_needs_hyphen (layout, state, break_num_chars); length = g_utf8_offset_to_pointer (layout->text + item->offset, break_num_chars) - (layout->text + item->offset); new_item = pango_item_split (item, length, break_num_chars); + if (break_needs_hyphen (layout, state, break_num_chars)) + new_item->analysis.flags |= PANGO_ANALYSIS_FLAG_NEED_HYPHEN; /* Add the width back, to the line, reshape, subtract the new width */ state->remaining_width += break_width; insert_run (line, state, new_item, FALSE); break_width = pango_glyph_string_get_width (((PangoGlyphItem *)(line->runs->data))->glyphs); state->remaining_width -= break_width; + state->log_widths_offset += break_num_chars; + /* Shaped items should never be broken */ g_assert (!shape_set); - if (insert_hyphen) - insert_hyphen_after (line, state, new_item); - - state->log_widths_offset += break_num_chars; - return BREAK_SOME_FIT; } } @@ -3994,44 +3950,23 @@ get_items_log_attrs (const char *text, int log_attrs_len) { int offset = 0; - int index = 0; - int num_bytes = 0; int num_chars = 0; - PangoAnalysis analysis = { NULL }; GList *l; - analysis.level = -1; - - pango_default_break (text, length, &analysis, log_attrs, log_attrs_len); + pango_default_break (text, length, NULL, log_attrs, log_attrs_len); for (l = items; l; l = l->next) { PangoItem *item = l->data; - if (l == items) - { - analysis = item->analysis; - index = item->offset; - offset = 0; - } + pango_tailor_break (text + item->offset, + item->length, + &item->analysis, + item->offset, + log_attrs + offset, + item->num_chars + 1); - if (can_break_together (&analysis, &item->analysis)) - { - num_bytes += item->length; - num_chars += item->num_chars; - } - else - { - pango_tailor_break (text + index, - num_bytes, - &analysis, - log_attrs + offset, - num_chars + 1); - - analysis = item->analysis; - index += num_bytes; - offset += num_chars; - } + offset += num_chars; } } @@ -4119,9 +4054,9 @@ no_break_filter_func (PangoAttribute *attribute, gpointer data G_GNUC_UNUSED) { static const PangoAttrType no_break_types[] = { - PANGO_ATTR_FONT_FEATURES + PANGO_ATTR_FONT_FEATURES, + PANGO_ATTR_ALLOW_BREAKS }; - int i; for (i = 0; i < (int)G_N_ELEMENTS (no_break_types); i++) diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 2c509dac..2b871584 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -153,6 +153,11 @@ * Fallback is enabled by default. Most applications should not * disable fallback. * + * allow_breaks + * : 'true' or 'false' whether to allow line breaks or not. If + * not allowed, the range will be kept in a single run as far + * as possible. Breaks are allowed by default. + * * lang * : A language code, indicating the text language * @@ -1297,6 +1302,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, const char *font_features = NULL; const char *alpha = NULL; const char *background_alpha = NULL; + const char *allow_breaks = NULL; g_markup_parse_context_get_position (context, &line_number, &char_number); @@ -1326,6 +1332,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, switch (names[i][0]) { case 'a': + CHECK_ATTRIBUTE (allow_breaks); CHECK_ATTRIBUTE (alpha); break; case 'b': @@ -1707,6 +1714,16 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, add_attribute (tag, pango_attr_font_features_new (font_features)); } + if (G_UNLIKELY (allow_breaks)) + { + gboolean b = FALSE; + + if (!span_parse_boolean ("allow_breaks", allow_breaks, &b, line_number, error)) + goto error; + + add_attribute (tag, pango_attr_allow_breaks_new (b)); + } + return TRUE; error: diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 17119436..0bb25ba5 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -861,7 +861,7 @@ extern gpointer get_gravity_class (void); static PangoGravity pango_fc_font_key_get_gravity (PangoFcFontKey *key) { - FcPattern *pattern; + const FcPattern *pattern; PangoGravity gravity = PANGO_GRAVITY_SOUTH; FcChar8 *s; @@ -878,7 +878,7 @@ pango_fc_font_key_get_gravity (PangoFcFontKey *key) static double get_font_size (PangoFcFontKey *key) { - FcPattern *pattern; + const FcPattern *pattern; double size; double dpi; diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c index 910ff4d7..12ce7ddb 100644 --- a/pango/pangofc-shape.c +++ b/pango/pangofc-shape.c @@ -158,6 +158,20 @@ pango_hb_shape (PangoFont *font, hb_buffer_set_flags (hb_buffer, HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT); hb_buffer_add_utf8 (hb_buffer, paragraph_text, paragraph_length, item_offset, item_length); + if (analysis->flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN) + { + /* Insert either a Unicode or ASCII hyphen. We may + * want to look for script-specific hyphens here. + */ + const char *p = paragraph_text + item_offset + item_length; + int last_char_len = p - g_utf8_prev_char (p); + hb_codepoint_t glyph; + + if (hb_font_get_nominal_glyph (hb_font, 0x2010, &glyph)) + hb_buffer_add (hb_buffer, 0x2010, item_length - last_char_len); + else if (hb_font_get_nominal_glyph (hb_font, '-', &glyph)) + hb_buffer_add (hb_buffer, '-', item_length - last_char_len); + } pango_font_get_features (font, features, G_N_ELEMENTS (features), &num_features); apply_extra_attributes (analysis->extra_attrs, features, G_N_ELEMENTS (features), &num_features); diff --git a/tests/breaks/one.expected b/tests/breaks/one.expected index d474c6e4..66c6bd48 100644 --- a/tests/breaks/one.expected +++ b/tests/breaks/one.expected @@ -1,5 +1,5 @@ -Text: a b c / d e f [ ] g h i [0xad] j k l . [ ] B l a [0x0a] -Breaks: c c c c lc c c c lc c c c lc c c c c lc c c c Lc -Whitespace: x x w w -Words: bs be bs be bs be b bs be b -Sentences: bs e bs e b +Text: a b c / d e f [ ] g h i [0xad] j k l . [ ] B l a [0x0a] +Breaks: c c c c lc c c c lc c c c lc c c c c lc c c c c +Whitespace: x x w w +Words: bs be bs be bs be b bs be b +Sentences: bs e bs e b diff --git a/tests/breaks/three.expected b/tests/breaks/three.expected index b7d8bd90..0e60f876 100644 --- a/tests/breaks/three.expected +++ b/tests/breaks/three.expected @@ -1,5 +1,5 @@ -Text: o n e [ ] t w o [0x2028] r e d [ ] b l u e[0x200d] g r e e n [0x0a] -Breaks: c c c c lc c c c Lc c c c lc c c c c c c c c c Lc -Whitespace: x w x w w -Words: bs be bs be bs be bs be b -Sentences: bs e bs e b +Text: o n e [ ] t w o [0x2028] r e d [ ] b l u e[0x200d] g r e e n [0x0a] +Breaks: c c c c lc c c c Lc c c c lc c c c c c c c c c c +Whitespace: x w x w w +Words: bs be bs be bs be bs be b +Sentences: bs e bs e b diff --git a/tests/breaks/two.expected b/tests/breaks/two.expected index cea1f884..7ff48c28 100644 --- a/tests/breaks/two.expected +++ b/tests/breaks/two.expected @@ -1,5 +1,5 @@ -Text: g o r i l · l e s [0x0a] -Breaks: c c c c c c c c c c Lc -Whitespace: w w -Words: bs e s be b -Sentences: bs e b +Text: g o r i l · l e s [0x0a] +Breaks: c c c c c c c c c c c +Whitespace: w w +Words: bs e s be b +Sentences: bs e b diff --git a/tests/layouts/valid-4.expected b/tests/layouts/valid-4.expected index d0ffe0ed..09f143f3 100644 --- a/tests/layouts/valid-4.expected +++ b/tests/layouts/valid-4.expected @@ -23,16 +23,14 @@ i=6, index=152, paragraph-start=1, dir=ltr '' --- runs -i=1, index=0, chars=29, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'This paragraph should actual' -i=2, index=30, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=common, language=en-us, '' -i=3, index=32, no run, line end -i=4, index=32, chars=31, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ly have multiple lines, unlike ' -i=5, index=63, no run, line end -i=6, index=63, chars=28, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'all the other wannabe äöü pa' -i=7, index=94, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=common, language=en-us, '' -i=8, index=96, no run, line end -i=9, index=96, chars=27, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ragraph tests in this ugh ' -i=10, index=124, no run, line end -i=11, index=124, chars=27, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'test-case. Grow some lines!' -i=12, index=151, no run, line end -i=13, index=152, no run, line end +i=1, index=0, chars=30, level=0, gravity=south, flags=4, font=OMITTED, script=latin, language=en-us, 'This paragraph should actual' +i=2, index=32, no run, line end +i=3, index=32, chars=31, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ly have multiple lines, unlike ' +i=4, index=63, no run, line end +i=5, index=63, chars=29, level=0, gravity=south, flags=4, font=OMITTED, script=latin, language=en-us, 'all the other wannabe äöü pa' +i=6, index=96, no run, line end +i=7, index=96, chars=27, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ragraph tests in this ugh ' +i=8, index=124, no run, line end +i=9, index=124, chars=27, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'test-case. Grow some lines!' +i=10, index=151, no run, line end +i=11, index=152, no run, line end diff --git a/tests/test-break.c b/tests/test-break.c index 00bc7be0..8549b678 100644 --- a/tests/test-break.c +++ b/tests/test-break.c @@ -41,13 +41,15 @@ test_file (const gchar *filename, GString *string) gsize length; GError *error = NULL; PangoLogAttr *attrs; - PangoLanguage *lang; int len; char *p; int i; GString *s1, *s2, *s3, *s4; int m; char *test; + char *text; + PangoAttrList *attributes; + PangoLayout *layout; if (!g_file_get_contents (filename, &contents, &length, &error)) { @@ -66,9 +68,17 @@ test_file (const gchar *filename, GString *string) len = g_utf8_strlen (test, -1) + 1; attrs = g_new (PangoLogAttr, len); - lang = pango_language_from_string ("en"); + if (!pango_parse_markup (test, -1, 0, &attributes, &text, NULL, &error)) + { + fprintf (stderr, "%s\n", error->message); + g_error_free (error); + return; + } - pango_get_log_attrs (test, length, -1, lang, attrs, len); + layout = pango_layout_new (context); + pango_layout_set_text (layout, text, length); + pango_layout_set_attributes (layout, attributes); + pango_layout_get_log_attrs (layout, &attrs, &len); s1 = g_string_new ("Breaks: "); s2 = g_string_new ("Whitespace: "); @@ -85,7 +95,7 @@ test_file (const gchar *filename, GString *string) g_string_append_printf (s4, "%*s", (int)(m - s4->len), ""); g_string_append_printf (string, "%*s", (int)(m - strlen ("Text: ")), ""); - for (i = 0, p = test; i < len; i++, p = g_utf8_next_char (p)) + for (i = 0, p = text; i < len; i++, p = g_utf8_next_char (p)) { PangoLogAttr log = attrs[i]; int b = 0; @@ -208,8 +218,10 @@ test_file (const gchar *filename, GString *string) g_string_free (s3, TRUE); g_string_free (s4, TRUE); + g_object_unref (layout); g_free (attrs); g_free (contents); + pango_attr_list_unref (attributes); } static gchar * @@ -270,7 +282,7 @@ main (int argc, char *argv[]) g_test_init (&argc, &argv, NULL); - context = pango_context_new (); + context = pango_font_map_create_context (pango_cairo_font_map_get_default ()); /* allow to easily generate expected output for new test cases */ if (argc > 1) diff --git a/tests/testiter.c b/tests/testiter.c index de3b462f..653c4bec 100644 --- a/tests/testiter.c +++ b/tests/testiter.c @@ -115,12 +115,19 @@ iter_char_test (PangoLayout *layout) if (run) { + PangoFontDescription *desc; + char *str; + /* Get needed data for the GlyphString */ pango_layout_iter_get_run_extents(iter, NULL, &run_extents); offset = run->item->offset; rtl = run->item->analysis.level%2; - verbose (" (current run: offset=%d,x=%d,len=%d,rtl=%d)\n", - offset, run_extents.x, run->item->length, rtl); + desc = pango_font_describe (run->item->analysis.font); + str = pango_font_description_to_string (desc); + verbose (" (current run: font=%s,offset=%d,x=%d,len=%d,rtl=%d)\n", + str, offset, run_extents.x, run->item->length, rtl); + g_free (str); + pango_font_description_free (desc); /* Calculate expected x result using index_to_x */ pango_glyph_string_index_to_x (run->glyphs, diff --git a/utils/test-hyphens.txt b/utils/test-hyphens.txt index de085d7f..65a6afc8 100644 --- a/utils/test-hyphens.txt +++ b/utils/test-hyphens.txt @@ -1,3 +1,3 @@ -A hyphenation algorithm is a set of rules, especially one codified for implementation in a computer program, that decides at which points a word can be broken over two lines with a hyphen. For example, a hyphenation algorithm might decide that impeachment can be broken as impeach‧ment or im‧peachment but not impe‧achment. +<span allow_breaks="false">A</span> hyphenation algorithm is a set of rules, especially one codified for implementation in a computer program, that decides at which points a word can be broken over two lines with a hyphen. For example, a hyphenation algorithm might decide that impeachment can be broken as <span allow_breaks="false">impeach‧ment</span> or <span allow_breaks="false">im‧peachment</span> but not <span allow_breaks="false">impe‧achment.</span> -One of the reasons for the complexity of the rules of wordbreaking is that different "dialects" of English tend to differ on hyphenation[citation needed]: American English tends to work on sound, but British English tends to look to the origins of the word and then to sound. There are also a large number of exceptions, which further complicates matters. +One of the reasons for the complexity of the rules of wordbreaking is that different "dialects" of English tend to differ on hyphenation [citation needed]: <span allow_breaks="false">American</span> English tends to work on sound, but British English tends to look to the origins of the word and then to sound. There are also a large number of exceptions, which further complicates matters. |