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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { | 462 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { |
463 if (horizontal_alignment_ != alignment) { | 463 if (horizontal_alignment_ != alignment) { |
464 horizontal_alignment_ = alignment; | 464 horizontal_alignment_ = alignment; |
465 display_offset_ = Vector2d(); | 465 display_offset_ = Vector2d(); |
466 cached_bounds_and_offset_valid_ = false; | 466 cached_bounds_and_offset_valid_ = false; |
467 } | 467 } |
468 } | 468 } |
469 | 469 |
470 void RenderText::SetFontList(const FontList& font_list) { | 470 void RenderText::SetFontList(const FontList& font_list) { |
471 font_list_ = font_list; | 471 font_list_ = font_list; |
| 472 const int font_style = font_list.GetFontStyle(); |
| 473 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); |
| 474 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); |
| 475 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); |
472 baseline_ = kInvalidBaseline; | 476 baseline_ = kInvalidBaseline; |
473 cached_bounds_and_offset_valid_ = false; | 477 cached_bounds_and_offset_valid_ = false; |
474 ResetLayout(); | 478 ResetLayout(); |
475 } | 479 } |
476 | 480 |
477 void RenderText::SetCursorEnabled(bool cursor_enabled) { | 481 void RenderText::SetCursorEnabled(bool cursor_enabled) { |
478 cursor_enabled_ = cursor_enabled; | 482 cursor_enabled_ = cursor_enabled; |
479 cached_bounds_and_offset_valid_ = false; | 483 cached_bounds_and_offset_valid_ = false; |
480 } | 484 } |
481 | 485 |
(...skipping 13 matching lines...) Expand all Loading... |
495 | 499 |
496 void RenderText::SetObscuredRevealIndex(int index) { | 500 void RenderText::SetObscuredRevealIndex(int index) { |
497 if (obscured_reveal_index_ == index) | 501 if (obscured_reveal_index_ == index) |
498 return; | 502 return; |
499 | 503 |
500 obscured_reveal_index_ = index; | 504 obscured_reveal_index_ = index; |
501 cached_bounds_and_offset_valid_ = false; | 505 cached_bounds_and_offset_valid_ = false; |
502 UpdateLayoutText(); | 506 UpdateLayoutText(); |
503 } | 507 } |
504 | 508 |
| 509 void RenderText::SetReplaceNewlineCharsWithSymbols(bool replace) { |
| 510 replace_newline_chars_with_symbols_ = replace; |
| 511 cached_bounds_and_offset_valid_ = false; |
| 512 UpdateLayoutText(); |
| 513 } |
| 514 |
505 void RenderText::SetMultiline(bool multiline) { | 515 void RenderText::SetMultiline(bool multiline) { |
506 if (multiline != multiline_) { | 516 if (multiline != multiline_) { |
507 multiline_ = multiline; | 517 multiline_ = multiline; |
508 cached_bounds_and_offset_valid_ = false; | 518 cached_bounds_and_offset_valid_ = false; |
509 lines_.clear(); | 519 lines_.clear(); |
510 } | 520 } |
511 } | 521 } |
512 | 522 |
513 void RenderText::SetElideBehavior(ElideBehavior elide_behavior) { | 523 void RenderText::SetElideBehavior(ElideBehavior elide_behavior) { |
514 // TODO(skanuj) : Add a test for triggering layout change. | 524 // TODO(skanuj) : Add a test for triggering layout change. |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 941 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
932 focused_(false), | 942 focused_(false), |
933 composition_range_(Range::InvalidRange()), | 943 composition_range_(Range::InvalidRange()), |
934 colors_(kDefaultColor), | 944 colors_(kDefaultColor), |
935 styles_(NUM_TEXT_STYLES), | 945 styles_(NUM_TEXT_STYLES), |
936 composition_and_selection_styles_applied_(false), | 946 composition_and_selection_styles_applied_(false), |
937 obscured_(false), | 947 obscured_(false), |
938 obscured_reveal_index_(-1), | 948 obscured_reveal_index_(-1), |
939 truncate_length_(0), | 949 truncate_length_(0), |
940 elide_behavior_(NO_ELIDE), | 950 elide_behavior_(NO_ELIDE), |
| 951 replace_newline_chars_with_symbols_(true), |
941 multiline_(false), | 952 multiline_(false), |
942 background_is_transparent_(false), | 953 background_is_transparent_(false), |
943 clip_to_display_rect_(true), | 954 clip_to_display_rect_(true), |
944 baseline_(kInvalidBaseline), | 955 baseline_(kInvalidBaseline), |
945 cached_bounds_and_offset_valid_(false) { | 956 cached_bounds_and_offset_valid_(false) { |
946 } | 957 } |
947 | 958 |
948 SelectionModel RenderText::GetAdjacentSelectionModel( | 959 SelectionModel RenderText::GetAdjacentSelectionModel( |
949 const SelectionModel& current, | 960 const SelectionModel& current, |
950 BreakType break_type, | 961 BreakType break_type, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 0, intersection.length(), lines_[line].size.height()); | 1087 0, intersection.length(), lines_[line].size.height()); |
1077 rects.push_back(rect + offset); | 1088 rects.push_back(rect + offset); |
1078 } | 1089 } |
1079 line_x += segment->x_range.length(); | 1090 line_x += segment->x_range.length(); |
1080 } | 1091 } |
1081 } | 1092 } |
1082 | 1093 |
1083 return rects; | 1094 return rects; |
1084 } | 1095 } |
1085 | 1096 |
| 1097 HorizontalAlignment RenderText::GetCurrentHorizontalAlignment() { |
| 1098 if (horizontal_alignment_ != ALIGN_TO_HEAD) |
| 1099 return horizontal_alignment_; |
| 1100 return GetTextDirection() == base::i18n::RIGHT_TO_LEFT ? ALIGN_RIGHT |
| 1101 : ALIGN_LEFT; |
| 1102 } |
| 1103 |
1086 Vector2d RenderText::GetAlignmentOffset(size_t line_number) { | 1104 Vector2d RenderText::GetAlignmentOffset(size_t line_number) { |
1087 // TODO(ckocagil): Enable |lines_| usage in other platforms. | 1105 // TODO(ckocagil): Enable |lines_| usage in other platforms. |
1088 #if defined(OS_WIN) | 1106 #if defined(OS_WIN) |
1089 DCHECK_LT(line_number, lines_.size()); | 1107 DCHECK_LT(line_number, lines_.size()); |
1090 #endif | 1108 #endif |
1091 Vector2d offset; | 1109 Vector2d offset; |
1092 if (horizontal_alignment_ != ALIGN_LEFT) { | 1110 HorizontalAlignment horizontal_alignment = GetCurrentHorizontalAlignment(); |
| 1111 if (horizontal_alignment != ALIGN_LEFT) { |
1093 #if defined(OS_WIN) | 1112 #if defined(OS_WIN) |
1094 const int width = lines_[line_number].size.width() + | 1113 const int width = lines_[line_number].size.width() + |
1095 (cursor_enabled_ ? 1 : 0); | 1114 (cursor_enabled_ ? 1 : 0); |
1096 #else | 1115 #else |
1097 const int width = GetContentWidth(); | 1116 const int width = GetContentWidth(); |
1098 #endif | 1117 #endif |
1099 offset.set_x(display_rect().width() - width); | 1118 offset.set_x(display_rect().width() - width); |
1100 if (horizontal_alignment_ == ALIGN_CENTER) | 1119 // Put any extra margin pixel on the left to match legacy behavior. |
1101 offset.set_x(offset.x() / 2); | 1120 if (horizontal_alignment == ALIGN_CENTER) |
| 1121 offset.set_x((offset.x() + 1) / 2); |
1102 } | 1122 } |
1103 | 1123 |
1104 // Vertically center the text. | 1124 // Vertically center the text. |
1105 if (multiline_) { | 1125 if (multiline_) { |
1106 const int text_height = lines_.back().preceding_heights + | 1126 const int text_height = lines_.back().preceding_heights + |
1107 lines_.back().size.height(); | 1127 lines_.back().size.height(); |
1108 offset.set_y((display_rect_.height() - text_height) / 2); | 1128 offset.set_y((display_rect_.height() - text_height) / 2); |
1109 } else { | 1129 } else { |
1110 offset.set_y(GetBaseline() - GetLayoutTextBaseline()); | 1130 offset.set_y(GetBaseline() - GetLayoutTextBaseline()); |
1111 } | 1131 } |
1112 | 1132 |
1113 return offset; | 1133 return offset; |
1114 } | 1134 } |
1115 | 1135 |
1116 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { | 1136 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { |
1117 const int width = display_rect().width(); | 1137 const int width = display_rect().width(); |
1118 if (multiline() || elide_behavior_ != FADE_TAIL || GetContentWidth() <= width) | 1138 if (multiline() || elide_behavior_ != FADE_TAIL || GetContentWidth() <= width) |
1119 return; | 1139 return; |
1120 | 1140 |
1121 const int gradient_width = CalculateFadeGradientWidth(font_list(), width); | 1141 const int gradient_width = CalculateFadeGradientWidth(font_list(), width); |
1122 if (gradient_width == 0) | 1142 if (gradient_width == 0) |
1123 return; | 1143 return; |
1124 | 1144 |
| 1145 HorizontalAlignment horizontal_alignment = GetCurrentHorizontalAlignment(); |
1125 Rect solid_part = display_rect(); | 1146 Rect solid_part = display_rect(); |
1126 Rect left_part; | 1147 Rect left_part; |
1127 Rect right_part; | 1148 Rect right_part; |
1128 if (horizontal_alignment_ != ALIGN_LEFT) { | 1149 if (horizontal_alignment != ALIGN_LEFT) { |
1129 left_part = solid_part; | 1150 left_part = solid_part; |
1130 left_part.Inset(0, 0, solid_part.width() - gradient_width, 0); | 1151 left_part.Inset(0, 0, solid_part.width() - gradient_width, 0); |
1131 solid_part.Inset(gradient_width, 0, 0, 0); | 1152 solid_part.Inset(gradient_width, 0, 0, 0); |
1132 } | 1153 } |
1133 if (horizontal_alignment_ != ALIGN_RIGHT) { | 1154 if (horizontal_alignment != ALIGN_RIGHT) { |
1134 right_part = solid_part; | 1155 right_part = solid_part; |
1135 right_part.Inset(solid_part.width() - gradient_width, 0, 0, 0); | 1156 right_part.Inset(solid_part.width() - gradient_width, 0, 0, 0); |
1136 solid_part.Inset(0, 0, gradient_width, 0); | 1157 solid_part.Inset(0, 0, gradient_width, 0); |
1137 } | 1158 } |
1138 | 1159 |
1139 Rect text_rect = display_rect(); | 1160 Rect text_rect = display_rect(); |
1140 text_rect.Inset(GetAlignmentOffset(0).x(), 0, 0, 0); | 1161 text_rect.Inset(GetAlignmentOffset(0).x(), 0, 0, 0); |
1141 | 1162 |
1142 // TODO(msw): Use the actual text colors corresponding to each faded part. | 1163 // TODO(msw): Use the actual text colors corresponding to each faded part. |
1143 skia::RefPtr<SkShader> shader = CreateFadeShader( | 1164 skia::RefPtr<SkShader> shader = CreateFadeShader( |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 !layout_text_.empty() && GetContentWidth() > display_rect_.width()) { | 1244 !layout_text_.empty() && GetContentWidth() > display_rect_.width()) { |
1224 // This doesn't trim styles so ellipsis may get rendered as a different | 1245 // This doesn't trim styles so ellipsis may get rendered as a different |
1225 // style than the preceding text. See crbug.com/327850. | 1246 // style than the preceding text. See crbug.com/327850. |
1226 layout_text_.assign( | 1247 layout_text_.assign( |
1227 Elide(layout_text_, display_rect_.width(), elide_behavior_)); | 1248 Elide(layout_text_, display_rect_.width(), elide_behavior_)); |
1228 } | 1249 } |
1229 | 1250 |
1230 // Replace the newline character with a newline symbol in single line mode. | 1251 // Replace the newline character with a newline symbol in single line mode. |
1231 static const base::char16 kNewline[] = { '\n', 0 }; | 1252 static const base::char16 kNewline[] = { '\n', 0 }; |
1232 static const base::char16 kNewlineSymbol[] = { 0x2424, 0 }; | 1253 static const base::char16 kNewlineSymbol[] = { 0x2424, 0 }; |
1233 if (!multiline_) | 1254 if (!multiline_ && replace_newline_chars_with_symbols_) |
1234 base::ReplaceChars(layout_text_, kNewline, kNewlineSymbol, &layout_text_); | 1255 base::ReplaceChars(layout_text_, kNewline, kNewlineSymbol, &layout_text_); |
1235 | 1256 |
1236 ResetLayout(); | 1257 ResetLayout(); |
1237 } | 1258 } |
1238 | 1259 |
1239 base::string16 RenderText::Elide(const base::string16& text, | 1260 base::string16 RenderText::Elide(const base::string16& text, |
1240 float available_width, | 1261 float available_width, |
1241 ElideBehavior behavior) { | 1262 ElideBehavior behavior) { |
1242 if (available_width <= 0 || text.empty()) | 1263 if (available_width <= 0 || text.empty()) |
1243 return base::string16(); | 1264 return base::string16(); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 delta_x = display_rect_.right() - cursor_bounds_.right(); | 1425 delta_x = display_rect_.right() - cursor_bounds_.right(); |
1405 } else if (cursor_bounds_.x() < display_rect_.x()) { | 1426 } else if (cursor_bounds_.x() < display_rect_.x()) { |
1406 // TODO(xji): have similar problem as above when overflow character is a | 1427 // TODO(xji): have similar problem as above when overflow character is a |
1407 // LTR character. | 1428 // LTR character. |
1408 // | 1429 // |
1409 // Pan to show the cursor when it overflows to the left. | 1430 // Pan to show the cursor when it overflows to the left. |
1410 delta_x = display_rect_.x() - cursor_bounds_.x(); | 1431 delta_x = display_rect_.x() - cursor_bounds_.x(); |
1411 } else if (display_offset_.x() != 0) { | 1432 } else if (display_offset_.x() != 0) { |
1412 // Reduce the pan offset to show additional overflow text when the display | 1433 // Reduce the pan offset to show additional overflow text when the display |
1413 // width increases. | 1434 // width increases. |
1414 const int negate_rtl = horizontal_alignment_ == ALIGN_RIGHT ? -1 : 1; | 1435 HorizontalAlignment horizontal_alignment = GetCurrentHorizontalAlignment(); |
| 1436 const int negate_rtl = horizontal_alignment == ALIGN_RIGHT ? -1 : 1; |
1415 const int offset = negate_rtl * display_offset_.x(); | 1437 const int offset = negate_rtl * display_offset_.x(); |
1416 if (display_width > (content_width + offset)) { | 1438 if (display_width > (content_width + offset)) { |
1417 delta_x = negate_rtl * (display_width - (content_width + offset)); | 1439 delta_x = negate_rtl * (display_width - (content_width + offset)); |
1418 } | 1440 } |
1419 } | 1441 } |
1420 | 1442 |
1421 Vector2d delta_offset(delta_x, 0); | 1443 Vector2d delta_offset(delta_x, 0); |
1422 display_offset_ += delta_offset; | 1444 display_offset_ += delta_offset; |
1423 cursor_bounds_ += delta_offset; | 1445 cursor_bounds_ += delta_offset; |
1424 } | 1446 } |
1425 | 1447 |
1426 void RenderText::DrawSelection(Canvas* canvas) { | 1448 void RenderText::DrawSelection(Canvas* canvas) { |
1427 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1449 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
1428 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1450 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
1429 canvas->FillRect(*i, selection_background_focused_color_); | 1451 canvas->FillRect(*i, selection_background_focused_color_); |
1430 } | 1452 } |
1431 | 1453 |
1432 } // namespace gfx | 1454 } // namespace gfx |
OLD | NEW |