Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |