Merge lp:~widelands-dev/widelands/bug-1687043-multiline-edit into lp:widelands

Proposed by Notabilis
Status: Merged
Merged at revision: 8346
Proposed branch: lp:~widelands-dev/widelands/bug-1687043-multiline-edit
Merge into: lp:widelands
Diff against target: 147 lines (+36/-33)
2 files modified
src/graphic/wordwrap.cc (+26/-32)
src/graphic/wordwrap.h (+10/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1687043-multiline-edit
Reviewer Review Type Date Requested Status
Klaus Halfmann compile, test, regressiontest Approve
GunChleoc Approve
Review via email: mp+323428@code.launchpad.net

Description of the change

Fixed heavy memory leak in the WordWrap class. The problem was loading the font on every change without freeing it.
Also did some refactoring so the font is only loaded once per class. This fixes a noticeable slowdown while typing in multi-line edit boxes.

To post a comment you must log in.
Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Looks fine for me, will compile this and check some Mutiline text fields....

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2128. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/227161415.
Appveyor build 1963. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1687043_multiline_edit-1963.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Code LGTM too :)

review: Approve
Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Multilineedit fields are ok (even with German Umauts),
word wrap is a bit early. Lets go.

@bunnybot merge

review: Approve (compile, test, regressiontest)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/graphic/wordwrap.cc'
2--- src/graphic/wordwrap.cc 2017-03-25 15:32:49 +0000
3+++ src/graphic/wordwrap.cc 2017-04-29 15:04:08 +0000
4@@ -25,7 +25,6 @@
5
6 #include <SDL_ttf.h>
7 #include <boost/format.hpp>
8-#include <unicode/uchar.h>
9 #include <unicode/unistr.h>
10
11 #include "base/log.h"
12@@ -35,39 +34,13 @@
13 #include "graphic/rendertarget.h"
14 #include "graphic/text/bidi.h"
15 #include "graphic/text/font_io.h"
16-#include "graphic/text/sdl_ttf_font.h"
17 #include "graphic/text_layout.h"
18
19-namespace {
20-
21-/**
22- * Get a width estimate for text wrapping.
23- */
24-uint32_t quick_width(const UChar& c, int ptsize) {
25- // Editor font is sans bold.
26- RT::IFont* font = RT::load_font(UI::g_fh1->fontset()->sans_bold(), ptsize);
27- int result = 0;
28- TTF_GlyphMetrics(font->get_ttf_font(), c, nullptr, nullptr, nullptr, nullptr, &result);
29- return result;
30-}
31-
32-uint32_t quick_width(const std::string& text, int ptsize) {
33- int result = 0;
34- const icu::UnicodeString parseme(text.c_str(), "UTF-8");
35- for (int i = 0; i < parseme.length(); ++i) {
36- UChar c = parseme.charAt(i);
37- if (!i18n::is_diacritic(c)) {
38- result += quick_width(c, ptsize);
39- }
40- }
41- return result;
42-}
43-}
44-
45 namespace UI {
46
47 WordWrap::WordWrap(int fontsize, const RGBColor& color, uint32_t gwrapwidth)
48- : draw_caret_(false), fontsize_(fontsize), color_(color) {
49+ : draw_caret_(false), fontsize_(fontsize), color_(color),
50+ font_(RT::load_font(UI::g_fh1->fontset()->sans_bold(), fontsize_)) {
51 wrapwidth_ = gwrapwidth;
52
53 if (wrapwidth_ < std::numeric_limits<uint32_t>::max()) {
54@@ -101,7 +74,7 @@
55 lines_.clear();
56
57 std::string::size_type line_start = 0;
58- uint32_t margin = quick_width(0x2003, fontsize_); // Em space
59+ uint32_t margin = quick_width(0x2003); // Em space
60
61 while (line_start <= text.size()) {
62 std::string::size_type next_line_start;
63@@ -209,7 +182,7 @@
64 // Diacritics do not add to the line width
65 if (!i18n::is_diacritic(c)) {
66 // This only estimates the width
67- line_width += quick_width(c, fontsize_);
68+ line_width += quick_width(c);
69 }
70 unicode_line += c;
71 }
72@@ -247,7 +220,7 @@
73 bool WordWrap::line_fits(const std::string& text, uint32_t safety_margin) const {
74 // calc_width_for_wrapping is fast, but it will underestimate the width.
75 // So, we test again with text_width to make sure that the line really fits.
76- return quick_width(i18n::make_ligatures(text.c_str()), fontsize_) <=
77+ return quick_width(i18n::make_ligatures(text.c_str())) <=
78 wrapwidth_ - safety_margin &&
79 text_width(text, fontsize_) <= wrapwidth_ - safety_margin;
80 }
81@@ -361,4 +334,25 @@
82 }
83 }
84
85+/**
86+ * Get a width estimate for text wrapping.
87+ */
88+uint32_t WordWrap::quick_width(const UChar& c) const {
89+ int result = 0;
90+ TTF_GlyphMetrics(font_->get_ttf_font(), c, nullptr, nullptr, nullptr, nullptr, &result);
91+ return result;
92+}
93+
94+uint32_t WordWrap::quick_width(const std::string& text) const {
95+ int result = 0;
96+ const icu::UnicodeString parseme(text.c_str(), "UTF-8");
97+ for (int i = 0; i < parseme.length(); ++i) {
98+ UChar c = parseme.charAt(i);
99+ if (!i18n::is_diacritic(c)) {
100+ result += quick_width(c);
101+ }
102+ }
103+ return result;
104+}
105+
106 } // namespace UI
107
108=== modified file 'src/graphic/wordwrap.h'
109--- src/graphic/wordwrap.h 2017-03-25 15:32:49 +0000
110+++ src/graphic/wordwrap.h 2017-04-29 15:04:08 +0000
111@@ -19,13 +19,16 @@
112 #ifndef WL_GRAPHIC_WORDWRAP_H
113 #define WL_GRAPHIC_WORDWRAP_H
114
115+#include <memory>
116 #include <string>
117+#include <unicode/uchar.h>
118 #include <vector>
119
120 #include "base/vector.h"
121 #include "graphic/align.h"
122 #include "graphic/color.h"
123 #include "graphic/text_constants.h"
124+#include "graphic/text/sdl_ttf_font.h"
125
126 class RenderTarget;
127
128@@ -79,13 +82,19 @@
129
130 bool line_fits(const std::string& text, uint32_t safety_margin) const;
131
132+ uint32_t quick_width(const UChar& c) const;
133+ uint32_t quick_width(const std::string& text) const;
134+
135 uint32_t wrapwidth_;
136 bool draw_caret_;
137
138 // TODO(GunChleoc): We can tie these to constexpr once the old font renderer is gone.
139- int fontsize_;
140+ const int fontsize_;
141 RGBColor color_;
142
143+ // Editor font is sans bold.
144+ std::unique_ptr<RT::IFont> font_;
145+
146 std::vector<LineData> lines_;
147 };
148

Subscribers

People subscribed via source and target branches

to status/vote changes: