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

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

Issue 152473008: More or less implement RenderTextHarfBuzz (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge 252563003 Created 6 years, 7 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
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 #include <climits> 8 #include <climits>
9 9
10 #include "base/command_line.h"
10 #include "base/i18n/break_iterator.h" 11 #include "base/i18n/break_iterator.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "third_party/icu/source/common/unicode/rbbi.h" 15 #include "third_party/icu/source/common/unicode/rbbi.h"
15 #include "third_party/icu/source/common/unicode/utf16.h" 16 #include "third_party/icu/source/common/unicode/utf16.h"
16 #include "third_party/skia/include/core/SkTypeface.h" 17 #include "third_party/skia/include/core/SkTypeface.h"
17 #include "third_party/skia/include/effects/SkGradientShader.h" 18 #include "third_party/skia/include/effects/SkGradientShader.h"
18 #include "ui/gfx/canvas.h" 19 #include "ui/gfx/canvas.h"
19 #include "ui/gfx/insets.h" 20 #include "ui/gfx/insets.h"
21 #include "ui/gfx/render_text_harfbuzz.h"
22 #include "ui/gfx/scoped_canvas.h"
20 #include "ui/gfx/skia_util.h" 23 #include "ui/gfx/skia_util.h"
24 #include "ui/gfx/switches.h"
21 #include "ui/gfx/text_constants.h" 25 #include "ui/gfx/text_constants.h"
22 #include "ui/gfx/text_elider.h" 26 #include "ui/gfx/text_elider.h"
23 #include "ui/gfx/text_utils.h" 27 #include "ui/gfx/text_utils.h"
24 #include "ui/gfx/utf16_indexing.h" 28 #include "ui/gfx/utf16_indexing.h"
25 29
26 namespace gfx { 30 namespace gfx {
27 31
28 namespace { 32 namespace {
29 33
30 // All chars are replaced by this char when the password style is set. 34 // All chars are replaced by this char when the password style is set.
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } 215 }
212 216
213 void SkiaTextRenderer::SetTextSize(SkScalar size) { 217 void SkiaTextRenderer::SetTextSize(SkScalar size) {
214 paint_.setTextSize(size); 218 paint_.setTextSize(size);
215 } 219 }
216 220
217 void SkiaTextRenderer::SetFontFamilyWithStyle(const std::string& family, 221 void SkiaTextRenderer::SetFontFamilyWithStyle(const std::string& family,
218 int style) { 222 int style) {
219 DCHECK(!family.empty()); 223 DCHECK(!family.empty());
220 224
221 SkTypeface::Style skia_style = ConvertFontStyleToSkiaTypefaceStyle(style); 225 skia::RefPtr<SkTypeface> typeface = CreateSkiaTypeface(family.c_str(), style);
222 skia::RefPtr<SkTypeface> typeface =
223 skia::AdoptRef(SkTypeface::CreateFromName(family.c_str(), skia_style));
224 if (typeface) { 226 if (typeface) {
225 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. 227 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here.
226 SetTypeface(typeface.get()); 228 SetTypeface(typeface.get());
227 229
228 // Enable fake bold text if bold style is needed but new typeface does not 230 // Enable fake bold text if bold style is needed but new typeface does not
229 // have it. 231 // have it.
230 paint_.setFakeBoldText((skia_style & SkTypeface::kBold) && 232 paint_.setFakeBoldText((style & gfx::Font::BOLD) && !typeface->isBold());
231 !typeface->isBold());
232 } 233 }
233 } 234 }
234 235
235 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { 236 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) {
236 paint_.setColor(foreground); 237 paint_.setColor(foreground);
237 } 238 }
238 239
239 void SkiaTextRenderer::SetShader(SkShader* shader, const Rect& bounds) { 240 void SkiaTextRenderer::SetShader(SkShader* shader, const Rect& bounds) {
240 bounds_ = RectToSkRect(bounds); 241 bounds_ = RectToSkRect(bounds);
241 paint_.setShader(shader); 242 paint_.setShader(shader);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 const SkScalar height = SkScalarMul(text_size, kLineThickness); 313 const SkScalar height = SkScalarMul(text_size, kLineThickness);
313 const SkScalar offset = SkScalarMulAdd(text_size, kStrikeThroughOffset, y); 314 const SkScalar offset = SkScalarMulAdd(text_size, kStrikeThroughOffset, y);
314 const SkRect r = SkRect::MakeLTRB(x, offset, x + width, offset + height); 315 const SkRect r = SkRect::MakeLTRB(x, offset, x + width, offset + height);
315 canvas_skia_->drawRect(r, paint_); 316 canvas_skia_->drawRect(r, paint_);
316 } 317 }
317 318
318 SkiaTextRenderer::DiagonalStrike::DiagonalStrike(Canvas* canvas, 319 SkiaTextRenderer::DiagonalStrike::DiagonalStrike(Canvas* canvas,
319 Point start, 320 Point start,
320 const SkPaint& paint) 321 const SkPaint& paint)
321 : canvas_(canvas), 322 : canvas_(canvas),
323 matrix_(canvas->sk_canvas()->getTotalMatrix()),
322 start_(start), 324 start_(start),
323 paint_(paint), 325 paint_(paint),
324 total_length_(0) { 326 total_length_(0) {
325 } 327 }
326 328
327 SkiaTextRenderer::DiagonalStrike::~DiagonalStrike() { 329 SkiaTextRenderer::DiagonalStrike::~DiagonalStrike() {
328 } 330 }
329 331
330 void SkiaTextRenderer::DiagonalStrike::AddPiece(int length, SkColor color) { 332 void SkiaTextRenderer::DiagonalStrike::AddPiece(int length, SkColor color) {
331 pieces_.push_back(Piece(length, color)); 333 pieces_.push_back(Piece(length, color));
332 total_length_ += length; 334 total_length_ += length;
333 } 335 }
334 336
335 void SkiaTextRenderer::DiagonalStrike::Draw() { 337 void SkiaTextRenderer::DiagonalStrike::Draw() {
336 const SkScalar text_size = paint_.getTextSize(); 338 const SkScalar text_size = paint_.getTextSize();
337 const SkScalar offset = SkScalarMul(text_size, kDiagonalStrikeMarginOffset); 339 const SkScalar offset = SkScalarMul(text_size, kDiagonalStrikeMarginOffset);
338 const int thickness = 340 const int thickness =
339 SkScalarCeilToInt(SkScalarMul(text_size, kLineThickness) * 2); 341 SkScalarCeilToInt(SkScalarMul(text_size, kLineThickness) * 2);
340 const int height = SkScalarCeilToInt(text_size - offset); 342 const int height = SkScalarCeilToInt(text_size - offset);
341 const Point end = start_ + Vector2d(total_length_, -height); 343 const Point end = start_ + Vector2d(total_length_, -height);
344 const int clip_height = height + 2 * thickness;
342 345
343 paint_.setAntiAlias(true); 346 paint_.setAntiAlias(true);
344 paint_.setStrokeWidth(thickness); 347 paint_.setStrokeWidth(thickness);
345 348
349 ScopedCanvas scoped_canvas(canvas_);
350
351 SkCanvas* sk_canvas = canvas_->sk_canvas();
352 sk_canvas->setMatrix(matrix_);
353
346 const bool clipped = pieces_.size() > 1; 354 const bool clipped = pieces_.size() > 1;
347 int x = start_.x(); 355 int x = start_.x();
348 for (size_t i = 0; i < pieces_.size(); ++i) { 356 for (size_t i = 0; i < pieces_.size(); ++i) {
349 paint_.setColor(pieces_[i].second); 357 paint_.setColor(pieces_[i].second);
350 358
351 if (clipped) { 359 if (clipped) {
352 canvas_->Save(); 360 sk_canvas->clipRect(RectToSkRect(
Alexei Svitkine (slow) 2014/05/12 15:58:31 The previous code restored at every iteration, whe
ckocagil 2014/05/13 15:03:48 We're not keeping the clip here, the SkRegion::kRe
353 canvas_->ClipRect(Rect(x, 0, pieces_[i].first, start_.y() + thickness)); 361 Rect(x, end.y() - thickness, pieces_[i].first, clip_height)),
362 SkRegion::kReplace_Op);
354 } 363 }
355 364
356 canvas_->DrawLine(start_, end, paint_); 365 canvas_->DrawLine(start_, end, paint_);
357 366
358 if (clipped)
359 canvas_->Restore();
360
361 x += pieces_[i].first; 367 x += pieces_[i].first;
362 } 368 }
363 } 369 }
364 370
365 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, 371 StyleIterator::StyleIterator(const BreakList<SkColor>& colors,
366 const std::vector<BreakList<bool> >& styles) 372 const std::vector<BreakList<bool> >& styles)
367 : colors_(colors), 373 : colors_(colors),
368 styles_(styles) { 374 styles_(styles) {
369 color_ = colors_.breaks().begin(); 375 color_ = colors_.breaks().begin();
370 for (size_t i = 0; i < styles_.size(); ++i) 376 for (size_t i = 0; i < styles_.size(); ++i)
(...skipping 16 matching lines...) Expand all
387 } 393 }
388 394
389 LineSegment::LineSegment() : run(0) {} 395 LineSegment::LineSegment() : run(0) {}
390 396
391 LineSegment::~LineSegment() {} 397 LineSegment::~LineSegment() {}
392 398
393 Line::Line() : preceding_heights(0), baseline(0) {} 399 Line::Line() : preceding_heights(0), baseline(0) {}
394 400
395 Line::~Line() {} 401 Line::~Line() {}
396 402
403 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const std::string& family,
404 int style) {
405 SkTypeface::Style skia_style = ConvertFontStyleToSkiaTypefaceStyle(style);
406 return skia::AdoptRef(SkTypeface::CreateFromName(family.c_str(), skia_style));
407 }
408
397 } // namespace internal 409 } // namespace internal
398 410
399 RenderText::~RenderText() { 411 RenderText::~RenderText() {
400 } 412 }
401 413
414 RenderText* RenderText::CreateInstance() {
415 if (CommandLine::ForCurrentProcess()->HasSwitch(
416 switches::kEnableHarfBuzzRenderText))
Alexei Svitkine (slow) 2014/05/12 15:58:31 Nit: {}'s
ckocagil 2014/05/13 15:03:48 Done.
417 return new RenderTextHarfBuzz;
418 return CreateNativeInstance();
419 }
420
402 void RenderText::SetText(const base::string16& text) { 421 void RenderText::SetText(const base::string16& text) {
403 DCHECK(!composition_range_.IsValid()); 422 DCHECK(!composition_range_.IsValid());
404 if (text_ == text) 423 if (text_ == text)
405 return; 424 return;
406 text_ = text; 425 text_ = text;
407 426
408 // Adjust ranged styles and colors to accommodate a new text length. 427 // Adjust ranged styles and colors to accommodate a new text length.
409 const size_t text_length = text_.length(); 428 const size_t text_length = text_.length();
410 colors_.SetMax(text_length); 429 colors_.SetMax(text_length);
411 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 430 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 cursor_bounds_ += delta_offset; 1329 cursor_bounds_ += delta_offset;
1311 } 1330 }
1312 1331
1313 void RenderText::DrawSelection(Canvas* canvas) { 1332 void RenderText::DrawSelection(Canvas* canvas) {
1314 const std::vector<Rect> sel = GetSubstringBounds(selection()); 1333 const std::vector<Rect> sel = GetSubstringBounds(selection());
1315 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) 1334 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i)
1316 canvas->FillRect(*i, selection_background_focused_color_); 1335 canvas->FillRect(*i, selection_background_focused_color_);
1317 } 1336 }
1318 1337
1319 } // namespace gfx 1338 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698