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

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

Issue 2439693002: MacViews: Use bullets for displaying obscured text. (Closed)
Patch Set: Fix tests. Created 4 years, 2 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
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 <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 private: 117 private:
118 RenderText* render_text_; 118 RenderText* render_text_;
119 119
120 DISALLOW_COPY_AND_ASSIGN(RenderTextTestApi); 120 DISALLOW_COPY_AND_ASSIGN(RenderTextTestApi);
121 }; 121 };
122 122
123 } // namespace test 123 } // namespace test
124 124
125 namespace { 125 namespace {
126 126
127 #if defined(OS_MACOSX)
sky 2016/10/21 15:06:41 Move kPasswordReplacementChar to header so you are
karandeepb 2016/10/24 12:09:54 Done.
128 const base::char16 kPasswordReplacementChar = 0x2022;
129 #else
130 const base::char16 kPasswordReplacementChar = '*';
131 #endif
132
127 // An enum specifying the different RenderText implementations to be tested. 133 // An enum specifying the different RenderText implementations to be tested.
128 enum RenderTextBackend { 134 enum RenderTextBackend {
129 RENDER_TEXT_HARFBUZZ, 135 RENDER_TEXT_HARFBUZZ,
130 RENDER_TEXT_MAC, 136 RENDER_TEXT_MAC,
131 }; 137 };
132 138
133 // Parameterised test name generator for tests depending on RenderTextBackend. 139 // Parameterised test name generator for tests depending on RenderTextBackend.
134 struct PrintRenderTextBackend { 140 struct PrintRenderTextBackend {
135 template <class ParamType> 141 template <class ParamType>
136 std::string operator()(const testing::TestParamInfo<ParamType>& info) const { 142 std::string operator()(const testing::TestParamInfo<ParamType>& info) const {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 EXPECT_EQ(expected_attr->diagonal_strike, actual_attr->diagonal_strike); 282 EXPECT_EQ(expected_attr->diagonal_strike, actual_attr->diagonal_strike);
277 EXPECT_EQ(expected_attr->font.GetFontName(), 283 EXPECT_EQ(expected_attr->font.GetFontName(),
278 actual_attr->font.GetFontName()); 284 actual_attr->font.GetFontName());
279 EXPECT_EQ(expected_attr->font.GetFontSize(), 285 EXPECT_EQ(expected_attr->font.GetFontSize(),
280 actual_attr->font.GetFontSize()); 286 actual_attr->font.GetFontSize());
281 EXPECT_EQ(expected_attr->font.GetWeight(), actual_attr->font.GetWeight()); 287 EXPECT_EQ(expected_attr->font.GetWeight(), actual_attr->font.GetWeight());
282 EXPECT_EQ(expected_attr->font.GetStyle(), actual_attr->font.GetStyle()); 288 EXPECT_EQ(expected_attr->font.GetStyle(), actual_attr->font.GetStyle());
283 } 289 }
284 } 290 }
285 291
292 // Helper method to return an obscured string of the given |length|, with the
293 // |reveal_index| filled with |reveal_char|.
294 base::string16 GetObscuredString(size_t length,
295 int reveal_index,
296 base::char16 reveal_char) {
297 std::vector<base::char16> arr(length, kPasswordReplacementChar);
298 arr[reveal_index] = reveal_char;
299 return base::string16(arr.begin(), arr.end());
300 }
301
302 // Helper method to return an obscured string of the given |length|.
303 base::string16 GetObscuredString(size_t length) {
304 return base::string16(length, kPasswordReplacementChar);
305 }
306
286 // The class which records the drawing operations so that the test case can 307 // The class which records the drawing operations so that the test case can
287 // verify where exactly the glyphs are drawn. 308 // verify where exactly the glyphs are drawn.
288 class TestSkiaTextRenderer : public internal::SkiaTextRenderer { 309 class TestSkiaTextRenderer : public internal::SkiaTextRenderer {
289 public: 310 public:
290 struct TextLog { 311 struct TextLog {
291 TextLog() : glyph_count(0u), color(SK_ColorTRANSPARENT) {} 312 TextLog() : glyph_count(0u), color(SK_ColorTRANSPARENT) {}
292 PointF origin; 313 PointF origin;
293 size_t glyph_count; 314 size_t glyph_count;
294 SkColor color; 315 SkColor color;
295 }; 316 };
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, selection_behavior); 749 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, selection_behavior);
729 EXPECT_EQ(SelectionModel(Range(select ? 0 : len, len), CURSOR_FORWARD), 750 EXPECT_EQ(SelectionModel(Range(select ? 0 : len, len), CURSOR_FORWARD),
730 render_text->selection_model()); 751 render_text->selection_model());
731 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, selection_behavior); 752 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, selection_behavior);
732 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 753 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
733 } 754 }
734 755
735 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 756 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
736 TEST_P(RenderTextHarfBuzzTest, ObscuredText) { 757 TEST_P(RenderTextHarfBuzzTest, ObscuredText) {
737 const base::string16 seuss = ASCIIToUTF16("hop on pop"); 758 const base::string16 seuss = ASCIIToUTF16("hop on pop");
738 const base::string16 no_seuss = ASCIIToUTF16("**********"); 759 const base::string16 no_seuss = GetObscuredString(seuss.length());
739 RenderText* render_text = GetRenderText(); 760 RenderText* render_text = GetRenderText();
740 761
741 // GetLayoutText() returns asterisks when the obscured bit is set. 762 // GetDisplayText() returns a string filled with kPasswordReplacementChar when
763 // the obscured bit is set.
742 render_text->SetText(seuss); 764 render_text->SetText(seuss);
743 render_text->SetObscured(true); 765 render_text->SetObscured(true);
744 EXPECT_EQ(seuss, render_text->text()); 766 EXPECT_EQ(seuss, render_text->text());
745 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 767 EXPECT_EQ(no_seuss, render_text->GetDisplayText());
746 render_text->SetObscured(false); 768 render_text->SetObscured(false);
747 EXPECT_EQ(seuss, render_text->text()); 769 EXPECT_EQ(seuss, render_text->text());
748 EXPECT_EQ(seuss, render_text->GetDisplayText()); 770 EXPECT_EQ(seuss, render_text->GetDisplayText());
749 771
750 render_text->SetObscured(true); 772 render_text->SetObscured(true);
751 773
752 // Surrogate pairs are counted as one code point. 774 // Surrogate pairs are counted as one code point.
753 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 0}; 775 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 0};
754 render_text->SetText(invalid_surrogates); 776 render_text->SetText(invalid_surrogates);
755 EXPECT_EQ(ASCIIToUTF16("**"), render_text->GetDisplayText()); 777 EXPECT_EQ(GetObscuredString(2), render_text->GetDisplayText());
756 const base::char16 valid_surrogates[] = {0xD800, 0xDC00, 0}; 778 const base::char16 valid_surrogates[] = {0xD800, 0xDC00, 0};
757 render_text->SetText(valid_surrogates); 779 render_text->SetText(valid_surrogates);
758 EXPECT_EQ(ASCIIToUTF16("*"), render_text->GetDisplayText()); 780 EXPECT_EQ(GetObscuredString(1), render_text->GetDisplayText());
759 EXPECT_EQ(0U, render_text->cursor_position()); 781 EXPECT_EQ(0U, render_text->cursor_position());
760 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 782 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
761 EXPECT_EQ(2U, render_text->cursor_position()); 783 EXPECT_EQ(2U, render_text->cursor_position());
762 784
763 // Test index conversion and cursor validity with a valid surrogate pair. 785 // Test index conversion and cursor validity with a valid surrogate pair.
764 EXPECT_EQ(0U, test_api()->TextIndexToDisplayIndex(0U)); 786 EXPECT_EQ(0U, test_api()->TextIndexToDisplayIndex(0U));
765 EXPECT_EQ(1U, test_api()->TextIndexToDisplayIndex(1U)); 787 EXPECT_EQ(1U, test_api()->TextIndexToDisplayIndex(1U));
766 EXPECT_EQ(1U, test_api()->TextIndexToDisplayIndex(2U)); 788 EXPECT_EQ(1U, test_api()->TextIndexToDisplayIndex(2U));
767 EXPECT_EQ(0U, test_api()->DisplayIndexToTextIndex(0U)); 789 EXPECT_EQ(0U, test_api()->DisplayIndexToTextIndex(0U));
768 EXPECT_EQ(2U, test_api()->DisplayIndexToTextIndex(1U)); 790 EXPECT_EQ(2U, test_api()->DisplayIndexToTextIndex(1U));
(...skipping 22 matching lines...) Expand all
791 }; 813 };
792 for (size_t i = 0; i < arraysize(texts); ++i) { 814 for (size_t i = 0; i < arraysize(texts); ++i) {
793 base::string16 text = WideToUTF16(texts[i]); 815 base::string16 text = WideToUTF16(texts[i]);
794 TestVisualCursorMotionInObscuredField(render_text, text, SELECTION_NONE); 816 TestVisualCursorMotionInObscuredField(render_text, text, SELECTION_NONE);
795 TestVisualCursorMotionInObscuredField(render_text, text, SELECTION_RETAIN); 817 TestVisualCursorMotionInObscuredField(render_text, text, SELECTION_RETAIN);
796 } 818 }
797 } 819 }
798 820
799 TEST_P(RenderTextTest, RevealObscuredText) { 821 TEST_P(RenderTextTest, RevealObscuredText) {
800 const base::string16 seuss = ASCIIToUTF16("hop on pop"); 822 const base::string16 seuss = ASCIIToUTF16("hop on pop");
801 const base::string16 no_seuss = ASCIIToUTF16("**********"); 823 const base::string16 no_seuss = GetObscuredString(seuss.length());
802 RenderText* render_text = GetRenderText(); 824 RenderText* render_text = GetRenderText();
803 825
804 render_text->SetText(seuss); 826 render_text->SetText(seuss);
805 render_text->SetObscured(true); 827 render_text->SetObscured(true);
806 EXPECT_EQ(seuss, render_text->text()); 828 EXPECT_EQ(seuss, render_text->text());
807 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 829 EXPECT_EQ(no_seuss, render_text->GetDisplayText());
808 830
809 // Valid reveal index and new revealed index clears previous one. 831 // Valid reveal index and new revealed index clears previous one.
810 render_text->RenderText::SetObscuredRevealIndex(0); 832 render_text->RenderText::SetObscuredRevealIndex(0);
811 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetDisplayText()); 833 EXPECT_EQ(GetObscuredString(seuss.length(), 0, 'h'),
834 render_text->GetDisplayText());
812 render_text->RenderText::SetObscuredRevealIndex(1); 835 render_text->RenderText::SetObscuredRevealIndex(1);
813 EXPECT_EQ(ASCIIToUTF16("*o********"), render_text->GetDisplayText()); 836 EXPECT_EQ(GetObscuredString(seuss.length(), 1, 'o'),
837 render_text->GetDisplayText());
814 render_text->RenderText::SetObscuredRevealIndex(2); 838 render_text->RenderText::SetObscuredRevealIndex(2);
815 EXPECT_EQ(ASCIIToUTF16("**p*******"), render_text->GetDisplayText()); 839 EXPECT_EQ(GetObscuredString(seuss.length(), 2, 'p'),
840 render_text->GetDisplayText());
816 841
817 // Invalid reveal index. 842 // Invalid reveal index.
818 render_text->RenderText::SetObscuredRevealIndex(-1); 843 render_text->RenderText::SetObscuredRevealIndex(-1);
819 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 844 EXPECT_EQ(no_seuss, render_text->GetDisplayText());
820 render_text->RenderText::SetObscuredRevealIndex(seuss.length() + 1); 845 render_text->RenderText::SetObscuredRevealIndex(seuss.length() + 1);
821 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 846 EXPECT_EQ(no_seuss, render_text->GetDisplayText());
822 847
823 // SetObscured clears the revealed index. 848 // SetObscured clears the revealed index.
824 render_text->RenderText::SetObscuredRevealIndex(0); 849 render_text->RenderText::SetObscuredRevealIndex(0);
825 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetDisplayText()); 850 EXPECT_EQ(GetObscuredString(seuss.length(), 0, 'h'),
851 render_text->GetDisplayText());
826 render_text->SetObscured(false); 852 render_text->SetObscured(false);
827 EXPECT_EQ(seuss, render_text->GetDisplayText()); 853 EXPECT_EQ(seuss, render_text->GetDisplayText());
828 render_text->SetObscured(true); 854 render_text->SetObscured(true);
829 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 855 EXPECT_EQ(no_seuss, render_text->GetDisplayText());
830 856
831 // SetText clears the revealed index. 857 // SetText clears the revealed index.
832 render_text->SetText(ASCIIToUTF16("new")); 858 render_text->SetText(ASCIIToUTF16("new"));
833 EXPECT_EQ(ASCIIToUTF16("***"), render_text->GetDisplayText()); 859 EXPECT_EQ(GetObscuredString(3), render_text->GetDisplayText());
834 render_text->RenderText::SetObscuredRevealIndex(2); 860 render_text->RenderText::SetObscuredRevealIndex(2);
835 EXPECT_EQ(ASCIIToUTF16("**w"), render_text->GetDisplayText()); 861 EXPECT_EQ(GetObscuredString(3, 2, 'w'), render_text->GetDisplayText());
836 render_text->SetText(ASCIIToUTF16("new longer")); 862 render_text->SetText(ASCIIToUTF16("new longer"));
837 EXPECT_EQ(ASCIIToUTF16("**********"), render_text->GetDisplayText()); 863 EXPECT_EQ(GetObscuredString(10), render_text->GetDisplayText());
838 864
839 // Text with invalid surrogates. 865 // Text with invalid surrogates.
840 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0}; 866 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0};
841 render_text->SetText(invalid_surrogates); 867 render_text->SetText(invalid_surrogates);
842 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetDisplayText()); 868 EXPECT_EQ(GetObscuredString(5), render_text->GetDisplayText());
843 render_text->RenderText::SetObscuredRevealIndex(0); 869 render_text->RenderText::SetObscuredRevealIndex(0);
844 const base::char16 invalid_expect_0[] = {0xDC00, '*', '*', '*', '*', 0}; 870 EXPECT_EQ(GetObscuredString(5, 0, 0xDC00), render_text->GetDisplayText());
845 EXPECT_EQ(invalid_expect_0, render_text->GetDisplayText());
846 render_text->RenderText::SetObscuredRevealIndex(1); 871 render_text->RenderText::SetObscuredRevealIndex(1);
847 const base::char16 invalid_expect_1[] = {'*', 0xD800, '*', '*', '*', 0}; 872 EXPECT_EQ(GetObscuredString(5, 1, 0xD800), render_text->GetDisplayText());
848 EXPECT_EQ(invalid_expect_1, render_text->GetDisplayText());
849 render_text->RenderText::SetObscuredRevealIndex(2); 873 render_text->RenderText::SetObscuredRevealIndex(2);
850 EXPECT_EQ(ASCIIToUTF16("**h**"), render_text->GetDisplayText()); 874 EXPECT_EQ(GetObscuredString(5, 2, 'h'), render_text->GetDisplayText());
851 875
852 // Text with valid surrogates before and after the reveal index. 876 // Text with valid surrogates before and after the reveal index.
853 const base::char16 valid_surrogates[] = 877 const base::char16 valid_surrogates[] =
854 {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0}; 878 {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0};
855 render_text->SetText(valid_surrogates); 879 render_text->SetText(valid_surrogates);
856 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetDisplayText()); 880 EXPECT_EQ(GetObscuredString(5), render_text->GetDisplayText());
857 render_text->RenderText::SetObscuredRevealIndex(0); 881 render_text->RenderText::SetObscuredRevealIndex(0);
858 const base::char16 valid_expect_0_and_1[] = 882 const base::char16 valid_expect_0_and_1[] = {0xD800,
859 {0xD800, 0xDC00, '*', '*', '*', '*', 0}; 883 0xDC00,
884 kPasswordReplacementChar,
885 kPasswordReplacementChar,
886 kPasswordReplacementChar,
887 kPasswordReplacementChar,
888 0};
860 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText()); 889 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText());
861 render_text->RenderText::SetObscuredRevealIndex(1); 890 render_text->RenderText::SetObscuredRevealIndex(1);
862 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText()); 891 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText());
863 render_text->RenderText::SetObscuredRevealIndex(2); 892 render_text->RenderText::SetObscuredRevealIndex(2);
864 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetDisplayText()); 893 EXPECT_EQ(GetObscuredString(5, 1, 'h'), render_text->GetDisplayText());
865 render_text->RenderText::SetObscuredRevealIndex(5); 894 render_text->RenderText::SetObscuredRevealIndex(5);
866 const base::char16 valid_expect_5_and_6[] = 895 const base::char16 valid_expect_5_and_6[] = {kPasswordReplacementChar,
867 {'*', '*', '*', '*', 0xD800, 0xDC00, 0}; 896 kPasswordReplacementChar,
897 kPasswordReplacementChar,
898 kPasswordReplacementChar,
899 0xD800,
900 0xDC00,
901 0};
868 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText()); 902 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText());
869 render_text->RenderText::SetObscuredRevealIndex(6); 903 render_text->RenderText::SetObscuredRevealIndex(6);
870 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText()); 904 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText());
871 } 905 }
872 906
873 TEST_P(RenderTextTest, ObscuredEmoji) { 907 TEST_P(RenderTextTest, ObscuredEmoji) {
874 // Ensures text itemization doesn't crash on obscured multi-char glyphs. 908 // Ensures text itemization doesn't crash on obscured multi-char glyphs.
875 RenderText* render_text = GetRenderText(); 909 RenderText* render_text = GetRenderText();
876 render_text->SetObscured(true); 910 render_text->SetObscured(true);
877 // Test the "Grinning face with smiling eyes" character followed by 'y'. 911 // Test the "Grinning face with smiling eyes" character followed by 'y'.
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 << "For case " << i << ": " << cases[i].text; 1130 << "For case " << i << ": " << cases[i].text;
1097 } 1131 }
1098 } 1132 }
1099 1133
1100 TEST_P(RenderTextTest, TruncatedObscuredText) { 1134 TEST_P(RenderTextTest, TruncatedObscuredText) {
1101 RenderText* render_text = GetRenderText(); 1135 RenderText* render_text = GetRenderText();
1102 render_text->set_truncate_length(3); 1136 render_text->set_truncate_length(3);
1103 render_text->SetObscured(true); 1137 render_text->SetObscured(true);
1104 render_text->SetText(WideToUTF16(L"abcdef")); 1138 render_text->SetText(WideToUTF16(L"abcdef"));
1105 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); 1139 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text());
1106 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetDisplayText()); 1140 EXPECT_EQ(GetObscuredString(3, 2, 0x2026), render_text->GetDisplayText());
1107 } 1141 }
1108 1142
1109 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 1143 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1110 TEST_P(RenderTextHarfBuzzTest, TruncatedCursorMovementLTR) { 1144 TEST_P(RenderTextHarfBuzzTest, TruncatedCursorMovementLTR) {
1111 RenderText* render_text = GetRenderText(); 1145 RenderText* render_text = GetRenderText();
1112 render_text->set_truncate_length(2); 1146 render_text->set_truncate_length(2);
1113 render_text->SetText(WideToUTF16(L"abcd")); 1147 render_text->SetText(WideToUTF16(L"abcd"));
1114 1148
1115 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 1149 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
1116 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1150 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
(...skipping 2947 matching lines...) Expand 10 before | Expand all | Expand 10 after
4064 ::testing::Values(RENDER_TEXT_HARFBUZZ), 4098 ::testing::Values(RENDER_TEXT_HARFBUZZ),
4065 PrintRenderTextBackend()); 4099 PrintRenderTextBackend());
4066 #endif 4100 #endif
4067 4101
4068 INSTANTIATE_TEST_CASE_P(, 4102 INSTANTIATE_TEST_CASE_P(,
4069 RenderTextHarfBuzzTest, 4103 RenderTextHarfBuzzTest,
4070 ::testing::Values(RENDER_TEXT_HARFBUZZ), 4104 ::testing::Values(RENDER_TEXT_HARFBUZZ),
4071 PrintRenderTextBackend()); 4105 PrintRenderTextBackend());
4072 4106
4073 } // namespace gfx 4107 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698