Merge lp:~widelands-dev/widelands/bug-1738760-fh1-newlines into lp:widelands

Proposed by Notabilis
Status: Merged
Merged at revision: 8608
Proposed branch: lp:~widelands-dev/widelands/bug-1738760-fh1-newlines
Merge into: lp:widelands
Diff against target: 215 lines (+52/-35)
1 file modified
src/graphic/text/rt_render.cc (+52/-35)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1738760-fh1-newlines
Reviewer Review Type Date Requested Status
Widelands Developers Pending
Review via email: mp+339495@code.launchpad.net

Commit message

Fixing incorrect layout of div's with width=fill when the previous div is wider than 50%.
Fixing superfluous space characters at beginning and end of lines.

Description of the change

Fixing incorrect layout of div's with width=fill when the previous div is wider than 50%. For testing, see changes in
https://bazaar.launchpad.net/~widelands-dev/widelands/bug-1738760-fh1-newlines/revision/8589
With trunk this leads to a second line, with this branch nothing happens optically as long as the percentage does not become too big.

Fixing superfluous space characters at beginning and end of lines. See the Tips section in the ingame or editor help for the ragged left edge.

when testing, please also check whether any other text or menus become broken in this branch.

To post a comment you must log in.
Revision history for this message
GunChleoc (gunchleoc) wrote :

Testing done :)

@bunnybot merge

In case you're a glutton for punishment, text floating around images would be nice too https://bugs.launchpad.net/widelands/+bug/1751620

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3247. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/345913522.
Appveyor build 3056. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1738760_fh1_newlines-3056.

Revision history for this message
Notabilis (notabilis27) wrote :

Thanks for testing.

And you sure know how to persuade people... :D

Revision history for this message
GunChleoc (gunchleoc) wrote :

