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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } | 86 } |
87 | 87 |
88 // Converts |Font::FontStyle| flags to |SkTypeface::Style| flags. | 88 // Converts |Font::FontStyle| flags to |SkTypeface::Style| flags. |
89 SkTypeface::Style ConvertFontStyleToSkiaTypefaceStyle(int font_style) { | 89 SkTypeface::Style ConvertFontStyleToSkiaTypefaceStyle(int font_style) { |
90 int skia_style = SkTypeface::kNormal; | 90 int skia_style = SkTypeface::kNormal; |
91 skia_style |= (font_style & Font::BOLD) ? SkTypeface::kBold : 0; | 91 skia_style |= (font_style & Font::BOLD) ? SkTypeface::kBold : 0; |
92 skia_style |= (font_style & Font::ITALIC) ? SkTypeface::kItalic : 0; | 92 skia_style |= (font_style & Font::ITALIC) ? SkTypeface::kItalic : 0; |
93 return static_cast<SkTypeface::Style>(skia_style); | 93 return static_cast<SkTypeface::Style>(skia_style); |
94 } | 94 } |
95 | 95 |
| 96 int round(float value) { |
| 97 return static_cast<int>(floor(value + 0.5f)); |
| 98 } |
| 99 |
96 // Given |font| and |display_width|, returns the width of the fade gradient. | 100 // Given |font| and |display_width|, returns the width of the fade gradient. |
97 int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { | 101 int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { |
98 // Fade in/out about 2.5 characters of the beginning/end of the string. | 102 // Fade in/out about 3 characters of the beginning/end of the string. |
99 // The .5 here is helpful if one of the characters is a space. | 103 // Use a 1/3 of the display width if the display width is very short. |
100 // Use a quarter of the display width if the display width is very short. | 104 const int narrow_width = font_list.GetExpectedTextWidth(3); |
101 const int average_character_width = font_list.GetExpectedTextWidth(1); | 105 const int gradient_width = std::min(narrow_width, round(display_width / 3.f)); |
102 const double gradient_width = std::min(average_character_width * 2.5, | 106 DCHECK_GE(gradient_width, 0); |
103 display_width / 4.0); | 107 return gradient_width; |
104 DCHECK_GE(gradient_width, 0.0); | |
105 return static_cast<int>(floor(gradient_width + 0.5)); | |
106 } | 108 } |
107 | 109 |
108 // Appends to |positions| and |colors| values corresponding to the fade over | 110 // Appends to |positions| and |colors| values corresponding to the fade over |
109 // |fade_rect| from color |c0| to color |c1|. | 111 // |fade_rect| from color |c0| to color |c1|. |
110 void AddFadeEffect(const Rect& text_rect, | 112 void AddFadeEffect(const Rect& text_rect, |
111 const Rect& fade_rect, | 113 const Rect& fade_rect, |
112 SkColor c0, | 114 SkColor c0, |
113 SkColor c1, | 115 SkColor c1, |
114 std::vector<SkScalar>* positions, | 116 std::vector<SkScalar>* positions, |
115 std::vector<SkColor>* colors) { | 117 std::vector<SkColor>* colors) { |
116 const SkScalar left = static_cast<SkScalar>(fade_rect.x() - text_rect.x()); | 118 const SkScalar left = static_cast<SkScalar>(fade_rect.x() - text_rect.x()); |
117 const SkScalar width = static_cast<SkScalar>(fade_rect.width()); | 119 const SkScalar width = static_cast<SkScalar>(fade_rect.width()); |
118 const SkScalar p0 = left / text_rect.width(); | 120 const SkScalar p0 = left / text_rect.width(); |
119 const SkScalar p1 = (left + width) / text_rect.width(); | 121 const SkScalar p1 = (left + width) / text_rect.width(); |
120 // Prepend 0.0 to |positions|, as required by Skia. | 122 // Prepend 0.0 to |positions|, as required by Skia. |
121 if (positions->empty() && p0 != 0.0) { | 123 if (positions->empty() && p0 != 0.0) { |
122 positions->push_back(0.0); | 124 positions->push_back(0.0); |
123 colors->push_back(c0); | 125 colors->push_back(c0); |
124 } | 126 } |
125 positions->push_back(p0); | 127 positions->push_back(p0); |
126 colors->push_back(c0); | 128 colors->push_back(c0); |
127 positions->push_back(p1); | 129 positions->push_back(p1); |
128 colors->push_back(c1); | 130 colors->push_back(c1); |
129 } | 131 } |
130 | 132 |
131 // Creates a SkShader to fade the text, with |left_part| specifying the left | 133 // Creates a SkShader to fade the text, with |left_part| specifying the left |
132 // fade effect, if any, and |right_part| specifying the right fade effect. | 134 // fade effect, if any, and |right_part| specifying the right fade effect. |
133 skia::RefPtr<SkShader> CreateFadeShader(const Rect& text_rect, | 135 skia::RefPtr<SkShader> CreateFadeShader(const FontList& font_list, |
| 136 const Rect& text_rect, |
134 const Rect& left_part, | 137 const Rect& left_part, |
135 const Rect& right_part, | 138 const Rect& right_part, |
136 SkColor color) { | 139 SkColor color) { |
137 // Fade alpha of 51/255 corresponds to a fade of 0.2 of the original color. | 140 // In general, fade down to 0 alpha. But when the available width is less |
138 const SkColor fade_color = SkColorSetA(color, 51); | 141 // than four characters, linearly ramp up the fade target alpha to as high as |
| 142 // 20% at zero width. This allows the user to see the last faded characters a |
| 143 // little better when there are only a few characters shown. |
| 144 const float width_fraction = |
| 145 text_rect.width() / static_cast<float>(font_list.GetExpectedTextWidth(4)); |
| 146 const SkAlpha kAlphaAtZeroWidth = 51; |
| 147 const SkAlpha alpha = (width_fraction < 1) ? |
| 148 static_cast<SkAlpha>(round((1 - width_fraction) * kAlphaAtZeroWidth)) : 0; |
| 149 const SkColor fade_color = SkColorSetA(color, alpha); |
| 150 |
139 std::vector<SkScalar> positions; | 151 std::vector<SkScalar> positions; |
140 std::vector<SkColor> colors; | 152 std::vector<SkColor> colors; |
141 | 153 |
142 if (!left_part.IsEmpty()) | 154 if (!left_part.IsEmpty()) |
143 AddFadeEffect(text_rect, left_part, fade_color, color, | 155 AddFadeEffect(text_rect, left_part, fade_color, color, |
144 &positions, &colors); | 156 &positions, &colors); |
145 if (!right_part.IsEmpty()) | 157 if (!right_part.IsEmpty()) |
146 AddFadeEffect(text_rect, right_part, color, fade_color, | 158 AddFadeEffect(text_rect, right_part, color, fade_color, |
147 &positions, &colors); | 159 &positions, &colors); |
148 DCHECK(!positions.empty()); | 160 DCHECK(!positions.empty()); |
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 if (horizontal_alignment != ALIGN_RIGHT) { | 1214 if (horizontal_alignment != ALIGN_RIGHT) { |
1203 right_part = solid_part; | 1215 right_part = solid_part; |
1204 right_part.Inset(solid_part.width() - gradient_width, 0, 0, 0); | 1216 right_part.Inset(solid_part.width() - gradient_width, 0, 0, 0); |
1205 solid_part.Inset(0, 0, gradient_width, 0); | 1217 solid_part.Inset(0, 0, gradient_width, 0); |
1206 } | 1218 } |
1207 | 1219 |
1208 Rect text_rect = display_rect(); | 1220 Rect text_rect = display_rect(); |
1209 text_rect.Inset(GetAlignmentOffset(0).x(), 0, 0, 0); | 1221 text_rect.Inset(GetAlignmentOffset(0).x(), 0, 0, 0); |
1210 | 1222 |
1211 // TODO(msw): Use the actual text colors corresponding to each faded part. | 1223 // TODO(msw): Use the actual text colors corresponding to each faded part. |
1212 skia::RefPtr<SkShader> shader = CreateFadeShader( | 1224 skia::RefPtr<SkShader> shader = |
1213 text_rect, left_part, right_part, colors_.breaks().front().second); | 1225 CreateFadeShader(font_list(), text_rect, left_part, right_part, |
| 1226 colors_.breaks().front().second); |
1214 if (shader) | 1227 if (shader) |
1215 renderer->SetShader(shader.get()); | 1228 renderer->SetShader(shader.get()); |
1216 } | 1229 } |
1217 | 1230 |
1218 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { | 1231 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { |
1219 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(shadows_); | 1232 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(shadows_); |
1220 renderer->SetDrawLooper(looper.get()); | 1233 renderer->SetDrawLooper(looper.get()); |
1221 } | 1234 } |
1222 | 1235 |
1223 base::i18n::TextDirection RenderText::GetTextDirection( | 1236 base::i18n::TextDirection RenderText::GetTextDirection( |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1521 | 1534 |
1522 SetDisplayOffset(display_offset_.x() + delta_x); | 1535 SetDisplayOffset(display_offset_.x() + delta_x); |
1523 } | 1536 } |
1524 | 1537 |
1525 void RenderText::DrawSelection(Canvas* canvas) { | 1538 void RenderText::DrawSelection(Canvas* canvas) { |
1526 for (const Rect& s : GetSubstringBounds(selection())) | 1539 for (const Rect& s : GetSubstringBounds(selection())) |
1527 canvas->FillRect(s, selection_background_focused_color_); | 1540 canvas->FillRect(s, selection_background_focused_color_); |
1528 } | 1541 } |
1529 | 1542 |
1530 } // namespace gfx | 1543 } // namespace gfx |
OLD | NEW |