Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: ui/views/controls/styled_label.cc

Issue 2348433002: Make styled-label trimming less agressive, allowing whitespace (Closed)
Patch Set: Refactoring: de-duplicated wrap to new line code in styled label credits to estade for code suggest… Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/styled_label.h" 5 #include "ui/views/controls/styled_label.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <vector> 10 #include <vector>
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 // The x position (in pixels) of the line we're on, relative to content 249 // The x position (in pixels) of the line we're on, relative to content
250 // bounds. 250 // bounds.
251 int x = 0; 251 int x = 0;
252 int total_height = 0; 252 int total_height = 0;
253 // The width that was actually used. Guaranteed to be no larger than |width|. 253 // The width that was actually used. Guaranteed to be no larger than |width|.
254 int used_width = 0; 254 int used_width = 0;
255 255
256 base::string16 remaining_string = text_; 256 base::string16 remaining_string = text_;
257 StyleRanges::const_iterator current_range = style_ranges_.begin(); 257 StyleRanges::const_iterator current_range = style_ranges_.begin();
258 258
259 bool first_loop_iteration = true;
260
259 // Iterate over the text, creating a bunch of labels and links and laying them 261 // Iterate over the text, creating a bunch of labels and links and laying them
260 // out in the appropriate positions. 262 // out in the appropriate positions.
261 while (!remaining_string.empty()) { 263 while (!remaining_string.empty()) {
262 // Don't put whitespace at beginning of a line with an exception for the 264 if (x == 0 && !first_loop_iteration) {
263 // first line (so the text's leading whitespace is respected). 265 if (remaining_string.front() == L'\n') {
264 if (x == 0 && line > 0) { 266 // Wrapped to the next line on \n, remove it. Other whitespace,
265 base::TrimWhitespace(remaining_string, base::TRIM_LEADING, 267 // eg, spaces to indent next line, are preserved.
266 &remaining_string); 268 remaining_string.erase(0, 1);
269 } else {
270 // Wrapped on whitespace character or characters in the middle of the
271 // line - none of them are needed at the beginning of the next line.
272 base::TrimWhitespace(remaining_string, base::TRIM_LEADING,
273 &remaining_string);
274 }
267 } 275 }
276 first_loop_iteration = false;
268 277
269 gfx::Range range(gfx::Range::InvalidRange()); 278 gfx::Range range(gfx::Range::InvalidRange());
270 if (current_range != style_ranges_.end()) 279 if (current_range != style_ranges_.end())
271 range = current_range->range; 280 range = current_range->range;
272 281
273 const size_t position = text_.size() - remaining_string.size(); 282 const size_t position = text_.size() - remaining_string.size();
274 283
275 const gfx::Rect chunk_bounds(x, 0, width - x, 2 * line_height); 284 const gfx::Rect chunk_bounds(x, 0, width - x, 2 * line_height);
276 std::vector<base::string16> substrings; 285 std::vector<base::string16> substrings;
277 gfx::FontList text_font_list = font_list_; 286 gfx::FontList text_font_list = font_list_;
278 // If the start of the remaining text is inside a styled range, the font 287 // If the start of the remaining text is inside a styled range, the font
279 // style may differ from the base font. The font specified by the range 288 // style may differ from the base font. The font specified by the range
280 // should be used when eliding text. 289 // should be used when eliding text.
281 if (position >= range.start()) { 290 if (position >= range.start()) {
282 text_font_list = 291 text_font_list =
283 text_font_list.Derive(0, current_range->style_info.font_style, 292 text_font_list.Derive(0, current_range->style_info.font_style,
284 current_range->style_info.weight); 293 current_range->style_info.weight);
285 } 294 }
286 gfx::ElideRectangleText(remaining_string, 295 gfx::ElideRectangleText(remaining_string,
287 text_font_list, 296 text_font_list,
288 chunk_bounds.width(), 297 chunk_bounds.width(),
289 chunk_bounds.height(), 298 chunk_bounds.height(),
290 gfx::WRAP_LONG_WORDS, 299 gfx::WRAP_LONG_WORDS,
291 &substrings); 300 &substrings);
292 301
293 if (substrings.empty() || substrings[0].empty()) { 302 if (substrings.empty()) {
303 // there is no room for anything; abort.
304 break;
305 }
306 if (substrings[0].empty()) {
307 x = 0;
294 // Nothing fits on this line. Start a new line. 308 // Nothing fits on this line. Start a new line.
295 // If x is 0, first line may have leading whitespace that doesn't fit in a 309 // As for the first line, don't advance line number so that it will be
Evan Stade 2016/12/15 00:02:36 nit: instead of "it will be handled again" perhaps
296 // single line, so try trimming those. Otherwise there is no room for 310 // handled again at the beginning of the loop.
297 // anything; abort. 311 if (line > 0) {
298 if (x == 0) { 312 ++line;
299 if (line == 0) {
300 base::TrimWhitespace(remaining_string, base::TRIM_LEADING,
301 &remaining_string);
302 continue;
303 }
304 break;
305 } 313 }
306
307 x = 0;
308 line++;
309 continue; 314 continue;
310 } 315 }
311 316
312 base::string16 chunk = substrings[0]; 317 base::string16 chunk = substrings[0];
313 318
314 std::unique_ptr<Label> label; 319 std::unique_ptr<Label> label;
315 if (position >= range.start()) { 320 if (position >= range.start()) {
316 const RangeStyleInfo& style_info = current_range->style_info; 321 const RangeStyleInfo& style_info = current_range->style_info;
317 322
318 if (style_info.disable_line_wrapping && chunk.size() < range.length() && 323 if (style_info.disable_line_wrapping && chunk.size() < range.length() &&
319 position == range.start() && x != 0) { 324 position == range.start() && x != 0) {
320 // If the chunk should not be wrapped, try to fit it entirely on the 325 // If the chunk should not be wrapped, try to fit it entirely on the
321 // next line. 326 // next line.
322 x = 0; 327 x = 0;
323 line++; 328 ++line;
324 continue; 329 continue;
325 } 330 }
326 331
327 if (chunk.size() > range.end() - position) 332 if (chunk.size() > range.end() - position)
328 chunk = chunk.substr(0, range.end() - position); 333 chunk = chunk.substr(0, range.end() - position);
329 334
330 label = CreateLabelRange(chunk, font_list_, style_info, this); 335 label = CreateLabelRange(chunk, font_list_, style_info, this);
331 336
332 if (style_info.is_link && !dry_run) 337 if (style_info.is_link && !dry_run)
333 link_targets_[label.get()] = range; 338 link_targets_[label.get()] = range;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 378
374 remaining_string = remaining_string.substr(chunk.size()); 379 remaining_string = remaining_string.substr(chunk.size());
375 } 380 }
376 381
377 DCHECK_LE(used_width, width); 382 DCHECK_LE(used_width, width);
378 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height); 383 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height);
379 return calculated_size_; 384 return calculated_size_;
380 } 385 }
381 386
382 } // namespace views 387 } // namespace views
OLDNEW
« no previous file with comments | « components/autofill/core/browser/legal_message_line.h ('k') | ui/views/controls/styled_label_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698