Index: ui/gfx/render_text_mac.cc |
diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc |
index 1c046648dc63220fcca566f1ec8c85a106cd3d5e..331e89617db2b7126c3bbf8c760315c010f3fa2d 100644 |
--- a/ui/gfx/render_text_mac.cc |
+++ b/ui/gfx/render_text_mac.cc |
@@ -33,13 +33,13 @@ const base::string16& RenderTextMac::GetDisplayText() { |
} |
Size RenderTextMac::GetStringSize() { |
- EnsureLayout(); |
- return Size(std::ceil(string_size_.width()), string_size_.height()); |
+ EnsureStringSize(); |
oshima
2015/03/05 18:14:20
I believe this should return the size of display t
Jun Mukai
2015/03/05 18:41:38
Reverted back to the original.
|
+ return Size(std::ceil(string_size_->width()), string_size_->height()); |
} |
SizeF RenderTextMac::GetStringSizeF() { |
- EnsureLayout(); |
- return string_size_; |
+ EnsureStringSize(); |
+ return *string_size_; |
} |
SelectionModel RenderTextMac::FindCursorPosition(const Point& point) { |
@@ -109,6 +109,7 @@ bool RenderTextMac::IsValidCursorIndex(size_t index) { |
void RenderTextMac::OnLayoutTextAttributeChanged(bool text_changed) { |
DCHECK(!multiline()) << "RenderTextMac does not support multi line"; |
+ string_size_.reset(); |
if (text_changed) { |
if (elide_behavior() != NO_ELIDE && |
elide_behavior() != FADE_TAIL && |
@@ -134,50 +135,8 @@ void RenderTextMac::EnsureLayout() { |
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, std::max(ascent + descent + leading, |
- static_cast<CGFloat>(min_line_height()))); |
- common_baseline_ = ascent; |
+ EnsureStringSize(); |
+ line_ = EnsureLayoutInternal(GetDisplayText(), &attributes_); |
} |
void RenderTextMac::DrawVisualText(Canvas* canvas) { |
@@ -218,8 +177,68 @@ RenderTextMac::TextRun::TextRun() |
RenderTextMac::TextRun::~TextRun() { |
} |
-void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
- CTFontRef font) { |
+void RenderTextMac::EnsureStringSize() { |
+ if (string_size_) |
+ return; |
+ |
+ base::ScopedCFTypeRef<CFMutableArrayRef> attributes_owner; |
+ base::ScopedCFTypeRef<CTLineRef> line( |
+ EnsureLayoutInternal(layout_text(), &attributes_owner)); |
+ |
+ 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_.reset(new SizeF( |
+ width, std::max(ascent + descent + leading, |
+ static_cast<CGFloat>(min_line_height())))); |
+ common_baseline_ = ascent; |
+} |
+ |
+base::ScopedCFTypeRef<CTLineRef> RenderTextMac::EnsureLayoutInternal( |
+ const base::string16& text, |
+ base::ScopedCFTypeRef<CFMutableArrayRef>* attributes_owner) const { |
+ 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. |
+ |
+ *attributes_owner = ApplyStyles(attr_text_mutable, ct_font); |
+ return base::ScopedCFTypeRef<CTLineRef>( |
+ CTLineCreateWithAttributedString(attr_text_mutable)); |
+} |
+ |
+base::ScopedCFTypeRef<CFMutableArrayRef> RenderTextMac::ApplyStyles( |
+ CFMutableAttributedStringRef attr_string, |
+ CTFontRef font) const { |
// Temporarily apply composition underlines and selection colors. |
ApplyCompositionAndSelectionStyles(); |
@@ -227,19 +246,20 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
// 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)); |
+ base::ScopedCFTypeRef<CFMutableArrayRef> attributes( |
+ 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 = GetDisplayText().length(); |
+ const size_t layout_text_length = CFAttributedStringGetLength(attr_string); |
for (size_t i = 0, end = 0; i < layout_text_length; i = end) { |
- end = TextIndexToDisplayIndex(style.GetRange().end()); |
+ end = std::min(style.GetRange().end(), layout_text_length); |
const CFRange range = CFRangeMake(i, end - i); |
base::ScopedCFTypeRef<CGColorRef> foreground( |
CGColorCreateFromSkColor(style.color())); |
CFAttributedStringSetAttribute(attr_string, range, |
kCTForegroundColorAttributeName, foreground); |
- CFArrayAppendValue(attributes_, foreground); |
+ CFArrayAppendValue(attributes, foreground); |
if (style.style(UNDERLINE)) { |
CTUnderlineStyle value = kCTUnderlineStyleSingle; |
@@ -248,7 +268,7 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
CFAttributedStringSetAttribute(attr_string, range, |
kCTUnderlineStyleAttributeName, |
underline_value); |
- CFArrayAppendValue(attributes_, underline_value); |
+ CFArrayAppendValue(attributes, underline_value); |
} |
const int traits = (style.style(BOLD) ? kCTFontBoldTrait : 0) | |
@@ -260,7 +280,7 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
if (styled_font) { |
CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, |
styled_font); |
- CFArrayAppendValue(attributes_, styled_font); |
+ CFArrayAppendValue(attributes, styled_font); |
} |
} |
@@ -269,6 +289,8 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
// Undo the temporarily applied composition underlines and selection colors. |
UndoCompositionAndSelectionStyles(); |
+ |
+ return attributes; |
} |
void RenderTextMac::ComputeRuns() { |