Yep *lol*

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/graphic/text/rt_render.cc'
2--- src/graphic/text/rt_render.cc 2018-01-04 13:55:25 +0000
3+++ src/graphic/text/rt_render.cc 2018-02-25 11:52:24 +0000
4@@ -52,8 +52,6 @@
5 #include "io/filesystem/filesystem_exceptions.h"
6 #include "io/filesystem/layered_filesystem.h"
7
8-// TODO(GunChleoc): text line can start with space text node when it's within a div.
9-// https://bugs.launchpad.net/widelands/+bug/1738759
10 namespace RT {
11
12 static const uint16_t INFINITE_WIDTH = 65535; // 2^16-1
13@@ -308,7 +306,7 @@
14 uint16_t fit_nodes(std::vector<std::shared_ptr<RenderNode>>* rv,
15 uint16_t w,
16 Borders p,
17- bool shrink_to_fit);
18+ bool trim_spaces);
19
20 private:
21 // Represents a change in the rendering constraints. For example when an
22@@ -327,7 +325,7 @@
23 uint16_t fit_line(uint16_t w,
24 const Borders&,
25 std::vector<std::shared_ptr<RenderNode>>* rv,
26- bool shrink_to_fit);
27+ bool trim_spaces);
28
29 uint16_t h_;
30 size_t idx_;
31@@ -338,11 +336,11 @@
32 uint16_t Layout::fit_line(uint16_t w,
33 const Borders& p,
34 std::vector<std::shared_ptr<RenderNode>>* rv,
35- bool shrink_to_fit) {
36+ bool trim_spaces) {
37 assert(rv->empty());
38
39 // Remove leading spaces
40- while (idx_ < all_nodes_.size() && all_nodes_[idx_]->is_non_mandatory_space() && shrink_to_fit) {
41+ while (idx_ < all_nodes_.size() && all_nodes_[idx_]->is_non_mandatory_space() && trim_spaces) {
42 all_nodes_[idx_++].reset();
43 }
44
45@@ -366,7 +364,7 @@
46 ++idx_;
47 }
48 // Remove trailing spaces
49- while (!rv->empty() && rv->back()->is_non_mandatory_space() && shrink_to_fit) {
50+ while (!rv->empty() && rv->back()->is_non_mandatory_space() && trim_spaces) {
51 x -= rv->back()->width();
52 rv->pop_back();
53 }
54@@ -420,7 +418,7 @@
55 uint16_t Layout::fit_nodes(std::vector<std::shared_ptr<RenderNode>>* rv,
56 uint16_t w,
57 Borders p,
58- bool shrink_to_fit) {
59+ bool trim_spaces) {
60 assert(rv->empty());
61 h_ = p.top;
62
63@@ -428,7 +426,7 @@
64 while (idx_ < all_nodes_.size()) {
65 std::vector<std::shared_ptr<RenderNode>> nodes_in_line;
66 size_t idx_before_iteration_ = idx_;
67- uint16_t biggest_hotspot = fit_line(w, p, &nodes_in_line, shrink_to_fit);
68+ uint16_t biggest_hotspot = fit_line(w, p, &nodes_in_line, trim_spaces);
69
70 int line_height = 0;
71 int line_start = INFINITE_WIDTH;
72@@ -679,12 +677,6 @@
73 return 0;
74 }
75 std::shared_ptr<UI::RenderedText> render(TextureCache* /* texture_cache */) override {
76- // TODO(GunChleoc): When using div width=*, some newline nodes are not being consumed.
77- // Since it is working as expected otherwise and I can't find the problem, let's fix this some
78- // other time.
79- // Testing can be done with the editor terrains/trees help
80- // https://bugs.launchpad.net/widelands/+bug/1738760
81- // NEVER_HERE();
82 return std::shared_ptr<UI::RenderedText>(new UI::RenderedText());
83 }
84 bool is_non_mandatory_space() const override {
85@@ -826,9 +818,6 @@
86 }
87
88 for (std::shared_ptr<RenderNode> n : nodes_to_render_) {
89- // TODO(GunChleoc): With div width=*, we are getting newline nodes here, which should have
90- // been consumed
91- // https://bugs.launchpad.net/widelands/+bug/1738760
92 const auto& renderme = n->render(texture_cache);
93 for (auto& rendered_rect : renderme->rects) {
94 if (rendered_rect->was_visited()) {
95@@ -1091,8 +1080,9 @@
96 *c->tag, font_cache_, nodestyle_, image_cache_, renderer_style_, fontsets_));
97 th->enter();
98 th->emit_nodes(nodes);
99- } else
100+ } else {
101 make_text_nodes(c->text, nodes, nodestyle_);
102+ }
103 }
104 }
105
106@@ -1343,6 +1333,7 @@
107 bool shrink_to_fit = true)
108 : TagHandler(tag, fc, ns, image_cache, init_renderer_style, fontsets),
109 shrink_to_fit_(shrink_to_fit),
110+ trim_spaces_(true),
111 w_(max_w),
112 render_node_(new DivTagRenderNode(ns)) {
113 }
114@@ -1379,33 +1370,61 @@
115 }
116
117 std::vector<std::shared_ptr<RenderNode>> subnodes;
118+ // If a percentage width is used, temporarily set it as the overall width. This way, divs with
119+ // width "fill" only use the width of their parent node. Also, percentages given in child nodes
120+ // are relative to the width of their parent node.
121+ const uint16_t old_overall_width = renderer_style_.overall_width;
122+ if (render_node_->desired_width().unit == WidthUnit::kPercent) {
123+ renderer_style_.overall_width =
124+ render_node_->desired_width().width * renderer_style_.overall_width / 100;
125+ }
126 TagHandler::emit_nodes(subnodes);
127+ renderer_style_.overall_width = old_overall_width;
128
129- if (!w_) { // Determine the width by the width of the widest subnode
130- for (std::shared_ptr<RenderNode> n : subnodes) {
131- if (n->width() >= INFINITE_WIDTH)
132- continue;
133- w_ = std::max<int>(w_, n->width() + padding.left + padding.right);
134- }
135+ // Determine the width by the width of the widest subnode
136+ uint16_t width_first_subnode = INFINITE_WIDTH;
137+ uint16_t widest_subnode = 0;
138+ for (std::shared_ptr<RenderNode> n : subnodes) {
139+ if (n->width() >= INFINITE_WIDTH) {
140+ continue;
141+ }
142+ if (width_first_subnode >= INFINITE_WIDTH && n->width() > 0) {
143+ width_first_subnode = n->width() + padding.left + padding.right;
144+ }
145+ widest_subnode = std::max<int>(widest_subnode, n->width() + padding.left + padding.right);
146+ }
147+ if (renderer_style_.remaining_width < width_first_subnode) {
148+ // Not enough space for first subnode. Move to next line
149+ renderer_style_.remaining_width = renderer_style_.overall_width;
150 }
151
152 switch (render_node_->desired_width().unit) {
153 case WidthUnit::kPercent:
154 w_ = render_node_->desired_width().width * renderer_style_.overall_width / 100;
155- renderer_style_.remaining_width -= w_;
156+
157+ // Reduce remaining width
158+ if (renderer_style_.remaining_width <= w_) {
159+ // Not enough space. Div will be placed in the next line, calculate the remaining space there
160+ renderer_style_.remaining_width = renderer_style_.overall_width - w_;
161+ } else {
162+ renderer_style_.remaining_width -= w_;
163+ }
164 break;
165 case WidthUnit::kFill:
166 w_ = renderer_style_.remaining_width;
167 renderer_style_.remaining_width = 0;
168 break;
169- default:; // Do nothing
170+ default:
171+ if (!w_) {
172+ w_ = widest_subnode;
173+ }
174+ // Else do nothing
175 }
176
177 // Layout takes ownership of subnodes
178 Layout layout(subnodes);
179 std::vector<std::shared_ptr<RenderNode>> nodes_to_render;
180-
181- uint16_t max_line_width = layout.fit_nodes(&nodes_to_render, w_, padding, shrink_to_fit_);
182+ uint16_t max_line_width = layout.fit_nodes(&nodes_to_render, w_, padding, trim_spaces_);
183 uint16_t extra_width = 0;
184 if (w_ < INFINITE_WIDTH && w_ > max_line_width) {
185 extra_width = w_ - max_line_width;
186@@ -1437,10 +1456,6 @@
187 w_ = max_line_width;
188 }
189
190- if (renderer_style_.remaining_width < w_) {
191- renderer_style_.remaining_width = renderer_style_.overall_width;
192- }
193-
194 render_node_->set_dimensions(w_, layout.height(), margin);
195 render_node_->set_nodes_to_render(nodes_to_render);
196 }
197@@ -1496,6 +1511,8 @@
198
199 protected:
200 bool shrink_to_fit_;
201+ // Always true for DivTagHandler but might be overwritten in RTTagHandler
202+ bool trim_spaces_;
203
204 private:
205 uint16_t w_;
206@@ -1518,8 +1535,8 @@
207 void handle_unique_attributes() override {
208 const AttrMap& a = tag_.attrs();
209 WordSpacerNode::show_spaces(a.has("db_show_spaces") ? a["db_show_spaces"].get_bool() : 0);
210- shrink_to_fit_ =
211- shrink_to_fit_ && (a.has("keep_spaces") ? !a["keep_spaces"].get_bool() : true);
212+ trim_spaces_ = (a.has("keep_spaces") ? !a["keep_spaces"].get_bool() : true);
213+ shrink_to_fit_ = shrink_to_fit_ && trim_spaces_;
214 }
215 };
216

Subscribers

People subscribed via source and target branches

to status/vote changes: