diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c
index 94c616bb4..127499798 100644
--- a/src/document/html/renderer.c
+++ b/src/document/html/renderer.c
@@ -1108,7 +1108,13 @@ justify_line(struct html_context *html_context, int y)
int prev_end = 0;
int word;
- clear_hchars(html_context, 0, y, overlap(par_format));
+ /* Allocate enough memory for the justified line.
+ * If the memory is not available, then leave the
+ * line unchanged, rather than halfway there. The
+ * following loop assumes the allocation succeeded. */
+ if (!realloc_line(html_context, html_context->part->document,
+ Y(y), X(overlap(par_format))))
+ goto out_of_memory;
for (word = 0; word < spaces; word++) {
/* We have to increase line length by 'diff' num. of
@@ -1122,14 +1128,40 @@ justify_line(struct html_context *html_context, int y)
assert(word_len >= 0);
if_assert_failed continue;
- if (!word_len) continue;
word_shift = (word * diff) / (spaces - 1);
new_start = word_start + word_shift;
+ /* Copy the original word, without any spaces. */
copy_chars(html_context, new_start, y, word_len,
&line[word_start]);
+ /* Copy the space that preceded the word,
+ * duplicating it as many times as necessary.
+ * This preserves its attributes, such as
+ * background color and underlining. If this
+ * is the first word, then skip the copy
+ * because there might not be a space there
+ * and anyway it need not be duplicated. */
+ if (word) {
+ int spacex;
+
+ /* realloc_line() was called above. */
+ assert(LEN(y) >= new_start);
+ if_assert_failed continue;
+
+ for (spacex = prev_end; spacex < new_start;
+ ++spacex) {
+ copy_screen_chars(&POS(spacex, y),
+ &line[word_start - 1],
+ 1);
+ }
+ }
+
+ /* Remember that any links at the right side
+ * of the added spaces have moved, and the
+ * spaces themselves may also belong to a
+ * link. */
new_spaces = new_start - prev_end - 1;
if (word && new_spaces) {
move_links(html_context, prev_end + 1, y, new_start, y);
@@ -1141,6 +1173,7 @@ justify_line(struct html_context *html_context, int y)
}
}
+out_of_memory:
fmem_free(space_list);
fmem_free(line);
}