summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-12-07 04:28:00 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-12-07 04:28:00 +0000
commit8b46f5db285c6c661a2a7c28c5b354426a8d5c61 (patch)
tree12270307395f0e41111bbabeea783f75e3060b09
parent43470dcc035f8c8c3331cce380c834dcba7c2c89 (diff)
parentdc5b1fdea7d63277f2b31489896d1947f0511a24 (diff)
downloadpango-8b46f5db285c6c661a2a7c28c5b354426a8d5c61.tar.gz
Merge branch 'fix-tabs-nowrap' into 'main'
Fix line width computation Closes #635 See merge request GNOME/pango!535
-rw-r--r--pango/pango-layout.c27
-rw-r--r--tests/fonts/DejaVuSansMono.ttfbin0 -> 340712 bytes
-rw-r--r--tests/fonts/fonts.conf6
-rw-r--r--tests/layouts/tabs-nowrap.layout363
-rw-r--r--tests/layouts/valid-12.layout16
-rw-r--r--tests/layouts/valid-13.layout16
-rw-r--r--tests/meson.build1
7 files changed, 412 insertions, 17 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index ed46d57a..a495596c 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3662,6 +3662,31 @@ get_decimal_prefix_width (PangoItem *item,
g_free (log_widths);
}
+static int
+line_width (ParaBreakState *state,
+ PangoLayoutLine *line)
+{
+ GSList *l;
+ int i;
+ int width = 0;
+
+ if (state->remaining_width > -1)
+ return state->line_width - state->remaining_width;
+
+ /* Compute the width of the line currently - inefficient, but easier
+ * than keeping the current width of the line up to date everywhere
+ */
+ for (l = line->runs; l; l = l->next)
+ {
+ PangoLayoutRun *run = l->data;
+
+ for (i = 0; i < run->glyphs->num_glyphs; i++)
+ width += run->glyphs->glyphs[i].geometry.width;
+ }
+
+ return width;
+}
+
static PangoGlyphString *
shape_run (PangoLayoutLine *line,
ParaBreakState *state,
@@ -3671,7 +3696,7 @@ shape_run (PangoLayoutLine *line,
PangoGlyphString *glyphs = pango_glyph_string_new ();
if (layout->text[item->offset] == '\t')
- shape_tab (line, &state->last_tab, &state->properties, state->line_width - state->remaining_width, item, glyphs);
+ shape_tab (line, &state->last_tab, &state->properties, line_width (state, line), item, glyphs);
else
{
PangoShapeFlags shape_flags = PANGO_SHAPE_NONE;
diff --git a/tests/fonts/DejaVuSansMono.ttf b/tests/fonts/DejaVuSansMono.ttf
new file mode 100644
index 00000000..d723948f
--- /dev/null
+++ b/tests/fonts/DejaVuSansMono.ttf
Binary files differ
diff --git a/tests/fonts/fonts.conf b/tests/fonts/fonts.conf
index 5ff7022b..4308770b 100644
--- a/tests/fonts/fonts.conf
+++ b/tests/fonts/fonts.conf
@@ -62,4 +62,10 @@
<family>Noto Color Emoji</family>
</prefer>
</alias>
+
+ <alias>
+ <family>DejaVu Sans Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+
</fontconfig>
diff --git a/tests/layouts/tabs-nowrap.layout b/tests/layouts/tabs-nowrap.layout
new file mode 100644
index 00000000..4a1d40b5
--- /dev/null
+++ b/tests/layouts/tabs-nowrap.layout
@@ -0,0 +1,363 @@
+{
+ "context" : {
+ "font" : "serif 12",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0
+ ]
+ },
+ "comment" : "A case where tabs were broken if line wrapping is disabled.",
+ "text" : "123\t9\n123456789",
+ "attributes" : [
+ {
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "font" : "DejaVu Sans Mono 32",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 239616,
+ "height" : 239616,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 5,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 3,
+ "text" : "123",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "DejaVu Sans Mono 32",
+ "checksum" : "84c5467cadd1f6f23db0d9fbb6377e0d301334d3b5f36e6d5acebd34d0857d3a",
+ "matrix" : [
+ 1,
+ -0,
+ -0,
+ 1,
+ 0,
+ 0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 20,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 21,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 22,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ },
+ {
+ "offset" : 3,
+ "length" : 1,
+ "text" : "\t",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "DejaVu Sans Mono 32",
+ "checksum" : "84c5467cadd1f6f23db0d9fbb6377e0d301334d3b5f36e6d5acebd34d0857d3a",
+ "matrix" : [
+ 1,
+ -0,
+ -0,
+ 1,
+ 0,
+ 0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 268435455,
+ "width" : 133120,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 4,
+ "length" : 1,
+ "text" : "9",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "DejaVu Sans Mono 32",
+ "checksum" : "84c5467cadd1f6f23db0d9fbb6377e0d301334d3b5f36e6d5acebd34d0857d3a",
+ "matrix" : [
+ 1,
+ -0,
+ -0,
+ 1,
+ 0,
+ 0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 28,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 6,
+ "length" : 9,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 6,
+ "length" : 9,
+ "text" : "123456789",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "DejaVu Sans Mono 32",
+ "checksum" : "84c5467cadd1f6f23db0d9fbb6377e0d301334d3b5f36e6d5acebd34d0857d3a",
+ "matrix" : [
+ 1,
+ -0,
+ -0,
+ 1,
+ 0,
+ 0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 20,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 21,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 22,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 23,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 24,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 25,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 26,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 27,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 28,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/layouts/valid-12.layout b/tests/layouts/valid-12.layout
index 099813ce..3c09f51f 100644
--- a/tests/layouts/valid-12.layout
+++ b/tests/layouts/valid-12.layout
@@ -52,8 +52,8 @@
"is-wrapped" : true,
"is-ellipsized" : false,
"unknown-glyphs" : 1,
- "width" : 202752,
- "height" : 202752,
+ "width" : 179200,
+ "height" : 179200,
"log-attrs" : [
{
"char-break" : true,
@@ -258,7 +258,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -330,7 +330,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -402,7 +402,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 44032,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -554,7 +554,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -626,7 +626,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 46080,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -698,7 +698,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
diff --git a/tests/layouts/valid-13.layout b/tests/layouts/valid-13.layout
index bd0f04fa..cb2ac92a 100644
--- a/tests/layouts/valid-13.layout
+++ b/tests/layouts/valid-13.layout
@@ -53,8 +53,8 @@
"is-wrapped" : false,
"is-ellipsized" : false,
"unknown-glyphs" : 1,
- "width" : 386048,
- "height" : 386048,
+ "width" : 315392,
+ "height" : 315392,
"log-attrs" : [
{
"char-break" : true,
@@ -271,7 +271,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -355,7 +355,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -439,7 +439,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 44032,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -607,7 +607,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 17408,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -691,7 +691,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 46080,
"is-cluster-start" : true,
"log-cluster" : 0
}
@@ -775,7 +775,7 @@
"glyphs" : [
{
"glyph" : 268435455,
- "width" : 51200,
+ "width" : 43008,
"is-cluster-start" : true,
"log-cluster" : 0
}
diff --git a/tests/meson.build b/tests/meson.build
index 2acf0def..b15c7291 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -96,6 +96,7 @@ installed_test_layouts_data = [
'layouts/effigy.layout',
'layouts/kebab.layout',
'layouts/tabs.layout',
+ 'layouts/tabs-nowrap.layout',
'layouts/valid-1.layout',
'layouts/valid-2.layout',
'layouts/valid-3.layout',