| 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/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 Loading... |
| 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 Loading... |
| 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( |
| 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 Loading... |
| 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)) { |
| 417 return new RenderTextHarfBuzz; |
| 418 } |
| 419 return CreateNativeInstance(); |
| 420 } |
| 421 |
| 402 void RenderText::SetText(const base::string16& text) { | 422 void RenderText::SetText(const base::string16& text) { |
| 403 DCHECK(!composition_range_.IsValid()); | 423 DCHECK(!composition_range_.IsValid()); |
| 404 if (text_ == text) | 424 if (text_ == text) |
| 405 return; | 425 return; |
| 406 text_ = text; | 426 text_ = text; |
| 407 | 427 |
| 408 // Adjust ranged styles and colors to accommodate a new text length. | 428 // Adjust ranged styles and colors to accommodate a new text length. |
| 409 const size_t text_length = text_.length(); | 429 const size_t text_length = text_.length(); |
| 410 colors_.SetMax(text_length); | 430 colors_.SetMax(text_length); |
| 411 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 431 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| (...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 cursor_bounds_ += delta_offset; | 1330 cursor_bounds_ += delta_offset; |
| 1311 } | 1331 } |
| 1312 | 1332 |
| 1313 void RenderText::DrawSelection(Canvas* canvas) { | 1333 void RenderText::DrawSelection(Canvas* canvas) { |
| 1314 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1334 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
| 1315 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1335 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
| 1316 canvas->FillRect(*i, selection_background_focused_color_); | 1336 canvas->FillRect(*i, selection_background_focused_color_); |
| 1317 } | 1337 } |
| 1318 | 1338 |
| 1319 } // namespace gfx | 1339 } // namespace gfx |
| OLD | NEW |