| Index: ui/gfx/render_text_mac.cc
|
| diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc
|
| deleted file mode 100644
|
| index 68780f84b946a290bdac20c3d827052f47325c9e..0000000000000000000000000000000000000000
|
| --- a/ui/gfx/render_text_mac.cc
|
| +++ /dev/null
|
| @@ -1,346 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "ui/gfx/render_text_mac.h"
|
| -
|
| -#include <ApplicationServices/ApplicationServices.h>
|
| -
|
| -#include <algorithm>
|
| -#include <cmath>
|
| -#include <utility>
|
| -
|
| -#include "base/mac/foundation_util.h"
|
| -#include "base/mac/scoped_cftyperef.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "skia/ext/skia_utils_mac.h"
|
| -
|
| -namespace gfx {
|
| -
|
| -RenderTextMac::RenderTextMac() : common_baseline_(0), runs_valid_(false) {
|
| -}
|
| -
|
| -RenderTextMac::~RenderTextMac() {
|
| -}
|
| -
|
| -Size RenderTextMac::GetStringSize() {
|
| - EnsureLayout();
|
| - return Size(std::ceil(string_size_.width()), string_size_.height());
|
| -}
|
| -
|
| -SizeF RenderTextMac::GetStringSizeF() {
|
| - EnsureLayout();
|
| - return string_size_;
|
| -}
|
| -
|
| -SelectionModel RenderTextMac::FindCursorPosition(const Point& point) {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return SelectionModel();
|
| -}
|
| -
|
| -std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() {
|
| - EnsureLayout();
|
| - if (!runs_valid_)
|
| - ComputeRuns();
|
| -
|
| - std::vector<RenderText::FontSpan> spans;
|
| - for (size_t i = 0; i < runs_.size(); ++i) {
|
| - Font font(runs_[i].font_name, runs_[i].text_size);
|
| - const CFRange cf_range = CTRunGetStringRange(runs_[i].ct_run);
|
| - const Range range(cf_range.location, cf_range.location + cf_range.length);
|
| - spans.push_back(RenderText::FontSpan(font, range));
|
| - }
|
| -
|
| - return spans;
|
| -}
|
| -
|
| -int RenderTextMac::GetLayoutTextBaseline() {
|
| - EnsureLayout();
|
| - return common_baseline_;
|
| -}
|
| -
|
| -SelectionModel RenderTextMac::AdjacentCharSelectionModel(
|
| - const SelectionModel& selection,
|
| - VisualCursorDirection direction) {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return SelectionModel();
|
| -}
|
| -
|
| -SelectionModel RenderTextMac::AdjacentWordSelectionModel(
|
| - const SelectionModel& selection,
|
| - VisualCursorDirection direction) {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return SelectionModel();
|
| -}
|
| -
|
| -Range RenderTextMac::GetGlyphBounds(size_t index) {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return Range();
|
| -}
|
| -
|
| -std::vector<Rect> RenderTextMac::GetSubstringBounds(const Range& range) {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return std::vector<Rect>();
|
| -}
|
| -
|
| -size_t RenderTextMac::TextIndexToLayoutIndex(size_t index) const {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return index;
|
| -}
|
| -
|
| -size_t RenderTextMac::LayoutIndexToTextIndex(size_t index) const {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return index;
|
| -}
|
| -
|
| -bool RenderTextMac::IsValidCursorIndex(size_t index) {
|
| - // TODO(asvitkine): Implement this. http://crbug.com/131618
|
| - return IsValidLogicalIndex(index);
|
| -}
|
| -
|
| -void RenderTextMac::ResetLayout() {
|
| - line_.reset();
|
| - attributes_.reset();
|
| - runs_.clear();
|
| - runs_valid_ = false;
|
| -}
|
| -
|
| -void RenderTextMac::EnsureLayout() {
|
| - if (line_.get())
|
| - return;
|
| - runs_.clear();
|
| - runs_valid_ = false;
|
| -
|
| - CTFontRef ct_font = base::mac::NSToCFCast(
|
| - font_list().GetPrimaryFont().GetNativeFont());
|
| -
|
| - const void* keys[] = { kCTFontAttributeName };
|
| - const void* values[] = { ct_font };
|
| - base::ScopedCFTypeRef<CFDictionaryRef> attributes(
|
| - CFDictionaryCreate(NULL,
|
| - keys,
|
| - values,
|
| - arraysize(keys),
|
| - NULL,
|
| - &kCFTypeDictionaryValueCallBacks));
|
| -
|
| - base::ScopedCFTypeRef<CFStringRef> cf_text(
|
| - base::SysUTF16ToCFStringRef(text()));
|
| - base::ScopedCFTypeRef<CFAttributedStringRef> attr_text(
|
| - CFAttributedStringCreate(NULL, cf_text, attributes));
|
| - base::ScopedCFTypeRef<CFMutableAttributedStringRef> attr_text_mutable(
|
| - CFAttributedStringCreateMutableCopy(NULL, 0, attr_text));
|
| -
|
| - // TODO(asvitkine|msw): Respect GetTextDirection(), which may not match the
|
| - // natural text direction. See kCTTypesetterOptionForcedEmbeddingLevel, etc.
|
| -
|
| - ApplyStyles(attr_text_mutable, ct_font);
|
| - line_.reset(CTLineCreateWithAttributedString(attr_text_mutable));
|
| -
|
| - CGFloat ascent = 0;
|
| - CGFloat descent = 0;
|
| - CGFloat leading = 0;
|
| - // TODO(asvitkine): Consider using CTLineGetBoundsWithOptions() on 10.8+.
|
| - double width = CTLineGetTypographicBounds(line_, &ascent, &descent, &leading);
|
| - // Ensure ascent and descent are not smaller than ones of the font list.
|
| - // Keep them tall enough to draw often-used characters.
|
| - // For example, if a text field contains a Japanese character, which is
|
| - // smaller than Latin ones, and then later a Latin one is inserted, this
|
| - // ensures that the text baseline does not shift.
|
| - CGFloat font_list_height = font_list().GetHeight();
|
| - CGFloat font_list_baseline = font_list().GetBaseline();
|
| - ascent = std::max(ascent, font_list_baseline);
|
| - descent = std::max(descent, font_list_height - font_list_baseline);
|
| - string_size_ = SizeF(width, ascent + descent + leading);
|
| - common_baseline_ = ascent;
|
| -}
|
| -
|
| -void RenderTextMac::DrawVisualText(Canvas* canvas) {
|
| - DCHECK(line_);
|
| - if (!runs_valid_)
|
| - ComputeRuns();
|
| -
|
| - internal::SkiaTextRenderer renderer(canvas);
|
| - ApplyFadeEffects(&renderer);
|
| - ApplyTextShadows(&renderer);
|
| -
|
| - for (size_t i = 0; i < runs_.size(); ++i) {
|
| - const TextRun& run = runs_[i];
|
| - renderer.SetForegroundColor(run.foreground);
|
| - renderer.SetTextSize(run.text_size);
|
| - renderer.SetFontFamilyWithStyle(run.font_name, run.font_style);
|
| - renderer.DrawPosText(&run.glyph_positions[0], &run.glyphs[0],
|
| - run.glyphs.size());
|
| - renderer.DrawDecorations(run.origin.x(), run.origin.y(), run.width,
|
| - run.underline, run.strike, run.diagonal_strike);
|
| - }
|
| -
|
| - renderer.EndDiagonalStrike();
|
| -}
|
| -
|
| -RenderTextMac::TextRun::TextRun()
|
| - : ct_run(NULL),
|
| - origin(SkPoint::Make(0, 0)),
|
| - width(0),
|
| - font_style(Font::NORMAL),
|
| - text_size(0),
|
| - foreground(SK_ColorBLACK),
|
| - underline(false),
|
| - strike(false),
|
| - diagonal_strike(false) {
|
| -}
|
| -
|
| -RenderTextMac::TextRun::~TextRun() {
|
| -}
|
| -
|
| -void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
|
| - CTFontRef font) {
|
| - // Temporarily apply composition underlines and selection colors.
|
| - ApplyCompositionAndSelectionStyles();
|
| -
|
| - // Note: CFAttributedStringSetAttribute() does not appear to retain the values
|
| - // passed in, as can be verified via CFGetRetainCount(). To ensure the
|
| - // attribute objects do not leak, they are saved to |attributes_|.
|
| - // Clear the attributes storage.
|
| - attributes_.reset(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
|
| -
|
| - // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html
|
| - internal::StyleIterator style(colors(), styles());
|
| - const size_t layout_text_length = GetLayoutText().length();
|
| - for (size_t i = 0, end = 0; i < layout_text_length; i = end) {
|
| - end = TextIndexToLayoutIndex(style.GetRange().end());
|
| - const CFRange range = CFRangeMake(i, end - i);
|
| - base::ScopedCFTypeRef<CGColorRef> foreground(
|
| - CGColorCreateFromSkColor(style.color()));
|
| - CFAttributedStringSetAttribute(attr_string, range,
|
| - kCTForegroundColorAttributeName, foreground);
|
| - CFArrayAppendValue(attributes_, foreground);
|
| -
|
| - if (style.style(UNDERLINE)) {
|
| - CTUnderlineStyle value = kCTUnderlineStyleSingle;
|
| - base::ScopedCFTypeRef<CFNumberRef> underline_value(
|
| - CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
|
| - CFAttributedStringSetAttribute(attr_string, range,
|
| - kCTUnderlineStyleAttributeName,
|
| - underline_value);
|
| - CFArrayAppendValue(attributes_, underline_value);
|
| - }
|
| -
|
| - const int traits = (style.style(BOLD) ? kCTFontBoldTrait : 0) |
|
| - (style.style(ITALIC) ? kCTFontItalicTrait : 0);
|
| - if (traits != 0) {
|
| - base::ScopedCFTypeRef<CTFontRef> styled_font(
|
| - CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits));
|
| - // TODO(asvitkine): Handle |styled_font| == NULL case better.
|
| - if (styled_font) {
|
| - CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName,
|
| - styled_font);
|
| - CFArrayAppendValue(attributes_, styled_font);
|
| - }
|
| - }
|
| -
|
| - style.UpdatePosition(LayoutIndexToTextIndex(end));
|
| - }
|
| -
|
| - // Undo the temporarily applied composition underlines and selection colors.
|
| - UndoCompositionAndSelectionStyles();
|
| -}
|
| -
|
| -void RenderTextMac::ComputeRuns() {
|
| - DCHECK(line_);
|
| -
|
| - CFArrayRef ct_runs = CTLineGetGlyphRuns(line_);
|
| - const CFIndex ct_runs_count = CFArrayGetCount(ct_runs);
|
| -
|
| - // TODO(asvitkine): Don't use GetLineOffset() until draw time, since it may be
|
| - // updated based on alignment changes without resetting the layout.
|
| - Vector2d text_offset = GetLineOffset(0);
|
| - // Skia will draw glyphs with respect to the baseline.
|
| - text_offset += Vector2d(0, common_baseline_);
|
| -
|
| - const SkScalar x = SkIntToScalar(text_offset.x());
|
| - const SkScalar y = SkIntToScalar(text_offset.y());
|
| - SkPoint run_origin = SkPoint::Make(x, y);
|
| -
|
| - const CFRange empty_cf_range = CFRangeMake(0, 0);
|
| - for (CFIndex i = 0; i < ct_runs_count; ++i) {
|
| - CTRunRef ct_run =
|
| - base::mac::CFCast<CTRunRef>(CFArrayGetValueAtIndex(ct_runs, i));
|
| - const size_t glyph_count = CTRunGetGlyphCount(ct_run);
|
| - const double run_width =
|
| - CTRunGetTypographicBounds(ct_run, empty_cf_range, NULL, NULL, NULL);
|
| - if (glyph_count == 0) {
|
| - run_origin.offset(run_width, 0);
|
| - continue;
|
| - }
|
| -
|
| - runs_.push_back(TextRun());
|
| - TextRun* run = &runs_.back();
|
| - run->ct_run = ct_run;
|
| - run->origin = run_origin;
|
| - run->width = run_width;
|
| - run->glyphs.resize(glyph_count);
|
| - CTRunGetGlyphs(ct_run, empty_cf_range, &run->glyphs[0]);
|
| - // CTRunGetGlyphs() sometimes returns glyphs with value 65535 and zero
|
| - // width (this has been observed at the beginning of a string containing
|
| - // Arabic content). Passing these to Skia will trigger an assertion;
|
| - // instead set their values to 0.
|
| - for (size_t glyph = 0; glyph < glyph_count; glyph++) {
|
| - if (run->glyphs[glyph] == 65535)
|
| - run->glyphs[glyph] = 0;
|
| - }
|
| -
|
| - run->glyph_positions.resize(glyph_count);
|
| - const CGPoint* positions_ptr = CTRunGetPositionsPtr(ct_run);
|
| - std::vector<CGPoint> positions;
|
| - if (positions_ptr == NULL) {
|
| - positions.resize(glyph_count);
|
| - CTRunGetPositions(ct_run, empty_cf_range, &positions[0]);
|
| - positions_ptr = &positions[0];
|
| - }
|
| - for (size_t glyph = 0; glyph < glyph_count; glyph++) {
|
| - SkPoint* point = &run->glyph_positions[glyph];
|
| - point->set(x + SkDoubleToScalar(positions_ptr[glyph].x),
|
| - y + SkDoubleToScalar(positions_ptr[glyph].y));
|
| - }
|
| -
|
| - // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle
|
| - // this better. Also, support strike and diagonal_strike.
|
| - CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
|
| - CTFontRef ct_font =
|
| - base::mac::GetValueFromDictionary<CTFontRef>(attributes,
|
| - kCTFontAttributeName);
|
| - base::ScopedCFTypeRef<CFStringRef> font_name_ref(
|
| - CTFontCopyFamilyName(ct_font));
|
| - run->font_name = base::SysCFStringRefToUTF8(font_name_ref);
|
| - run->text_size = CTFontGetSize(ct_font);
|
| -
|
| - CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font);
|
| - if (traits & kCTFontBoldTrait)
|
| - run->font_style |= Font::BOLD;
|
| - if (traits & kCTFontItalicTrait)
|
| - run->font_style |= Font::ITALIC;
|
| -
|
| - const CGColorRef foreground =
|
| - base::mac::GetValueFromDictionary<CGColorRef>(
|
| - attributes, kCTForegroundColorAttributeName);
|
| - if (foreground)
|
| - run->foreground = CGColorRefToSkColor(foreground);
|
| -
|
| - const CFNumberRef underline =
|
| - base::mac::GetValueFromDictionary<CFNumberRef>(
|
| - attributes, kCTUnderlineStyleAttributeName);
|
| - CTUnderlineStyle value = kCTUnderlineStyleNone;
|
| - if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value))
|
| - run->underline = (value == kCTUnderlineStyleSingle);
|
| -
|
| - run_origin.offset(run_width, 0);
|
| - }
|
| - runs_valid_ = true;
|
| -}
|
| -
|
| -RenderText* RenderText::CreateNativeInstance() {
|
| - return new RenderTextMac;
|
| -}
|
| -
|
| -} // namespace gfx
|
|
|