OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <climits> | 8 #include <climits> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 | 524 |
525 void RenderText::SetElideBehavior(ElideBehavior elide_behavior) { | 525 void RenderText::SetElideBehavior(ElideBehavior elide_behavior) { |
526 // TODO(skanuj) : Add a test for triggering layout change. | 526 // TODO(skanuj) : Add a test for triggering layout change. |
527 if (elide_behavior_ != elide_behavior) { | 527 if (elide_behavior_ != elide_behavior) { |
528 elide_behavior_ = elide_behavior; | 528 elide_behavior_ = elide_behavior; |
529 OnDisplayTextAttributeChanged(); | 529 OnDisplayTextAttributeChanged(); |
530 } | 530 } |
531 } | 531 } |
532 | 532 |
533 void RenderText::SetDisplayRect(const Rect& r) { | 533 void RenderText::SetDisplayRect(const Rect& r) { |
| 534 DLOG(INFO) << "in SetDisplayRect."; |
534 if (r != display_rect_) { | 535 if (r != display_rect_) { |
535 display_rect_ = r; | 536 display_rect_ = r; |
536 baseline_ = kInvalidBaseline; | 537 baseline_ = kInvalidBaseline; |
537 cached_bounds_and_offset_valid_ = false; | 538 cached_bounds_and_offset_valid_ = false; |
538 lines_.clear(); | 539 lines_.clear(); |
539 if (elide_behavior_ != NO_ELIDE && | 540 if (elide_behavior_ != NO_ELIDE && |
540 elide_behavior_ != FADE_TAIL) { | 541 elide_behavior_ != FADE_TAIL) { |
| 542 DLOG(INFO) << "via set display rect: " << GetDisplayText(); |
541 OnDisplayTextAttributeChanged(); | 543 OnDisplayTextAttributeChanged(); |
542 } | 544 } |
543 } | 545 } |
544 } | 546 } |
545 | 547 |
546 void RenderText::SetCursorPosition(size_t position) { | 548 void RenderText::SetCursorPosition(size_t position) { |
547 MoveCursorTo(position, false); | 549 MoveCursorTo(position, false); |
548 } | 550 } |
549 | 551 |
550 void RenderText::MoveCursor(BreakType break_type, | 552 void RenderText::MoveCursor(BreakType break_type, |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 int RenderText::GetBaseline() { | 746 int RenderText::GetBaseline() { |
745 if (baseline_ == kInvalidBaseline) | 747 if (baseline_ == kInvalidBaseline) |
746 baseline_ = DetermineBaselineCenteringText(display_rect(), font_list()); | 748 baseline_ = DetermineBaselineCenteringText(display_rect(), font_list()); |
747 DCHECK_NE(kInvalidBaseline, baseline_); | 749 DCHECK_NE(kInvalidBaseline, baseline_); |
748 return baseline_; | 750 return baseline_; |
749 } | 751 } |
750 | 752 |
751 void RenderText::Draw(Canvas* canvas) { | 753 void RenderText::Draw(Canvas* canvas) { |
752 EnsureLayout(); | 754 EnsureLayout(); |
753 | 755 |
| 756 DLOG(INFO) << "Draw: " << GetDisplayText(); |
| 757 |
754 if (clip_to_display_rect()) { | 758 if (clip_to_display_rect()) { |
755 Rect clip_rect(display_rect()); | 759 Rect clip_rect(display_rect()); |
756 clip_rect.Inset(ShadowValue::GetMargin(shadows_)); | 760 clip_rect.Inset(ShadowValue::GetMargin(shadows_)); |
757 | 761 |
758 canvas->Save(); | 762 canvas->Save(); |
759 canvas->ClipRect(clip_rect); | 763 canvas->ClipRect(clip_rect); |
760 } | 764 } |
761 | 765 |
762 if (!text().empty() && focused()) | 766 if (!text().empty() && focused()) |
763 DrawSelection(canvas); | 767 DrawSelection(canvas); |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 if (!multiline_ && replace_newline_chars_with_symbols_) | 1275 if (!multiline_ && replace_newline_chars_with_symbols_) |
1272 base::ReplaceChars(layout_text_, kNewline, kNewlineSymbol, &layout_text_); | 1276 base::ReplaceChars(layout_text_, kNewline, kNewlineSymbol, &layout_text_); |
1273 | 1277 |
1274 OnLayoutTextAttributeChanged(true); | 1278 OnLayoutTextAttributeChanged(true); |
1275 } | 1279 } |
1276 | 1280 |
1277 base::string16 RenderText::Elide(const base::string16& text, | 1281 base::string16 RenderText::Elide(const base::string16& text, |
1278 float text_width, | 1282 float text_width, |
1279 float available_width, | 1283 float available_width, |
1280 ElideBehavior behavior) { | 1284 ElideBehavior behavior) { |
| 1285 DLOG(INFO) << "Elide: '" << text << "' " << text_width << ", " << available_wi
dth << ", " << behavior; |
1281 if (available_width <= 0 || text.empty()) | 1286 if (available_width <= 0 || text.empty()) |
1282 return base::string16(); | 1287 return base::string16(); |
1283 if (behavior == ELIDE_EMAIL) | 1288 if (behavior == ELIDE_EMAIL) |
1284 return ElideEmail(text, available_width); | 1289 return ElideEmail(text, available_width); |
1285 if (text_width > 0 && text_width < available_width) | 1290 if (text_width > 0 && text_width < available_width) |
1286 return text; | 1291 return text; |
1287 | 1292 |
1288 TRACE_EVENT0("ui", "RenderText::Elide"); | 1293 TRACE_EVENT0("ui", "RenderText::Elide"); |
1289 | 1294 |
1290 // Create a RenderText copy with attributes that affect the rendering width. | 1295 // Create a RenderText copy with attributes that affect the rendering width. |
(...skipping 12 matching lines...) Expand all Loading... |
1303 return text; | 1308 return text; |
1304 | 1309 |
1305 const base::string16 ellipsis = base::string16(kEllipsisUTF16); | 1310 const base::string16 ellipsis = base::string16(kEllipsisUTF16); |
1306 const bool insert_ellipsis = (behavior != TRUNCATE); | 1311 const bool insert_ellipsis = (behavior != TRUNCATE); |
1307 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); | 1312 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); |
1308 const bool elide_at_beginning = (behavior == ELIDE_HEAD); | 1313 const bool elide_at_beginning = (behavior == ELIDE_HEAD); |
1309 | 1314 |
1310 if (insert_ellipsis) { | 1315 if (insert_ellipsis) { |
1311 render_text->SetText(ellipsis); | 1316 render_text->SetText(ellipsis); |
1312 const float ellipsis_width = render_text->GetContentWidthF(); | 1317 const float ellipsis_width = render_text->GetContentWidthF(); |
| 1318 DLOG(INFO) << " added elipsis of width: " << ellipsis_width; |
1313 if (ellipsis_width > available_width) | 1319 if (ellipsis_width > available_width) |
1314 return base::string16(); | 1320 return base::string16(); |
1315 } | 1321 } |
1316 | 1322 |
1317 StringSlicer slicer(text, ellipsis, elide_in_middle, elide_at_beginning); | 1323 StringSlicer slicer(text, ellipsis, elide_in_middle, elide_at_beginning); |
1318 | 1324 |
1319 // Use binary search to compute the elided text. | 1325 // Use binary search to compute the elided text. |
1320 size_t lo = 0; | 1326 size_t lo = 0; |
1321 size_t hi = text.length() - 1; | 1327 size_t hi = text.length() - 1; |
1322 const base::i18n::TextDirection text_direction = GetTextDirection(text); | 1328 const base::i18n::TextDirection text_direction = GetTextDirection(text); |
(...skipping 15 matching lines...) Expand all Loading... |
1338 base::i18n::TextDirection trailing_text_direction = | 1344 base::i18n::TextDirection trailing_text_direction = |
1339 base::i18n::GetLastStrongCharacterDirection(new_text); | 1345 base::i18n::GetLastStrongCharacterDirection(new_text); |
1340 new_text.append(ellipsis); | 1346 new_text.append(ellipsis); |
1341 if (trailing_text_direction != text_direction) { | 1347 if (trailing_text_direction != text_direction) { |
1342 if (trailing_text_direction == base::i18n::LEFT_TO_RIGHT) | 1348 if (trailing_text_direction == base::i18n::LEFT_TO_RIGHT) |
1343 new_text += base::i18n::kLeftToRightMark; | 1349 new_text += base::i18n::kLeftToRightMark; |
1344 else | 1350 else |
1345 new_text += base::i18n::kRightToLeftMark; | 1351 new_text += base::i18n::kRightToLeftMark; |
1346 } | 1352 } |
1347 render_text->SetText(new_text); | 1353 render_text->SetText(new_text); |
| 1354 DLOG(INFO) << "text set to: " << new_text; |
1348 } | 1355 } |
1349 | 1356 |
1350 // Restore styles. Make sure style ranges don't break new text graphemes. | 1357 // Restore styles. Make sure style ranges don't break new text graphemes. |
1351 render_text->styles_ = styles_; | 1358 render_text->styles_ = styles_; |
1352 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) { | 1359 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) { |
1353 BreakList<bool>& break_list = render_text->styles_[style]; | 1360 BreakList<bool>& break_list = render_text->styles_[style]; |
1354 break_list.SetMax(render_text->text_.length()); | 1361 break_list.SetMax(render_text->text_.length()); |
1355 Range range; | 1362 Range range; |
1356 while (range.end() < break_list.max()) { | 1363 while (range.end() < break_list.max()) { |
1357 BreakList<bool>::const_iterator current_break = | 1364 BreakList<bool>::const_iterator current_break = |
(...skipping 16 matching lines...) Expand all Loading... |
1374 if (guess_width > available_width) { | 1381 if (guess_width > available_width) { |
1375 hi = guess - 1; | 1382 hi = guess - 1; |
1376 // Move back on the loop terminating condition when the guess is too wide. | 1383 // Move back on the loop terminating condition when the guess is too wide. |
1377 if (hi < lo) | 1384 if (hi < lo) |
1378 lo = hi; | 1385 lo = hi; |
1379 } else { | 1386 } else { |
1380 lo = guess + 1; | 1387 lo = guess + 1; |
1381 } | 1388 } |
1382 } | 1389 } |
1383 | 1390 |
| 1391 DLOG(INFO) << "returning " << render_text->text(); |
| 1392 |
1384 return render_text->text(); | 1393 return render_text->text(); |
1385 } | 1394 } |
1386 | 1395 |
1387 base::string16 RenderText::ElideEmail(const base::string16& email, | 1396 base::string16 RenderText::ElideEmail(const base::string16& email, |
1388 float available_width) { | 1397 float available_width) { |
1389 // The returned string will have at least one character besides the ellipsis | 1398 // The returned string will have at least one character besides the ellipsis |
1390 // on either side of '@'; if that's impossible, a single ellipsis is returned. | 1399 // on either side of '@'; if that's impossible, a single ellipsis is returned. |
1391 // If possible, only the username is elided. Otherwise, the domain is elided | 1400 // If possible, only the username is elided. Otherwise, the domain is elided |
1392 // in the middle, splitting available width equally with the elided username. | 1401 // in the middle, splitting available width equally with the elided username. |
1393 // If the username is short enough that it doesn't need half the available | 1402 // If the username is short enough that it doesn't need half the available |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 | 1473 |
1465 SetDisplayOffset(display_offset_.x() + delta_x); | 1474 SetDisplayOffset(display_offset_.x() + delta_x); |
1466 } | 1475 } |
1467 | 1476 |
1468 void RenderText::DrawSelection(Canvas* canvas) { | 1477 void RenderText::DrawSelection(Canvas* canvas) { |
1469 for (const Rect& s : GetSubstringBounds(selection())) | 1478 for (const Rect& s : GetSubstringBounds(selection())) |
1470 canvas->FillRect(s, selection_background_focused_color_); | 1479 canvas->FillRect(s, selection_background_focused_color_); |
1471 } | 1480 } |
1472 | 1481 |
1473 } // namespace gfx | 1482 } // namespace gfx |
OLD | NEW |