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

Side by Side Diff: ui/gfx/render_text.cc

Issue 24012002: Move Range code to gfx. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: d Created 7 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/render_text_linux.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 8
9 #include "base/i18n/break_iterator.h" 9 #include "base/i18n/break_iterator.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 const std::vector<BreakList<bool> >& styles) 281 const std::vector<BreakList<bool> >& styles)
282 : colors_(colors), 282 : colors_(colors),
283 styles_(styles) { 283 styles_(styles) {
284 color_ = colors_.breaks().begin(); 284 color_ = colors_.breaks().begin();
285 for (size_t i = 0; i < styles_.size(); ++i) 285 for (size_t i = 0; i < styles_.size(); ++i)
286 style_.push_back(styles_[i].breaks().begin()); 286 style_.push_back(styles_[i].breaks().begin());
287 } 287 }
288 288
289 StyleIterator::~StyleIterator() {} 289 StyleIterator::~StyleIterator() {}
290 290
291 ui::Range StyleIterator::GetRange() const { 291 gfx::Range StyleIterator::GetRange() const {
292 ui::Range range(colors_.GetRange(color_)); 292 gfx::Range range(colors_.GetRange(color_));
293 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) 293 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
294 range = range.Intersect(styles_[i].GetRange(style_[i])); 294 range = range.Intersect(styles_[i].GetRange(style_[i]));
295 return range; 295 return range;
296 } 296 }
297 297
298 void StyleIterator::UpdatePosition(size_t position) { 298 void StyleIterator::UpdatePosition(size_t position) {
299 color_ = colors_.GetBreak(position); 299 color_ = colors_.GetBreak(position);
300 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) 300 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
301 style_[i] = styles_[i].GetBreak(position); 301 style_[i] = styles_[i].GetBreak(position);
302 } 302 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 position = GetAdjacentSelectionModel(position, break_type, direction); 424 position = GetAdjacentSelectionModel(position, break_type, direction);
425 } 425 }
426 if (select) 426 if (select)
427 position.set_selection_start(selection().start()); 427 position.set_selection_start(selection().start());
428 MoveCursorTo(position); 428 MoveCursorTo(position);
429 } 429 }
430 430
431 bool RenderText::MoveCursorTo(const SelectionModel& model) { 431 bool RenderText::MoveCursorTo(const SelectionModel& model) {
432 // Enforce valid selection model components. 432 // Enforce valid selection model components.
433 size_t text_length = text().length(); 433 size_t text_length = text().length();
434 ui::Range range(std::min(model.selection().start(), text_length), 434 gfx::Range range(std::min(model.selection().start(), text_length),
435 std::min(model.caret_pos(), text_length)); 435 std::min(model.caret_pos(), text_length));
436 // The current model only supports caret positions at valid character indices. 436 // The current model only supports caret positions at valid character indices.
437 if (!IsCursorablePosition(range.start()) || 437 if (!IsCursorablePosition(range.start()) ||
438 !IsCursorablePosition(range.end())) 438 !IsCursorablePosition(range.end()))
439 return false; 439 return false;
440 SelectionModel sel(range, model.caret_affinity()); 440 SelectionModel sel(range, model.caret_affinity());
441 bool changed = sel != selection_model_; 441 bool changed = sel != selection_model_;
442 SetSelectionModel(sel); 442 SetSelectionModel(sel);
443 return changed; 443 return changed;
444 } 444 }
445 445
446 bool RenderText::MoveCursorTo(const Point& point, bool select) { 446 bool RenderText::MoveCursorTo(const Point& point, bool select) {
447 SelectionModel position = FindCursorPosition(point); 447 SelectionModel position = FindCursorPosition(point);
448 if (select) 448 if (select)
449 position.set_selection_start(selection().start()); 449 position.set_selection_start(selection().start());
450 return MoveCursorTo(position); 450 return MoveCursorTo(position);
451 } 451 }
452 452
453 bool RenderText::SelectRange(const ui::Range& range) { 453 bool RenderText::SelectRange(const gfx::Range& range) {
454 ui::Range sel(std::min(range.start(), text().length()), 454 gfx::Range sel(std::min(range.start(), text().length()),
455 std::min(range.end(), text().length())); 455 std::min(range.end(), text().length()));
456 if (!IsCursorablePosition(sel.start()) || !IsCursorablePosition(sel.end())) 456 if (!IsCursorablePosition(sel.start()) || !IsCursorablePosition(sel.end()))
457 return false; 457 return false;
458 LogicalCursorDirection affinity = 458 LogicalCursorDirection affinity =
459 (sel.is_reversed() || sel.is_empty()) ? CURSOR_FORWARD : CURSOR_BACKWARD; 459 (sel.is_reversed() || sel.is_empty()) ? CURSOR_FORWARD : CURSOR_BACKWARD;
460 SetSelectionModel(SelectionModel(sel, affinity)); 460 SetSelectionModel(SelectionModel(sel, affinity));
461 return true; 461 return true;
462 } 462 }
463 463
464 bool RenderText::IsPointInSelection(const Point& point) { 464 bool RenderText::IsPointInSelection(const Point& point) {
465 if (selection().is_empty()) 465 if (selection().is_empty())
466 return false; 466 return false;
467 SelectionModel cursor = FindCursorPosition(point); 467 SelectionModel cursor = FindCursorPosition(point);
468 return RangeContainsCaret( 468 return RangeContainsCaret(
469 selection(), cursor.caret_pos(), cursor.caret_affinity()); 469 selection(), cursor.caret_pos(), cursor.caret_affinity());
470 } 470 }
471 471
472 void RenderText::ClearSelection() { 472 void RenderText::ClearSelection() {
473 SetSelectionModel(SelectionModel(cursor_position(), 473 SetSelectionModel(SelectionModel(cursor_position(),
474 selection_model_.caret_affinity())); 474 selection_model_.caret_affinity()));
475 } 475 }
476 476
477 void RenderText::SelectAll(bool reversed) { 477 void RenderText::SelectAll(bool reversed) {
478 const size_t length = text().length(); 478 const size_t length = text().length();
479 const ui::Range all = reversed ? ui::Range(length, 0) : ui::Range(0, length); 479 const gfx::Range all = reversed ? gfx::Range(length, 0) :
480 gfx::Range(0, length);
480 const bool success = SelectRange(all); 481 const bool success = SelectRange(all);
481 DCHECK(success); 482 DCHECK(success);
482 } 483 }
483 484
484 void RenderText::SelectWord() { 485 void RenderText::SelectWord() {
485 if (obscured_) { 486 if (obscured_) {
486 SelectAll(false); 487 SelectAll(false);
487 return; 488 return;
488 } 489 }
489 490
(...skipping 20 matching lines...) Expand all
510 511
511 for (; selection_max < text().length(); ++selection_max) 512 for (; selection_max < text().length(); ++selection_max)
512 if (iter.IsEndOfWord(selection_max) || iter.IsStartOfWord(selection_max)) 513 if (iter.IsEndOfWord(selection_max) || iter.IsStartOfWord(selection_max))
513 break; 514 break;
514 515
515 const bool reversed = selection().is_reversed(); 516 const bool reversed = selection().is_reversed();
516 MoveCursorTo(reversed ? selection_max : selection_min, false); 517 MoveCursorTo(reversed ? selection_max : selection_min, false);
517 MoveCursorTo(reversed ? selection_min : selection_max, true); 518 MoveCursorTo(reversed ? selection_min : selection_max, true);
518 } 519 }
519 520
520 const ui::Range& RenderText::GetCompositionRange() const { 521 const gfx::Range& RenderText::GetCompositionRange() const {
521 return composition_range_; 522 return composition_range_;
522 } 523 }
523 524
524 void RenderText::SetCompositionRange(const ui::Range& composition_range) { 525 void RenderText::SetCompositionRange(const gfx::Range& composition_range) {
525 CHECK(!composition_range.IsValid() || 526 CHECK(!composition_range.IsValid() ||
526 ui::Range(0, text_.length()).Contains(composition_range)); 527 gfx::Range(0, text_.length()).Contains(composition_range));
527 composition_range_.set_end(composition_range.end()); 528 composition_range_.set_end(composition_range.end());
528 composition_range_.set_start(composition_range.start()); 529 composition_range_.set_start(composition_range.start());
529 ResetLayout(); 530 ResetLayout();
530 } 531 }
531 532
532 void RenderText::SetColor(SkColor value) { 533 void RenderText::SetColor(SkColor value) {
533 colors_.SetValue(value); 534 colors_.SetValue(value);
534 535
535 #if defined(OS_WIN) 536 #if defined(OS_WIN)
536 // TODO(msw): Windows applies colors and decorations in the layout process. 537 // TODO(msw): Windows applies colors and decorations in the layout process.
537 cached_bounds_and_offset_valid_ = false; 538 cached_bounds_and_offset_valid_ = false;
538 ResetLayout(); 539 ResetLayout();
539 #endif 540 #endif
540 } 541 }
541 542
542 void RenderText::ApplyColor(SkColor value, const ui::Range& range) { 543 void RenderText::ApplyColor(SkColor value, const gfx::Range& range) {
543 colors_.ApplyValue(value, range); 544 colors_.ApplyValue(value, range);
544 545
545 #if defined(OS_WIN) 546 #if defined(OS_WIN)
546 // TODO(msw): Windows applies colors and decorations in the layout process. 547 // TODO(msw): Windows applies colors and decorations in the layout process.
547 cached_bounds_and_offset_valid_ = false; 548 cached_bounds_and_offset_valid_ = false;
548 ResetLayout(); 549 ResetLayout();
549 #endif 550 #endif
550 } 551 }
551 552
552 void RenderText::SetStyle(TextStyle style, bool value) { 553 void RenderText::SetStyle(TextStyle style, bool value) {
553 styles_[style].SetValue(value); 554 styles_[style].SetValue(value);
554 555
555 // Only invalidate the layout on font changes; not for colors or decorations. 556 // Only invalidate the layout on font changes; not for colors or decorations.
556 bool invalidate = (style == BOLD) || (style == ITALIC); 557 bool invalidate = (style == BOLD) || (style == ITALIC);
557 #if defined(OS_WIN) 558 #if defined(OS_WIN)
558 // TODO(msw): Windows applies colors and decorations in the layout process. 559 // TODO(msw): Windows applies colors and decorations in the layout process.
559 invalidate = true; 560 invalidate = true;
560 #endif 561 #endif
561 if (invalidate) { 562 if (invalidate) {
562 cached_bounds_and_offset_valid_ = false; 563 cached_bounds_and_offset_valid_ = false;
563 ResetLayout(); 564 ResetLayout();
564 } 565 }
565 } 566 }
566 567
567 void RenderText::ApplyStyle(TextStyle style, 568 void RenderText::ApplyStyle(TextStyle style,
568 bool value, 569 bool value,
569 const ui::Range& range) { 570 const gfx::Range& range) {
570 styles_[style].ApplyValue(value, range); 571 styles_[style].ApplyValue(value, range);
571 572
572 // Only invalidate the layout on font changes; not for colors or decorations. 573 // Only invalidate the layout on font changes; not for colors or decorations.
573 bool invalidate = (style == BOLD) || (style == ITALIC); 574 bool invalidate = (style == BOLD) || (style == ITALIC);
574 #if defined(OS_WIN) 575 #if defined(OS_WIN)
575 // TODO(msw): Windows applies colors and decorations in the layout process. 576 // TODO(msw): Windows applies colors and decorations in the layout process.
576 invalidate = true; 577 invalidate = true;
577 #endif 578 #endif
578 if (invalidate) { 579 if (invalidate) {
579 cached_bounds_and_offset_valid_ = false; 580 cached_bounds_and_offset_valid_ = false;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 int x = 0, width = 1; 698 int x = 0, width = 1;
698 Size size = GetStringSize(); 699 Size size = GetStringSize();
699 if (caret_pos == (caret_affinity == CURSOR_BACKWARD ? 0 : text().length())) { 700 if (caret_pos == (caret_affinity == CURSOR_BACKWARD ? 0 : text().length())) {
700 // The caret is attached to the boundary. Always return a 1-dip width caret, 701 // The caret is attached to the boundary. Always return a 1-dip width caret,
701 // since there is nothing to overtype. 702 // since there is nothing to overtype.
702 if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0)) 703 if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0))
703 x = size.width(); 704 x = size.width();
704 } else { 705 } else {
705 size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ? 706 size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ?
706 caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD); 707 caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD);
707 ui::Range xspan(GetGlyphBounds(grapheme_start)); 708 gfx::Range xspan(GetGlyphBounds(grapheme_start));
708 if (insert_mode) { 709 if (insert_mode) {
709 x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start(); 710 x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start();
710 } else { // overtype mode 711 } else { // overtype mode
711 x = xspan.GetMin(); 712 x = xspan.GetMin();
712 width = xspan.length(); 713 width = xspan.length();
713 } 714 }
714 } 715 }
715 return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height())); 716 return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height()));
716 } 717 }
717 718
(...skipping 20 matching lines...) Expand all
738 739
739 while (index > 0) { 740 while (index > 0) {
740 index--; 741 index--;
741 if (IsCursorablePosition(index)) 742 if (IsCursorablePosition(index))
742 return index; 743 return index;
743 } 744 }
744 return 0; 745 return 0;
745 } 746 }
746 747
747 SelectionModel RenderText::GetSelectionModelForSelectionStart() { 748 SelectionModel RenderText::GetSelectionModelForSelectionStart() {
748 const ui::Range& sel = selection(); 749 const gfx::Range& sel = selection();
749 if (sel.is_empty()) 750 if (sel.is_empty())
750 return selection_model_; 751 return selection_model_;
751 return SelectionModel(sel.start(), 752 return SelectionModel(sel.start(),
752 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); 753 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD);
753 } 754 }
754 755
755 void RenderText::SetTextShadows(const ShadowValues& shadows) { 756 void RenderText::SetTextShadows(const ShadowValues& shadows) {
756 text_shadows_ = shadows; 757 text_shadows_ = shadows;
757 } 758 }
758 759
759 RenderText::RenderText() 760 RenderText::RenderText()
760 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), 761 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT),
761 vertical_alignment_(ALIGN_VCENTER), 762 vertical_alignment_(ALIGN_VCENTER),
762 directionality_mode_(DIRECTIONALITY_FROM_TEXT), 763 directionality_mode_(DIRECTIONALITY_FROM_TEXT),
763 text_direction_(base::i18n::UNKNOWN_DIRECTION), 764 text_direction_(base::i18n::UNKNOWN_DIRECTION),
764 cursor_enabled_(true), 765 cursor_enabled_(true),
765 cursor_visible_(false), 766 cursor_visible_(false),
766 insert_mode_(true), 767 insert_mode_(true),
767 cursor_color_(kDefaultColor), 768 cursor_color_(kDefaultColor),
768 selection_color_(kDefaultColor), 769 selection_color_(kDefaultColor),
769 selection_background_focused_color_(kDefaultSelectionBackgroundColor), 770 selection_background_focused_color_(kDefaultSelectionBackgroundColor),
770 focused_(false), 771 focused_(false),
771 composition_range_(ui::Range::InvalidRange()), 772 composition_range_(gfx::Range::InvalidRange()),
772 colors_(kDefaultColor), 773 colors_(kDefaultColor),
773 styles_(NUM_TEXT_STYLES), 774 styles_(NUM_TEXT_STYLES),
774 composition_and_selection_styles_applied_(false), 775 composition_and_selection_styles_applied_(false),
775 obscured_(false), 776 obscured_(false),
776 obscured_reveal_index_(-1), 777 obscured_reveal_index_(-1),
777 truncate_length_(0), 778 truncate_length_(0),
778 fade_head_(false), 779 fade_head_(false),
779 fade_tail_(false), 780 fade_tail_(false),
780 background_is_transparent_(false), 781 background_is_transparent_(false),
781 clip_to_display_rect_(true), 782 clip_to_display_rect_(true),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 DCHECK(!composition_and_selection_styles_applied_); 824 DCHECK(!composition_and_selection_styles_applied_);
824 saved_colors_ = colors_; 825 saved_colors_ = colors_;
825 saved_underlines_ = styles_[UNDERLINE]; 826 saved_underlines_ = styles_[UNDERLINE];
826 827
827 // Apply an underline to the composition range in |underlines|. 828 // Apply an underline to the composition range in |underlines|.
828 if (composition_range_.IsValid() && !composition_range_.is_empty()) 829 if (composition_range_.IsValid() && !composition_range_.is_empty())
829 styles_[UNDERLINE].ApplyValue(true, composition_range_); 830 styles_[UNDERLINE].ApplyValue(true, composition_range_);
830 831
831 // Apply the selected text color to the [un-reversed] selection range. 832 // Apply the selected text color to the [un-reversed] selection range.
832 if (!selection().is_empty()) { 833 if (!selection().is_empty()) {
833 const ui::Range range(selection().GetMin(), selection().GetMax()); 834 const gfx::Range range(selection().GetMin(), selection().GetMax());
834 colors_.ApplyValue(selection_color_, range); 835 colors_.ApplyValue(selection_color_, range);
835 } 836 }
836 composition_and_selection_styles_applied_ = true; 837 composition_and_selection_styles_applied_ = true;
837 } 838 }
838 839
839 void RenderText::UndoCompositionAndSelectionStyles() { 840 void RenderText::UndoCompositionAndSelectionStyles() {
840 // Restore the underline and color breaks to undo the temporary styles. 841 // Restore the underline and color breaks to undo the temporary styles.
841 DCHECK(composition_and_selection_styles_applied_); 842 DCHECK(composition_and_selection_styles_applied_);
842 colors_ = saved_colors_; 843 colors_ = saved_colors_;
843 styles_[UNDERLINE] = saved_underlines_; 844 styles_[UNDERLINE] = saved_underlines_;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 if (shader) 923 if (shader)
923 renderer->SetShader(shader.get(), display_rect()); 924 renderer->SetShader(shader.get(), display_rect());
924 } 925 }
925 926
926 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { 927 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) {
927 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_); 928 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_);
928 renderer->SetDrawLooper(looper.get()); 929 renderer->SetDrawLooper(looper.get());
929 } 930 }
930 931
931 // static 932 // static
932 bool RenderText::RangeContainsCaret(const ui::Range& range, 933 bool RenderText::RangeContainsCaret(const gfx::Range& range,
933 size_t caret_pos, 934 size_t caret_pos,
934 LogicalCursorDirection caret_affinity) { 935 LogicalCursorDirection caret_affinity) {
935 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). 936 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9).
936 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? 937 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ?
937 caret_pos - 1 : caret_pos + 1; 938 caret_pos - 1 : caret_pos + 1;
938 return range.Contains(ui::Range(caret_pos, adjacent)); 939 return range.Contains(gfx::Range(caret_pos, adjacent));
939 } 940 }
940 941
941 void RenderText::MoveCursorTo(size_t position, bool select) { 942 void RenderText::MoveCursorTo(size_t position, bool select) {
942 size_t cursor = std::min(position, text().length()); 943 size_t cursor = std::min(position, text().length());
943 if (IsCursorablePosition(cursor)) 944 if (IsCursorablePosition(cursor))
944 SetSelectionModel(SelectionModel( 945 SetSelectionModel(SelectionModel(
945 ui::Range(select ? selection().start() : cursor, cursor), 946 gfx::Range(select ? selection().start() : cursor, cursor),
946 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); 947 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD));
947 } 948 }
948 949
949 void RenderText::UpdateLayoutText() { 950 void RenderText::UpdateLayoutText() {
950 layout_text_.clear(); 951 layout_text_.clear();
951 952
952 if (obscured_) { 953 if (obscured_) {
953 size_t obscured_text_length = 954 size_t obscured_text_length =
954 static_cast<size_t>(ui::UTF16IndexToOffset(text_, 0, text_.length())); 955 static_cast<size_t>(ui::UTF16IndexToOffset(text_, 0, text_.length()));
955 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); 956 layout_text_.assign(obscured_text_length, kPasswordReplacementChar);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 cursor_bounds_ += delta_offset; 1028 cursor_bounds_ += delta_offset;
1028 } 1029 }
1029 1030
1030 void RenderText::DrawSelection(Canvas* canvas) { 1031 void RenderText::DrawSelection(Canvas* canvas) {
1031 const std::vector<Rect> sel = GetSubstringBounds(selection()); 1032 const std::vector<Rect> sel = GetSubstringBounds(selection());
1032 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) 1033 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i)
1033 canvas->FillRect(*i, selection_background_focused_color_); 1034 canvas->FillRect(*i, selection_background_focused_color_);
1034 } 1035 }
1035 1036
1036 } // namespace gfx 1037 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/render_text_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698