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

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

Issue 2969623004: RenderText: Allow strike-through line thickness to be customized. (Closed)
Patch Set: Created 3 years, 5 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
« ui/gfx/render_text.h ('K') | « ui/gfx/render_text.h ('k') | no next file » | 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 <limits.h> 7 #include <limits.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <climits> 10 #include <climits>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 namespace gfx { 47 namespace gfx {
48 48
49 namespace { 49 namespace {
50 50
51 // Default color used for the text and cursor. 51 // Default color used for the text and cursor.
52 const SkColor kDefaultColor = SK_ColorBLACK; 52 const SkColor kDefaultColor = SK_ColorBLACK;
53 53
54 // Default color used for drawing selection background. 54 // Default color used for drawing selection background.
55 const SkColor kDefaultSelectionBackgroundColor = SK_ColorGRAY; 55 const SkColor kDefaultSelectionBackgroundColor = SK_ColorGRAY;
56 56
57 // Fraction of the text size to lower a strike through below the baseline. 57 // Fraction of the text size to lower a strike through below the baseline.
cjgrant 2017/06/30 19:04:25 Should this be "raise the strike through above the
msw 2017/06/30 20:51:23 That seems fine to me, just make sure you don't ac
cjgrant 2017/07/05 16:16:48 I did some underline and strike before/after tests
58 const SkScalar kStrikeThroughOffset = (-SK_Scalar1 * 6 / 21); 58 const SkScalar kStrikeThroughOffset = (-SK_Scalar1 * 29 / 126);
cjgrant 2017/06/30 21:06:24 Forgot to say, this relatively nasty-looking const
msw 2017/06/30 23:01:32 Acknowledged.
cjgrant 2017/07/05 16:16:48 And, it's now actually correct. :|
59 // Fraction of the text size to lower an underline below the baseline. 59 // Fraction of the text size to lower an underline below the baseline.
60 const SkScalar kUnderlineOffset = (SK_Scalar1 / 9); 60 const SkScalar kUnderlineOffset = (SK_Scalar1 / 9);
61 // Fraction of the text size to use for a strike through or under-line. 61 // Default fraction of the text size to use for a strike through or under-line.
msw 2017/06/30 20:51:23 optional nit: "underline" here to match most uses
cjgrant 2017/07/05 16:16:48 Done.
62 const SkScalar kLineThickness = (SK_Scalar1 / 18); 62 const SkScalar kLineThickness = (SK_Scalar1 / 18);
msw 2017/06/30 20:51:23 optional nit: kLineThicknessFactor
cjgrant 2017/07/05 16:16:48 Done.
63 63
64 // Invalid value of baseline. Assigning this value to |baseline_| causes 64 // Invalid value of baseline. Assigning this value to |baseline_| causes
65 // re-calculation of baseline. 65 // re-calculation of baseline.
66 const int kInvalidBaseline = INT_MAX; 66 const int kInvalidBaseline = INT_MAX;
67 67
68 int round(float value) { 68 int round(float value) {
69 return static_cast<int>(floor(value + 0.5f)); 69 return static_cast<int>(floor(value + 0.5f));
70 } 70 }
71 71
72 // Given |font| and |display_width|, returns the width of the fade gradient. 72 // Given |font| and |display_width|, returns the width of the fade gradient.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD)); 181 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD));
182 break_list->ApplyValue(current_break->second, range); 182 break_list->ApplyValue(current_break->second, range);
183 } 183 }
184 } 184 }
185 } 185 }
186 186
187 } // namespace 187 } // namespace
188 188
189 namespace internal { 189 namespace internal {
190 190
191 // Value of |underline_thickness_| that indicates that underline metrics have
192 // not been set explicitly.
193 const SkScalar kUnderlineMetricsNotSet = -1.0f;
cjgrant 2017/06/30 19:04:25 I don't see that underscore overrides are actually
msw 2017/06/30 20:51:23 Afaict, you're right; thanks for removing this unu
194
195 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) 191 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas)
196 : canvas_(canvas), 192 : canvas_(canvas),
197 canvas_skia_(canvas->sk_canvas()), 193 canvas_skia_(canvas->sk_canvas()),
198 underline_thickness_(kUnderlineMetricsNotSet), 194 strike_thickness_factor_(kLineThickness) {
199 underline_position_(0.0f) {
200 DCHECK(canvas_skia_); 195 DCHECK(canvas_skia_);
201 flags_.setTextEncoding(cc::PaintFlags::kGlyphID_TextEncoding); 196 flags_.setTextEncoding(cc::PaintFlags::kGlyphID_TextEncoding);
202 flags_.setStyle(cc::PaintFlags::kFill_Style); 197 flags_.setStyle(cc::PaintFlags::kFill_Style);
203 flags_.setAntiAlias(true); 198 flags_.setAntiAlias(true);
204 flags_.setSubpixelText(true); 199 flags_.setSubpixelText(true);
205 flags_.setLCDRenderText(true); 200 flags_.setLCDRenderText(true);
206 flags_.setHinting(cc::PaintFlags::kNormal_Hinting); 201 flags_.setHinting(cc::PaintFlags::kNormal_Hinting);
207 } 202 }
208 203
209 SkiaTextRenderer::~SkiaTextRenderer() { 204 SkiaTextRenderer::~SkiaTextRenderer() {
(...skipping 17 matching lines...) Expand all
227 } 222 }
228 223
229 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { 224 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) {
230 flags_.setColor(foreground); 225 flags_.setColor(foreground);
231 } 226 }
232 227
233 void SkiaTextRenderer::SetShader(std::unique_ptr<cc::PaintShader> shader) { 228 void SkiaTextRenderer::SetShader(std::unique_ptr<cc::PaintShader> shader) {
234 flags_.setShader(std::move(shader)); 229 flags_.setShader(std::move(shader));
235 } 230 }
236 231
237 void SkiaTextRenderer::SetUnderlineMetrics(SkScalar thickness, 232 void SkiaTextRenderer::SetStrikeThicknessFactor(SkScalar factor) {
238 SkScalar position) { 233 strike_thickness_factor_ = factor;
239 underline_thickness_ = thickness;
240 underline_position_ = position;
241 } 234 }
242 235
243 void SkiaTextRenderer::DrawPosText(const SkPoint* pos, 236 void SkiaTextRenderer::DrawPosText(const SkPoint* pos,
244 const uint16_t* glyphs, 237 const uint16_t* glyphs,
245 size_t glyph_count) { 238 size_t glyph_count) {
246 const size_t byte_length = glyph_count * sizeof(glyphs[0]); 239 const size_t byte_length = glyph_count * sizeof(glyphs[0]);
247 canvas_skia_->drawPosText(&glyphs[0], byte_length, &pos[0], flags_); 240 canvas_skia_->drawPosText(&glyphs[0], byte_length, &pos[0], flags_);
248 } 241 }
249 242
250 void SkiaTextRenderer::DrawDecorations(int x, 243 void SkiaTextRenderer::DrawDecorations(int x,
251 int y, 244 int y,
252 int width, 245 int width,
253 bool underline, 246 bool underline,
254 bool strike) { 247 bool strike) {
255 if (underline) 248 if (underline)
256 DrawUnderline(x, y, width); 249 DrawUnderline(x, y, width);
257 if (strike) 250 if (strike)
258 DrawStrike(x, y, width); 251 DrawStrike(x, y, width);
259 } 252 }
260 253
261 void SkiaTextRenderer::DrawUnderline(int x, int y, int width) { 254 void SkiaTextRenderer::DrawUnderline(int x, int y, int width) {
262 SkScalar x_scalar = SkIntToScalar(x); 255 SkScalar x_scalar = SkIntToScalar(x);
256 const SkScalar text_size = flags_.getTextSize();
263 SkRect r = SkRect::MakeLTRB( 257 SkRect r = SkRect::MakeLTRB(
264 x_scalar, y + underline_position_, x_scalar + width, 258 x_scalar, y + text_size * kUnderlineOffset, x_scalar + width,
265 y + underline_position_ + underline_thickness_); 259 y + (text_size * (kUnderlineOffset + kLineThickness)));
266 if (underline_thickness_ == kUnderlineMetricsNotSet) {
267 const SkScalar text_size = flags_.getTextSize();
268 r.fTop = text_size * kUnderlineOffset + y;
269 r.fBottom = r.fTop + text_size * kLineThickness;
270 }
271 canvas_skia_->drawRect(r, flags_); 260 canvas_skia_->drawRect(r, flags_);
272 } 261 }
273 262
274 void SkiaTextRenderer::DrawStrike(int x, int y, int width) const { 263 void SkiaTextRenderer::DrawStrike(int x, int y, int width) const {
275 const SkScalar text_size = flags_.getTextSize(); 264 const SkScalar text_size = flags_.getTextSize();
276 const SkScalar height = text_size * kLineThickness; 265 const SkScalar height = text_size * strike_thickness_factor_;
277 const SkScalar offset = text_size * kStrikeThroughOffset + y; 266 const SkScalar offset = text_size * kStrikeThroughOffset - height / 2 + y;
278 SkScalar x_scalar = SkIntToScalar(x); 267 SkScalar x_scalar = SkIntToScalar(x);
279 const SkRect r = 268 const SkRect r =
280 SkRect::MakeLTRB(x_scalar, offset, x_scalar + width, offset + height); 269 SkRect::MakeLTRB(x_scalar, offset, x_scalar + width, offset + height);
281 canvas_skia_->drawRect(r, flags_); 270 canvas_skia_->drawRect(r, flags_);
282 } 271 }
283 272
284 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, 273 StyleIterator::StyleIterator(const BreakList<SkColor>& colors,
285 const BreakList<BaselineStyle>& baselines, 274 const BreakList<BaselineStyle>& baselines,
286 const BreakList<Font::Weight>& weights, 275 const BreakList<Font::Weight>& weights,
287 const std::vector<BreakList<bool>>& styles) 276 const std::vector<BreakList<bool>>& styles)
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 764
776 canvas->Save(); 765 canvas->Save();
777 canvas->ClipRect(clip_rect); 766 canvas->ClipRect(clip_rect);
778 } 767 }
779 768
780 if (!text().empty() && focused()) 769 if (!text().empty() && focused())
781 DrawSelection(canvas); 770 DrawSelection(canvas);
782 771
783 if (!text().empty()) { 772 if (!text().empty()) {
784 internal::SkiaTextRenderer renderer(canvas); 773 internal::SkiaTextRenderer renderer(canvas);
774 renderer.SetStrikeThicknessFactor(strike_thickness_factor_);
cjgrant 2017/06/30 19:04:25 I must be doing this wrong, but I don't see a bett
msw 2017/06/30 20:51:23 I would suggest removing SkiaTextRenderer::SetStri
cjgrant 2017/06/30 21:06:24 I'd thought about plumbing through the call path,
msw 2017/06/30 23:01:32 You could add a simple accessor |RenderText::strik
cjgrant 2017/07/05 16:16:48 I did your top-preference, and removed the DrawDec
785 DrawVisualText(&renderer); 775 DrawVisualText(&renderer);
786 } 776 }
787 777
788 if (clip_to_display_rect()) 778 if (clip_to_display_rect())
789 canvas->Restore(); 779 canvas->Restore();
790 } 780 }
791 781
792 bool RenderText::IsValidLogicalIndex(size_t index) const { 782 bool RenderText::IsValidLogicalIndex(size_t index) const {
793 // Check that the index is at a valid code point (not mid-surrgate-pair) and 783 // Check that the index is at a valid code point (not mid-surrgate-pair) and
794 // that it's not truncated from the display text (its glyph may be shown). 784 // that it's not truncated from the display text (its glyph may be shown).
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 left_rect->origin() + Vector2d(0, lines()[line_index].baseline); 962 left_rect->origin() + Vector2d(0, lines()[line_index].baseline);
973 return true; 963 return true;
974 } 964 }
975 965
976 base::string16 RenderText::GetTextFromRange(const Range& range) const { 966 base::string16 RenderText::GetTextFromRange(const Range& range) const {
977 if (range.IsValid() && range.GetMin() < text().length()) 967 if (range.IsValid() && range.GetMin() < text().length())
978 return text().substr(range.GetMin(), range.length()); 968 return text().substr(range.GetMin(), range.length());
979 return base::string16(); 969 return base::string16();
980 } 970 }
981 971
972 void RenderText::SetStrikeThicknessFactor(SkScalar factor) {
msw 2017/06/30 20:51:23 nit: this could be a simple setter defined in the
cjgrant 2017/07/05 16:16:48 Done.
973 strike_thickness_factor_ = factor;
974 }
975
982 RenderText::RenderText() 976 RenderText::RenderText()
983 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), 977 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT),
984 directionality_mode_(DIRECTIONALITY_FROM_TEXT), 978 directionality_mode_(DIRECTIONALITY_FROM_TEXT),
985 text_direction_(base::i18n::UNKNOWN_DIRECTION), 979 text_direction_(base::i18n::UNKNOWN_DIRECTION),
986 cursor_enabled_(true), 980 cursor_enabled_(true),
987 selection_color_(kDefaultColor), 981 selection_color_(kDefaultColor),
988 selection_background_focused_color_(kDefaultSelectionBackgroundColor), 982 selection_background_focused_color_(kDefaultSelectionBackgroundColor),
989 focused_(false), 983 focused_(false),
990 composition_range_(Range::InvalidRange()), 984 composition_range_(Range::InvalidRange()),
991 colors_(kDefaultColor), 985 colors_(kDefaultColor),
992 baselines_(NORMAL_BASELINE), 986 baselines_(NORMAL_BASELINE),
993 weights_(Font::Weight::NORMAL), 987 weights_(Font::Weight::NORMAL),
994 styles_(NUM_TEXT_STYLES), 988 styles_(NUM_TEXT_STYLES),
995 composition_and_selection_styles_applied_(false), 989 composition_and_selection_styles_applied_(false),
996 obscured_(false), 990 obscured_(false),
997 obscured_reveal_index_(-1), 991 obscured_reveal_index_(-1),
998 truncate_length_(0), 992 truncate_length_(0),
999 elide_behavior_(NO_ELIDE), 993 elide_behavior_(NO_ELIDE),
1000 text_elided_(false), 994 text_elided_(false),
1001 min_line_height_(0), 995 min_line_height_(0),
1002 multiline_(false), 996 multiline_(false),
1003 max_lines_(0), 997 max_lines_(0),
1004 word_wrap_behavior_(IGNORE_LONG_WORDS), 998 word_wrap_behavior_(IGNORE_LONG_WORDS),
1005 replace_newline_chars_with_symbols_(true), 999 replace_newline_chars_with_symbols_(true),
1006 subpixel_rendering_suppressed_(false), 1000 subpixel_rendering_suppressed_(false),
1007 clip_to_display_rect_(true), 1001 clip_to_display_rect_(true),
1008 baseline_(kInvalidBaseline), 1002 baseline_(kInvalidBaseline),
1009 cached_bounds_and_offset_valid_(false) {} 1003 cached_bounds_and_offset_valid_(false),
1004 strike_thickness_factor_(kLineThickness) {}
1010 1005
1011 SelectionModel RenderText::GetAdjacentSelectionModel( 1006 SelectionModel RenderText::GetAdjacentSelectionModel(
1012 const SelectionModel& current, 1007 const SelectionModel& current,
1013 BreakType break_type, 1008 BreakType break_type,
1014 VisualCursorDirection direction) { 1009 VisualCursorDirection direction) {
1015 EnsureLayout(); 1010 EnsureLayout();
1016 1011
1017 if (break_type == LINE_BREAK || text().empty()) 1012 if (break_type == LINE_BREAK || text().empty())
1018 return EdgeSelectionModel(direction); 1013 return EdgeSelectionModel(direction);
1019 if (break_type == CHARACTER_BREAK) 1014 if (break_type == CHARACTER_BREAK)
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 1634
1640 for (; range_max < length; ++range_max) 1635 for (; range_max < length; ++range_max)
1641 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max)) 1636 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max))
1642 break; 1637 break;
1643 1638
1644 return range.is_reversed() ? Range(range_max, range_min) 1639 return range.is_reversed() ? Range(range_max, range_min)
1645 : Range(range_min, range_max); 1640 : Range(range_min, range_max);
1646 } 1641 }
1647 1642
1648 } // namespace gfx 1643 } // namespace gfx
OLDNEW
« ui/gfx/render_text.h ('K') | « ui/gfx/render_text.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698