| 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_mac.h" | 5 #include "ui/gfx/render_text_mac.h" |
| 6 | 6 |
| 7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
| 8 #include <ApplicationServices/ApplicationServices.h> | 8 #include <ApplicationServices/ApplicationServices.h> |
| 9 #include <CoreText/CoreText.h> | 9 #include <CoreText/CoreText.h> |
| 10 | 10 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 111 |
| 112 std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() { | 112 std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() { |
| 113 EnsureLayout(); | 113 EnsureLayout(); |
| 114 if (!runs_valid_) | 114 if (!runs_valid_) |
| 115 ComputeRuns(); | 115 ComputeRuns(); |
| 116 | 116 |
| 117 std::vector<RenderText::FontSpan> spans; | 117 std::vector<RenderText::FontSpan> spans; |
| 118 for (size_t i = 0; i < runs_.size(); ++i) { | 118 for (size_t i = 0; i < runs_.size(); ++i) { |
| 119 const CFRange cf_range = CTRunGetStringRange(runs_[i].ct_run); | 119 const CFRange cf_range = CTRunGetStringRange(runs_[i].ct_run); |
| 120 const Range range(cf_range.location, cf_range.location + cf_range.length); | 120 const Range range(cf_range.location, cf_range.location + cf_range.length); |
| 121 spans.push_back(RenderText::FontSpan(runs_[i].font, range)); | 121 spans.push_back(RenderText::FontSpan( |
| 122 gfx::Font(base::mac::CFToNSCast(runs_[i].ct_font.get())), range)); |
| 122 } | 123 } |
| 123 | 124 |
| 124 return spans; | 125 return spans; |
| 125 } | 126 } |
| 126 | 127 |
| 127 int RenderTextMac::GetDisplayTextBaseline() { | 128 int RenderTextMac::GetDisplayTextBaseline() { |
| 128 EnsureLayout(); | 129 EnsureLayout(); |
| 129 return common_baseline_; | 130 return common_baseline_; |
| 130 } | 131 } |
| 131 | 132 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 DCHECK(line_); | 204 DCHECK(line_); |
| 204 if (!runs_valid_) | 205 if (!runs_valid_) |
| 205 ComputeRuns(); | 206 ComputeRuns(); |
| 206 | 207 |
| 207 ApplyFadeEffects(renderer); | 208 ApplyFadeEffects(renderer); |
| 208 ApplyTextShadows(renderer); | 209 ApplyTextShadows(renderer); |
| 209 | 210 |
| 210 for (size_t i = 0; i < runs_.size(); ++i) { | 211 for (size_t i = 0; i < runs_.size(); ++i) { |
| 211 const TextRun& run = runs_[i]; | 212 const TextRun& run = runs_[i]; |
| 212 renderer->SetForegroundColor(run.foreground); | 213 renderer->SetForegroundColor(run.foreground); |
| 213 | 214 renderer->SetTextSize(CTFontGetSize(run.ct_font)); |
| 214 CTFontRef ct_font = static_cast<CTFontRef>(run.font.GetNativeFont()); | |
| 215 renderer->SetTextSize(CTFontGetSize(ct_font)); | |
| 216 | 215 |
| 217 // The painter adds its own ref. So don't |release()| it from the ref ptr in | 216 // The painter adds its own ref. So don't |release()| it from the ref ptr in |
| 218 // TextRun. | 217 // TextRun. |
| 219 renderer->SetTypeface(run.typeface.get()); | 218 renderer->SetTypeface(run.typeface.get()); |
| 220 | 219 |
| 221 renderer->DrawPosText(&run.glyph_positions[0], &run.glyphs[0], | 220 renderer->DrawPosText(&run.glyph_positions[0], &run.glyphs[0], |
| 222 run.glyphs.size()); | 221 run.glyphs.size()); |
| 223 renderer->DrawDecorations(run.origin.x(), run.origin.y(), run.width, | 222 renderer->DrawDecorations(run.origin.x(), run.origin.y(), run.width, |
| 224 run.underline, run.strike, run.diagonal_strike); | 223 run.underline, run.strike, run.diagonal_strike); |
| 225 } | 224 } |
| 226 | 225 |
| 227 renderer->EndDiagonalStrike(); | 226 renderer->EndDiagonalStrike(); |
| 228 } | 227 } |
| 229 | 228 |
| 230 RenderTextMac::TextRun::TextRun() | 229 RenderTextMac::TextRun::TextRun() |
| 231 : ct_run(NULL), | 230 : ct_run(NULL), |
| 232 origin(SkPoint::Make(0, 0)), | 231 origin(SkPoint::Make(0, 0)), |
| 233 width(0), | 232 width(0), |
| 234 foreground(SK_ColorBLACK), | 233 foreground(SK_ColorBLACK), |
| 235 underline(false), | 234 underline(false), |
| 236 strike(false), | 235 strike(false), |
| 237 diagonal_strike(false) {} | 236 diagonal_strike(false) {} |
| 238 | 237 |
| 239 RenderTextMac::TextRun::TextRun(const TextRun& other) = default; | 238 RenderTextMac::TextRun::TextRun(TextRun&& other) = default; |
| 240 | 239 |
| 241 RenderTextMac::TextRun::~TextRun() {} | 240 RenderTextMac::TextRun::~TextRun() {} |
| 242 | 241 |
| 243 float RenderTextMac::GetLayoutTextWidth() { | 242 float RenderTextMac::GetLayoutTextWidth() { |
| 244 base::ScopedCFTypeRef<CFMutableArrayRef> attributes_owner; | 243 base::ScopedCFTypeRef<CFMutableArrayRef> attributes_owner; |
| 245 base::ScopedCFTypeRef<CTLineRef> line( | 244 base::ScopedCFTypeRef<CTLineRef> line( |
| 246 EnsureLayoutInternal(layout_text(), &attributes_owner)); | 245 EnsureLayoutInternal(layout_text(), &attributes_owner)); |
| 247 SkScalar baseline; | 246 SkScalar baseline; |
| 248 return GetCTLineSize(line.get(), &baseline).width(); | 247 return GetCTLineSize(line.get(), &baseline).width(); |
| 249 } | 248 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 CTRunRef ct_run = | 371 CTRunRef ct_run = |
| 373 base::mac::CFCast<CTRunRef>(CFArrayGetValueAtIndex(ct_runs, i)); | 372 base::mac::CFCast<CTRunRef>(CFArrayGetValueAtIndex(ct_runs, i)); |
| 374 const size_t glyph_count = CTRunGetGlyphCount(ct_run); | 373 const size_t glyph_count = CTRunGetGlyphCount(ct_run); |
| 375 const double run_width = | 374 const double run_width = |
| 376 CTRunGetTypographicBounds(ct_run, empty_cf_range, NULL, NULL, NULL); | 375 CTRunGetTypographicBounds(ct_run, empty_cf_range, NULL, NULL, NULL); |
| 377 if (glyph_count == 0) { | 376 if (glyph_count == 0) { |
| 378 run_origin.offset(run_width, 0); | 377 run_origin.offset(run_width, 0); |
| 379 continue; | 378 continue; |
| 380 } | 379 } |
| 381 | 380 |
| 382 runs_.push_back(TextRun()); | 381 runs_.emplace_back(); |
| 383 TextRun* run = &runs_.back(); | 382 TextRun* run = &runs_.back(); |
| 384 run->ct_run = ct_run; | 383 run->ct_run = ct_run; |
| 385 run->origin = run_origin; | 384 run->origin = run_origin; |
| 386 run->width = run_width; | 385 run->width = run_width; |
| 387 run->glyphs.resize(glyph_count); | 386 run->glyphs.resize(glyph_count); |
| 388 CTRunGetGlyphs(ct_run, empty_cf_range, &run->glyphs[0]); | 387 CTRunGetGlyphs(ct_run, empty_cf_range, &run->glyphs[0]); |
| 389 // CTRunGetGlyphs() sometimes returns glyphs with value 65535 and zero | 388 // CTRunGetGlyphs() sometimes returns glyphs with value 65535 and zero |
| 390 // width (this has been observed at the beginning of a string containing | 389 // width (this has been observed at the beginning of a string containing |
| 391 // Arabic content). Passing these to Skia will trigger an assertion; | 390 // Arabic content). Passing these to Skia will trigger an assertion; |
| 392 // instead set their values to 0. | 391 // instead set their values to 0. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 407 SkPoint* point = &run->glyph_positions[glyph]; | 406 SkPoint* point = &run->glyph_positions[glyph]; |
| 408 point->set(x + SkDoubleToScalar(positions_ptr[glyph].x), | 407 point->set(x + SkDoubleToScalar(positions_ptr[glyph].x), |
| 409 y + SkDoubleToScalar(positions_ptr[glyph].y)); | 408 y + SkDoubleToScalar(positions_ptr[glyph].y)); |
| 410 } | 409 } |
| 411 | 410 |
| 412 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle | 411 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle |
| 413 // this better. Also, support strike and diagonal_strike. | 412 // this better. Also, support strike and diagonal_strike. |
| 414 CFDictionaryRef attributes = CTRunGetAttributes(ct_run); | 413 CFDictionaryRef attributes = CTRunGetAttributes(ct_run); |
| 415 CTFontRef ct_font = base::mac::GetValueFromDictionary<CTFontRef>( | 414 CTFontRef ct_font = base::mac::GetValueFromDictionary<CTFontRef>( |
| 416 attributes, kCTFontAttributeName); | 415 attributes, kCTFontAttributeName); |
| 417 run->font = Font(static_cast<NSFont*>(ct_font)); | 416 run->ct_font.reset(ct_font, base::scoped_policy::RETAIN); |
| 418 run->typeface.reset(SkCreateTypefaceFromCTFont(ct_font)); | 417 run->typeface.reset(SkCreateTypefaceFromCTFont(ct_font)); |
| 419 | 418 |
| 420 const CGColorRef foreground = base::mac::GetValueFromDictionary<CGColorRef>( | 419 const CGColorRef foreground = base::mac::GetValueFromDictionary<CGColorRef>( |
| 421 attributes, kCTForegroundColorAttributeName); | 420 attributes, kCTForegroundColorAttributeName); |
| 422 if (foreground) | 421 if (foreground) |
| 423 run->foreground = skia::CGColorRefToSkColor(foreground); | 422 run->foreground = skia::CGColorRefToSkColor(foreground); |
| 424 | 423 |
| 425 const CFNumberRef underline = | 424 const CFNumberRef underline = |
| 426 base::mac::GetValueFromDictionary<CFNumberRef>( | 425 base::mac::GetValueFromDictionary<CFNumberRef>( |
| 427 attributes, kCTUnderlineStyleAttributeName); | 426 attributes, kCTUnderlineStyleAttributeName); |
| 428 CTUnderlineStyle value = kCTUnderlineStyleNone; | 427 CTUnderlineStyle value = kCTUnderlineStyleNone; |
| 429 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value)) | 428 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value)) |
| 430 run->underline = (value == kCTUnderlineStyleSingle); | 429 run->underline = (value == kCTUnderlineStyleSingle); |
| 431 | 430 |
| 432 run_origin.offset(run_width, 0); | 431 run_origin.offset(run_width, 0); |
| 433 } | 432 } |
| 434 runs_valid_ = true; | 433 runs_valid_ = true; |
| 435 } | 434 } |
| 436 | 435 |
| 437 void RenderTextMac::InvalidateStyle() { | 436 void RenderTextMac::InvalidateStyle() { |
| 438 line_.reset(); | 437 line_.reset(); |
| 439 attributes_.reset(); | 438 attributes_.reset(); |
| 440 runs_.clear(); | 439 runs_.clear(); |
| 441 runs_valid_ = false; | 440 runs_valid_ = false; |
| 442 } | 441 } |
| 443 | 442 |
| 444 } // namespace gfx | 443 } // namespace gfx |
| OLD | NEW |