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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 canvas_->DrawLine(start_, end, paint_); | 342 canvas_->DrawLine(start_, end, paint_); |
343 | 343 |
344 if (clipped) | 344 if (clipped) |
345 canvas_->Restore(); | 345 canvas_->Restore(); |
346 | 346 |
347 x += pieces_[i].first; | 347 x += pieces_[i].first; |
348 } | 348 } |
349 } | 349 } |
350 | 350 |
351 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, | 351 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, |
352 const BreakList<BaselineStyle>& baselines, | |
352 const std::vector<BreakList<bool> >& styles) | 353 const std::vector<BreakList<bool> >& styles) |
353 : colors_(colors), | 354 : colors_(colors), |
355 baselines_(baselines), | |
354 styles_(styles) { | 356 styles_(styles) { |
355 color_ = colors_.breaks().begin(); | 357 color_ = colors_.breaks().begin(); |
358 baseline_ = baselines_.breaks().begin(); | |
356 for (size_t i = 0; i < styles_.size(); ++i) | 359 for (size_t i = 0; i < styles_.size(); ++i) |
357 style_.push_back(styles_[i].breaks().begin()); | 360 style_.push_back(styles_[i].breaks().begin()); |
358 } | 361 } |
359 | 362 |
360 StyleIterator::~StyleIterator() {} | 363 StyleIterator::~StyleIterator() {} |
361 | 364 |
362 Range StyleIterator::GetRange() const { | 365 Range StyleIterator::GetRange() const { |
363 Range range(colors_.GetRange(color_)); | 366 Range range(colors_.GetRange(color_)); |
367 range = range.Intersect(baselines_.GetRange(baseline_)); | |
364 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 368 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
365 range = range.Intersect(styles_[i].GetRange(style_[i])); | 369 range = range.Intersect(styles_[i].GetRange(style_[i])); |
366 return range; | 370 return range; |
367 } | 371 } |
368 | 372 |
369 void StyleIterator::UpdatePosition(size_t position) { | 373 void StyleIterator::UpdatePosition(size_t position) { |
370 color_ = colors_.GetBreak(position); | 374 color_ = colors_.GetBreak(position); |
375 baseline_ = baselines_.GetBreak(position); | |
371 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 376 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
372 style_[i] = styles_[i].GetBreak(position); | 377 style_[i] = styles_[i].GetBreak(position); |
373 } | 378 } |
374 | 379 |
375 LineSegment::LineSegment() : width(0), run(0) {} | 380 LineSegment::LineSegment() : width(0), run(0) {} |
376 | 381 |
377 LineSegment::~LineSegment() {} | 382 LineSegment::~LineSegment() {} |
378 | 383 |
379 Line::Line() : preceding_heights(0), baseline(0) {} | 384 Line::Line() : preceding_heights(0), baseline(0) {} |
380 | 385 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 RenderText* RenderText::CreateInstanceForEditing() { | 421 RenderText* RenderText::CreateInstanceForEditing() { |
417 return new RenderTextHarfBuzz; | 422 return new RenderTextHarfBuzz; |
418 } | 423 } |
419 | 424 |
420 void RenderText::SetText(const base::string16& text) { | 425 void RenderText::SetText(const base::string16& text) { |
421 DCHECK(!composition_range_.IsValid()); | 426 DCHECK(!composition_range_.IsValid()); |
422 if (text_ == text) | 427 if (text_ == text) |
423 return; | 428 return; |
424 text_ = text; | 429 text_ = text; |
425 | 430 |
426 // Adjust ranged styles and colors to accommodate a new text length. | 431 // Adjust ranged styles and colors to accommodate a new text length. |
msw
2015/02/18 17:07:23
nit: Adjust ranged styles, baselines, and colors..
dschuyler
2015/02/18 22:36:02
Done.
| |
427 // Clear style ranges as they might break new text graphemes and apply | 432 // Clear style ranges as they might break new text graphemes and apply |
428 // the first style to the whole text instead. | 433 // the first style to the whole text instead. |
429 const size_t text_length = text_.length(); | 434 const size_t text_length = text_.length(); |
430 colors_.SetMax(text_length); | 435 colors_.SetMax(text_length); |
436 baselines_.SetMax(text_length); | |
msw
2015/02/18 17:07:23
You'll need to clear the baseline values here, lik
dschuyler
2015/02/18 22:36:02
Done.
| |
431 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) { | 437 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) { |
432 BreakList<bool>& break_list = styles_[style]; | 438 BreakList<bool>& break_list = styles_[style]; |
433 break_list.SetValue(break_list.breaks().begin()->second); | 439 break_list.SetValue(break_list.breaks().begin()->second); |
434 break_list.SetMax(text_length); | 440 break_list.SetMax(text_length); |
435 } | 441 } |
436 cached_bounds_and_offset_valid_ = false; | 442 cached_bounds_and_offset_valid_ = false; |
437 | 443 |
438 // Reset selection model. SetText should always followed by SetSelectionModel | 444 // Reset selection model. SetText should always followed by SetSelectionModel |
439 // or SetCursorPosition in upper layer. | 445 // or SetCursorPosition in upper layer. |
440 SetSelectionModel(SelectionModel()); | 446 SetSelectionModel(SelectionModel()); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
661 } | 667 } |
662 | 668 |
663 void RenderText::SetColor(SkColor value) { | 669 void RenderText::SetColor(SkColor value) { |
664 colors_.SetValue(value); | 670 colors_.SetValue(value); |
665 } | 671 } |
666 | 672 |
667 void RenderText::ApplyColor(SkColor value, const Range& range) { | 673 void RenderText::ApplyColor(SkColor value, const Range& range) { |
668 colors_.ApplyValue(value, range); | 674 colors_.ApplyValue(value, range); |
669 } | 675 } |
670 | 676 |
677 void RenderText::SetBaselineStyle(BaselineStyle value) { | |
678 baselines_.SetValue(value); | |
679 } | |
680 | |
681 void RenderText::ApplyBaselineStyle(BaselineStyle value, const Range& range) { | |
682 baselines_.ApplyValue(value, range); | |
683 } | |
684 | |
671 void RenderText::SetStyle(TextStyle style, bool value) { | 685 void RenderText::SetStyle(TextStyle style, bool value) { |
672 styles_[style].SetValue(value); | 686 styles_[style].SetValue(value); |
673 | 687 |
674 cached_bounds_and_offset_valid_ = false; | 688 cached_bounds_and_offset_valid_ = false; |
675 ResetLayout(); | 689 ResetLayout(); |
676 } | 690 } |
677 | 691 |
678 void RenderText::ApplyStyle(TextStyle style, bool value, const Range& range) { | 692 void RenderText::ApplyStyle(TextStyle style, bool value, const Range& range) { |
679 // Do not change styles mid-grapheme to avoid breaking ligatures. | 693 // Do not change styles mid-grapheme to avoid breaking ligatures. |
680 const size_t start = IsValidCursorIndex(range.start()) ? range.start() : | 694 const size_t start = IsValidCursorIndex(range.start()) ? range.start() : |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 text_direction_(base::i18n::UNKNOWN_DIRECTION), | 932 text_direction_(base::i18n::UNKNOWN_DIRECTION), |
919 cursor_enabled_(true), | 933 cursor_enabled_(true), |
920 cursor_visible_(false), | 934 cursor_visible_(false), |
921 insert_mode_(true), | 935 insert_mode_(true), |
922 cursor_color_(kDefaultColor), | 936 cursor_color_(kDefaultColor), |
923 selection_color_(kDefaultColor), | 937 selection_color_(kDefaultColor), |
924 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 938 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
925 focused_(false), | 939 focused_(false), |
926 composition_range_(Range::InvalidRange()), | 940 composition_range_(Range::InvalidRange()), |
927 colors_(kDefaultColor), | 941 colors_(kDefaultColor), |
942 baselines_(NORMAL_BASELINE), | |
928 styles_(NUM_TEXT_STYLES), | 943 styles_(NUM_TEXT_STYLES), |
929 composition_and_selection_styles_applied_(false), | 944 composition_and_selection_styles_applied_(false), |
930 obscured_(false), | 945 obscured_(false), |
931 obscured_reveal_index_(-1), | 946 obscured_reveal_index_(-1), |
932 truncate_length_(0), | 947 truncate_length_(0), |
933 elide_behavior_(NO_ELIDE), | 948 elide_behavior_(NO_ELIDE), |
934 replace_newline_chars_with_symbols_(true), | 949 replace_newline_chars_with_symbols_(true), |
935 min_line_height_(0), | 950 min_line_height_(0), |
936 multiline_(false), | 951 multiline_(false), |
937 background_is_transparent_(false), | 952 background_is_transparent_(false), |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1252 if (behavior == ELIDE_EMAIL) | 1267 if (behavior == ELIDE_EMAIL) |
1253 return ElideEmail(text, available_width); | 1268 return ElideEmail(text, available_width); |
1254 | 1269 |
1255 // Create a RenderText copy with attributes that affect the rendering width. | 1270 // Create a RenderText copy with attributes that affect the rendering width. |
1256 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); | 1271 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); |
1257 render_text->SetFontList(font_list_); | 1272 render_text->SetFontList(font_list_); |
1258 render_text->SetDirectionalityMode(directionality_mode_); | 1273 render_text->SetDirectionalityMode(directionality_mode_); |
1259 render_text->SetCursorEnabled(cursor_enabled_); | 1274 render_text->SetCursorEnabled(cursor_enabled_); |
1260 render_text->set_truncate_length(truncate_length_); | 1275 render_text->set_truncate_length(truncate_length_); |
1261 render_text->styles_ = styles_; | 1276 render_text->styles_ = styles_; |
1277 render_text->baselines_ = baselines_; | |
1262 render_text->colors_ = colors_; | 1278 render_text->colors_ = colors_; |
1263 render_text->SetText(text); | 1279 render_text->SetText(text); |
1264 if (render_text->GetContentWidthF() <= available_width) | 1280 if (render_text->GetContentWidthF() <= available_width) |
1265 return text; | 1281 return text; |
1266 | 1282 |
1267 const base::string16 ellipsis = base::string16(kEllipsisUTF16); | 1283 const base::string16 ellipsis = base::string16(kEllipsisUTF16); |
1268 const bool insert_ellipsis = (behavior != TRUNCATE); | 1284 const bool insert_ellipsis = (behavior != TRUNCATE); |
1269 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); | 1285 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); |
1270 const bool elide_at_beginning = (behavior == ELIDE_HEAD); | 1286 const bool elide_at_beginning = (behavior == ELIDE_HEAD); |
1271 StringSlicer slicer(text, ellipsis, elide_in_middle, elide_at_beginning); | 1287 StringSlicer slicer(text, ellipsis, elide_in_middle, elide_at_beginning); |
1272 | 1288 |
1273 render_text->SetText(ellipsis); | 1289 render_text->SetText(ellipsis); |
1274 const float ellipsis_width = render_text->GetContentWidthF(); | 1290 const float ellipsis_width = render_text->GetContentWidthF(); |
1275 | 1291 |
1276 if (insert_ellipsis && (ellipsis_width > available_width)) | 1292 if (insert_ellipsis && (ellipsis_width > available_width)) |
1277 return base::string16(); | 1293 return base::string16(); |
1278 | 1294 |
1279 // Use binary search to compute the elided text. | 1295 // Use binary search to compute the elided text. |
1280 size_t lo = 0; | 1296 size_t lo = 0; |
1281 size_t hi = text.length() - 1; | 1297 size_t hi = text.length() - 1; |
1282 const base::i18n::TextDirection text_direction = GetTextDirection(); | 1298 const base::i18n::TextDirection text_direction = GetTextDirection(); |
1283 for (size_t guess = (lo + hi) / 2; lo <= hi; guess = (lo + hi) / 2) { | 1299 for (size_t guess = (lo + hi) / 2; lo <= hi; guess = (lo + hi) / 2) { |
1284 // Restore colors. They will be truncated to size by SetText. | 1300 // Restore colors. They will be truncated to size by SetText. |
1285 render_text->colors_ = colors_; | 1301 render_text->colors_ = colors_; |
1302 render_text->baselines_ = baselines_; | |
msw
2015/02/18 17:07:23
With the change to clear the baseline values on Se
dschuyler
2015/02/18 22:36:02
I moved the restore break list code out to a separ
| |
1286 base::string16 new_text = | 1303 base::string16 new_text = |
1287 slicer.CutString(guess, insert_ellipsis && behavior != ELIDE_TAIL); | 1304 slicer.CutString(guess, insert_ellipsis && behavior != ELIDE_TAIL); |
1288 render_text->SetText(new_text); | 1305 render_text->SetText(new_text); |
1289 | 1306 |
1290 // This has to be an additional step so that the ellipsis is rendered with | 1307 // This has to be an additional step so that the ellipsis is rendered with |
1291 // same style as trailing part of the text. | 1308 // same style as trailing part of the text. |
1292 if (insert_ellipsis && behavior == ELIDE_TAIL) { | 1309 if (insert_ellipsis && behavior == ELIDE_TAIL) { |
1293 // When ellipsis follows text whose directionality is not the same as that | 1310 // When ellipsis follows text whose directionality is not the same as that |
1294 // of the whole text, it will be rendered with the directionality of the | 1311 // of the whole text, it will be rendered with the directionality of the |
1295 // whole text. Since we want ellipsis to indicate continuation of the | 1312 // whole text. Since we want ellipsis to indicate continuation of the |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1425 SetDisplayOffset(display_offset_.x() + delta_x); | 1442 SetDisplayOffset(display_offset_.x() + delta_x); |
1426 } | 1443 } |
1427 | 1444 |
1428 void RenderText::DrawSelection(Canvas* canvas) { | 1445 void RenderText::DrawSelection(Canvas* canvas) { |
1429 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1446 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
1430 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1447 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
1431 canvas->FillRect(*i, selection_background_focused_color_); | 1448 canvas->FillRect(*i, selection_background_focused_color_); |
1432 } | 1449 } |
1433 | 1450 |
1434 } // namespace gfx | 1451 } // namespace gfx |
OLD | NEW |