From 5d291dae7d6e036b4c67986f94cfcfe66ddf0905 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Sat, 12 Oct 2013 02:34:07 +0200 Subject: [PATCH] Proper bounds checking for line break positions. Closes #2037. --- src/text/layout.cpp | 16 ++-- ...xt-bug2037-800-300-1.0-grid-reference.json | 87 ++++++++++++++++++ ...text-bug2037-800-300-1.0-agg-reference.png | Bin 0 -> 3474 bytes ...xt-bug2037-800-300-1.0-cairo-reference.png | Bin 0 -> 2721 bytes ...text-bug2037-800-300-2.0-agg-reference.png | Bin 0 -> 9074 bytes ...xt-bug2037-800-300-2.0-cairo-reference.png | Bin 0 -> 7797 bytes tests/visual_tests/styles/text-bug2037.xml | 16 +++- 7 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 tests/visual_tests/grids/text-bug2037-800-300-1.0-grid-reference.json create mode 100644 tests/visual_tests/images/text-bug2037-800-300-1.0-agg-reference.png create mode 100644 tests/visual_tests/images/text-bug2037-800-300-1.0-cairo-reference.png create mode 100644 tests/visual_tests/images/text-bug2037-800-300-2.0-agg-reference.png create mode 100644 tests/visual_tests/images/text-bug2037-800-300-2.0-cairo-reference.png diff --git a/src/text/layout.cpp b/src/text/layout.cpp index 732cef1f7..61b99387b 100644 --- a/src/text/layout.cpp +++ b/src/text/layout.cpp @@ -95,7 +95,7 @@ void text_layout::break_line(text_line_ptr line, double wrap_width, unsigned tex breakitr->setText(text); double current_line_length = 0; - unsigned last_break_position = 0; + unsigned last_break_position = line->first_char(); for (unsigned i=line->first_char(); ilast_char(); i++) { //TODO: character_spacing @@ -109,11 +109,8 @@ void text_layout::break_line(text_line_ptr line, double wrap_width, unsigned tex unsigned break_position = wrap_before ? breakitr->preceding(i) : breakitr->following(i); - /* Break iterator operates on the whole string, while we only look at one line. So we need to - * clamp break values. */ - if (break_position < line->first_char()) break_position = line->first_char(); - if (break_position > line->last_char()) break_position = line->last_char(); - + /* following() returns a break position after the last word. So DONE should only be returned + * when calling preceding. */ if (break_position <= last_break_position || break_position == BreakIterator::DONE) { //A single word is longer than the maximum line width. @@ -125,6 +122,11 @@ void text_layout::break_line(text_line_ptr line, double wrap_width, unsigned tex MAPNIK_LOG_WARN(text_layout) << "Unexpected result in break_line. Trying to recover...\n"; } } + /* Break iterator operates on the whole string, while we only look at one line. So we need to + * clamp break values. */ + if (break_position < line->first_char()) break_position = line->first_char(); + if (break_position > line->last_char()) break_position = line->last_char(); + text_line_ptr new_line = boost::make_shared(last_break_position, break_position); clear_cluster_widths(last_break_position, break_position); shape_text(new_line); @@ -133,7 +135,7 @@ void text_layout::break_line(text_line_ptr line, double wrap_width, unsigned tex i = break_position - 1; current_line_length = 0; } - if (last_break_position == 0) + if (last_break_position == line->first_char()) { //No line breaks => no reshaping required add_line(line); diff --git a/tests/visual_tests/grids/text-bug2037-800-300-1.0-grid-reference.json b/tests/visual_tests/grids/text-bug2037-800-300-1.0-grid-reference.json new file mode 100644 index 000000000..270ee2c4b --- /dev/null +++ b/tests/visual_tests/grids/text-bug2037-800-300-1.0-grid-reference.json @@ -0,0 +1,87 @@ +{ + "keys": [ + "", + "7", + "3", + "4", + "8" + ], + "data": {}, + "grid": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ! !!!!!!!!!! ", + " ## #### $$ $$$$ !!!! ! !!! ", + " ###### $$$$$$ ! %% % ", + " # $ !!! % % %%%%%% ", + " ## # $$ $ ", + " # $ !!!! %%%%% %%%% ", + " # ## ## $ $$ $$ !! !! %%% %% ", + " ## # ## $$ $ $$ ! ! % % ", + " ! !!! % %%% ", + " ### # $$$ $ ", + " !!!! % %% % %%%%% ", + " ### # $$$ $ !!!! % %% % %%%% ", + " #### $$$$ ", + " !!!!!! ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ] +} \ No newline at end of file diff --git a/tests/visual_tests/images/text-bug2037-800-300-1.0-agg-reference.png b/tests/visual_tests/images/text-bug2037-800-300-1.0-agg-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..35327336b4aac492ab4b683bf0b1eb96231970ab GIT binary patch literal 3474 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 literal 0 HcmV?d00001 diff --git a/tests/visual_tests/images/text-bug2037-800-300-1.0-cairo-reference.png b/tests/visual_tests/images/text-bug2037-800-300-1.0-cairo-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..5fdc79f4abf86cc68735d3f5448c9771c18b7c16 GIT binary patch literal 2721 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 avir_yPUmgFBtOsWxp@tIwes@skNzKwR%2EG literal 0 HcmV?d00001 diff --git a/tests/visual_tests/images/text-bug2037-800-300-2.0-cairo-reference.png b/tests/visual_tests/images/text-bug2037-800-300-2.0-cairo-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..f8aa12c284277a8c31465882536ca3ff2c5d6026 GIT binary patch literal 7797 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 \ No newline at end of file