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

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: rebased; decorations Created 6 years, 8 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/i18n/break_iterator.h" 10 #include "base/i18n/break_iterator.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "third_party/icu/source/common/unicode/rbbi.h" 14 #include "third_party/icu/source/common/unicode/rbbi.h"
15 #include "third_party/icu/source/common/unicode/utf16.h" 15 #include "third_party/icu/source/common/unicode/utf16.h"
16 #include "third_party/skia/include/core/SkTypeface.h" 16 #include "third_party/skia/include/core/SkTypeface.h"
17 #include "third_party/skia/include/effects/SkGradientShader.h" 17 #include "third_party/skia/include/effects/SkGradientShader.h"
18 #include "ui/gfx/canvas.h" 18 #include "ui/gfx/canvas.h"
19 #include "ui/gfx/insets.h" 19 #include "ui/gfx/insets.h"
20 #include "ui/gfx/render_text_harfbuzz.h"
21 #include "ui/gfx/scoped_canvas.h"
20 #include "ui/gfx/skia_util.h" 22 #include "ui/gfx/skia_util.h"
21 #include "ui/gfx/text_constants.h" 23 #include "ui/gfx/text_constants.h"
22 #include "ui/gfx/text_elider.h" 24 #include "ui/gfx/text_elider.h"
23 #include "ui/gfx/text_utils.h" 25 #include "ui/gfx/text_utils.h"
24 #include "ui/gfx/utf16_indexing.h" 26 #include "ui/gfx/utf16_indexing.h"
25 27
26 namespace gfx { 28 namespace gfx {
27 29
28 namespace { 30 namespace {
29 31
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } 213 }
212 214
213 void SkiaTextRenderer::SetTextSize(SkScalar size) { 215 void SkiaTextRenderer::SetTextSize(SkScalar size) {
214 paint_.setTextSize(size); 216 paint_.setTextSize(size);
215 } 217 }
216 218
217 void SkiaTextRenderer::SetFontFamilyWithStyle(const std::string& family, 219 void SkiaTextRenderer::SetFontFamilyWithStyle(const std::string& family,
218 int style) { 220 int style) {
219 DCHECK(!family.empty()); 221 DCHECK(!family.empty());
220 222
221 SkTypeface::Style skia_style = ConvertFontStyleToSkiaTypefaceStyle(style); 223 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) { 224 if (typeface) {
225 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. 225 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here.
226 SetTypeface(typeface.get()); 226 SetTypeface(typeface.get());
227 227
228 // Enable fake bold text if bold style is needed but new typeface does not 228 // Enable fake bold text if bold style is needed but new typeface does not
229 // have it. 229 // have it.
230 paint_.setFakeBoldText((skia_style & SkTypeface::kBold) && 230 paint_.setFakeBoldText((style & gfx::Font::BOLD) && !typeface->isBold());
231 !typeface->isBold());
232 } 231 }
233 } 232 }
234 233
235 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { 234 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) {
236 paint_.setColor(foreground); 235 paint_.setColor(foreground);
237 } 236 }
238 237
239 void SkiaTextRenderer::SetShader(SkShader* shader, const Rect& bounds) { 238 void SkiaTextRenderer::SetShader(SkShader* shader, const Rect& bounds) {
240 bounds_ = RectToSkRect(bounds); 239 bounds_ = RectToSkRect(bounds);
241 paint_.setShader(shader); 240 paint_.setShader(shader);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 const SkScalar height = SkScalarMul(text_size, kLineThickness); 311 const SkScalar height = SkScalarMul(text_size, kLineThickness);
313 const SkScalar offset = SkScalarMulAdd(text_size, kStrikeThroughOffset, y); 312 const SkScalar offset = SkScalarMulAdd(text_size, kStrikeThroughOffset, y);
314 const SkRect r = SkRect::MakeLTRB(x, offset, x + width, offset + height); 313 const SkRect r = SkRect::MakeLTRB(x, offset, x + width, offset + height);
315 canvas_skia_->drawRect(r, paint_); 314 canvas_skia_->drawRect(r, paint_);
316 } 315 }
317 316
318 SkiaTextRenderer::DiagonalStrike::DiagonalStrike(Canvas* canvas, 317 SkiaTextRenderer::DiagonalStrike::DiagonalStrike(Canvas* canvas,
319 Point start, 318 Point start,
320 const SkPaint& paint) 319 const SkPaint& paint)
321 : canvas_(canvas), 320 : canvas_(canvas),
321 matrix_(canvas->sk_canvas()->getTotalMatrix()),
msw 2014/04/29 06:24:45 nit: can this just be calculated in DiagonalStrike
ckocagil 2014/05/01 22:02:01 No, because for each text run we do a matrix trans
msw 2014/05/02 05:08:21 This wasn't previously necessary, is it related to
ckocagil 2014/05/06 03:38:40 Actually these changes are intended. When we want
msw 2014/05/09 22:55:18 Ah, so we could apply canvas translations in Rende
ckocagil 2014/05/12 09:53:29 It doesn't simplify SkiaTextRenderer. Sure, I will
322 start_(start), 322 start_(start),
323 paint_(paint), 323 paint_(paint),
324 total_length_(0) { 324 total_length_(0) {
325 } 325 }
326 326
327 SkiaTextRenderer::DiagonalStrike::~DiagonalStrike() { 327 SkiaTextRenderer::DiagonalStrike::~DiagonalStrike() {
328 } 328 }
329 329
330 void SkiaTextRenderer::DiagonalStrike::AddPiece(int length, SkColor color) { 330 void SkiaTextRenderer::DiagonalStrike::AddPiece(int length, SkColor color) {
331 pieces_.push_back(Piece(length, color)); 331 pieces_.push_back(Piece(length, color));
332 total_length_ += length; 332 total_length_ += length;
333 } 333 }
334 334
335 void SkiaTextRenderer::DiagonalStrike::Draw() { 335 void SkiaTextRenderer::DiagonalStrike::Draw() {
336 const SkScalar text_size = paint_.getTextSize(); 336 const SkScalar text_size = paint_.getTextSize();
337 const SkScalar offset = SkScalarMul(text_size, kDiagonalStrikeMarginOffset); 337 const SkScalar offset = SkScalarMul(text_size, kDiagonalStrikeMarginOffset);
338 const int thickness = 338 const int thickness =
339 SkScalarCeilToInt(SkScalarMul(text_size, kLineThickness) * 2); 339 SkScalarCeilToInt(SkScalarMul(text_size, kLineThickness) * 2);
340 const int height = SkScalarCeilToInt(text_size - offset); 340 const int height = SkScalarCeilToInt(text_size - offset);
341 const Point end = start_ + Vector2d(total_length_, -height); 341 const Point end = start_ + Vector2d(total_length_, -height);
342 const int clip_height = height + 2 * thickness;
342 343
343 paint_.setAntiAlias(true); 344 paint_.setAntiAlias(true);
344 paint_.setStrokeWidth(thickness); 345 paint_.setStrokeWidth(thickness);
345 346
347 ScopedCanvas scoped_canvas(canvas_);
msw 2014/04/29 06:24:45 Why this is needed over doing Canvas::Save/Restore
ckocagil 2014/05/01 22:02:01 This is just another way of doing Save/Restore, no
msw 2014/05/02 05:08:21 Reducing the amount of churn in this change is hig
ckocagil 2014/05/06 03:38:40 Done, this is now a Save/Restore pair.
msw 2014/05/09 22:55:18 It doesn't look like you updated the latest patch
348
349 SkCanvas* sk_canvas = canvas_->sk_canvas();
350 sk_canvas->setMatrix(matrix_);
351
346 const bool clipped = pieces_.size() > 1; 352 const bool clipped = pieces_.size() > 1;
347 int x = start_.x(); 353 int x = start_.x();
348 for (size_t i = 0; i < pieces_.size(); ++i) { 354 for (size_t i = 0; i < pieces_.size(); ++i) {
349 paint_.setColor(pieces_[i].second); 355 paint_.setColor(pieces_[i].second);
350 356
351 if (clipped) { 357 if (clipped) {
352 canvas_->Save(); 358 sk_canvas->clipRect(RectToSkRect(
353 canvas_->ClipRect(Rect(x, 0, pieces_[i].first, start_.y() + thickness)); 359 Rect(x, end.y() - thickness, pieces_[i].first, clip_height)),
msw 2014/05/09 22:55:18 I think you'll need to still respect start_.y() fo
ckocagil 2014/05/12 09:53:29 We're already respecting that value by using end.y
360 SkRegion::kReplace_Op);
354 } 361 }
355 362
356 canvas_->DrawLine(start_, end, paint_); 363 canvas_->DrawLine(start_, end, paint_);
357 364
358 if (clipped)
359 canvas_->Restore();
360
361 x += pieces_[i].first; 365 x += pieces_[i].first;
362 } 366 }
363 } 367 }
364 368
365 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, 369 StyleIterator::StyleIterator(const BreakList<SkColor>& colors,
366 const std::vector<BreakList<bool> >& styles) 370 const std::vector<BreakList<bool> >& styles)
367 : colors_(colors), 371 : colors_(colors),
368 styles_(styles) { 372 styles_(styles) {
369 color_ = colors_.breaks().begin(); 373 color_ = colors_.breaks().begin();
370 for (size_t i = 0; i < styles_.size(); ++i) 374 for (size_t i = 0; i < styles_.size(); ++i)
(...skipping 16 matching lines...) Expand all
387 } 391 }
388 392
389 LineSegment::LineSegment() : run(0) {} 393 LineSegment::LineSegment() : run(0) {}
390 394
391 LineSegment::~LineSegment() {} 395 LineSegment::~LineSegment() {}
392 396
393 Line::Line() : preceding_heights(0), baseline(0) {} 397 Line::Line() : preceding_heights(0), baseline(0) {}
394 398
395 Line::~Line() {} 399 Line::~Line() {}
396 400
401 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const std::string& family,
402 int style) {
403 SkTypeface::Style skia_style = ConvertFontStyleToSkiaTypefaceStyle(style);
404 return skia::AdoptRef(SkTypeface::CreateFromName(family.c_str(), skia_style));
405 }
406
397 } // namespace internal 407 } // namespace internal
398 408
399 RenderText::~RenderText() { 409 RenderText::~RenderText() {
400 } 410 }
401 411
412 RenderText* RenderText::CreateInstance() {
413 if (CommandLine::ForCurrentProcess()->HasSwitch("use-harfbuzz-rendertext"))
msw 2014/04/29 06:24:45 Make "use-harfbuzz-rendertext" a proper ui/gfx/swi
ckocagil 2014/05/01 22:02:01 Done. I added the strings to chrome/app/generated_
msw 2014/05/02 05:08:21 Good, the file I suggested for strings was wrong,
414 return new RenderTextHarfBuzz;
415 return CreateNativeInstance();
416 }
417
402 void RenderText::SetText(const base::string16& text) { 418 void RenderText::SetText(const base::string16& text) {
403 DCHECK(!composition_range_.IsValid()); 419 DCHECK(!composition_range_.IsValid());
404 if (text_ == text) 420 if (text_ == text)
405 return; 421 return;
406 text_ = text; 422 text_ = text;
407 423
408 // Adjust ranged styles and colors to accommodate a new text length. 424 // Adjust ranged styles and colors to accommodate a new text length.
409 const size_t text_length = text_.length(); 425 const size_t text_length = text_.length();
410 colors_.SetMax(text_length); 426 colors_.SetMax(text_length);
411 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 427 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 cursor_bounds_ += delta_offset; 1317 cursor_bounds_ += delta_offset;
1302 } 1318 }
1303 1319
1304 void RenderText::DrawSelection(Canvas* canvas) { 1320 void RenderText::DrawSelection(Canvas* canvas) {
1305 const std::vector<Rect> sel = GetSubstringBounds(selection()); 1321 const std::vector<Rect> sel = GetSubstringBounds(selection());
1306 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) 1322 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i)
1307 canvas->FillRect(*i, selection_background_focused_color_); 1323 canvas->FillRect(*i, selection_background_focused_color_);
1308 } 1324 }
1309 1325
1310 } // namespace gfx 1326 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698