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

Side by Side Diff: ui/gfx/render_text_mac.cc

Issue 968923004: Use GetDisplayText() instead of text() for rendering text. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 5 years, 9 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
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_mac.h" 5 #include "ui/gfx/render_text_mac.h"
6 6
7 #include <ApplicationServices/ApplicationServices.h> 7 #include <ApplicationServices/ApplicationServices.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 15 matching lines...) Expand all
26 26
27 scoped_ptr<RenderText> RenderTextMac::CreateInstanceOfSameType() const { 27 scoped_ptr<RenderText> RenderTextMac::CreateInstanceOfSameType() const {
28 return make_scoped_ptr(new RenderTextMac); 28 return make_scoped_ptr(new RenderTextMac);
29 } 29 }
30 30
31 const base::string16& RenderTextMac::GetDisplayText() { 31 const base::string16& RenderTextMac::GetDisplayText() {
32 return text_elided() ? display_text() : layout_text(); 32 return text_elided() ? display_text() : layout_text();
33 } 33 }
34 34
35 Size RenderTextMac::GetStringSize() { 35 Size RenderTextMac::GetStringSize() {
36 EnsureLayout(); 36 EnsureStringSize();
37 return Size(std::ceil(string_size_.width()), string_size_.height()); 37 return Size(std::ceil(string_size_->width()), string_size_->height());
38 } 38 }
39 39
40 SizeF RenderTextMac::GetStringSizeF() { 40 SizeF RenderTextMac::GetStringSizeF() {
41 EnsureLayout(); 41 EnsureStringSize();
42 return string_size_; 42 return *string_size_;
43 } 43 }
44 44
45 SelectionModel RenderTextMac::FindCursorPosition(const Point& point) { 45 SelectionModel RenderTextMac::FindCursorPosition(const Point& point) {
46 // TODO(asvitkine): Implement this. http://crbug.com/131618 46 // TODO(asvitkine): Implement this. http://crbug.com/131618
47 return SelectionModel(); 47 return SelectionModel();
48 } 48 }
49 49
50 std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() { 50 std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() {
51 EnsureLayout(); 51 EnsureLayout();
52 if (!runs_valid_) 52 if (!runs_valid_)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 return Range(); 87 return Range();
88 } 88 }
89 89
90 std::vector<Rect> RenderTextMac::GetSubstringBounds(const Range& range) { 90 std::vector<Rect> RenderTextMac::GetSubstringBounds(const Range& range) {
91 // TODO(asvitkine): Implement this. http://crbug.com/131618 91 // TODO(asvitkine): Implement this. http://crbug.com/131618
92 return std::vector<Rect>(); 92 return std::vector<Rect>();
93 } 93 }
94 94
95 size_t RenderTextMac::TextIndexToDisplayIndex(size_t index) { 95 size_t RenderTextMac::TextIndexToDisplayIndex(size_t index) {
96 // TODO(asvitkine): Implement this. http://crbug.com/131618 96 // TODO(asvitkine): Implement this. http://crbug.com/131618
97 return index; 97 return std::min(index, GetDisplayText().size());
tapted 2015/03/05 06:32:49 should this be `.size() - 1`?
Jun Mukai 2015/03/05 18:01:38 This change isn't necessary, removed.
98 } 98 }
99 99
100 size_t RenderTextMac::DisplayIndexToTextIndex(size_t index) { 100 size_t RenderTextMac::DisplayIndexToTextIndex(size_t index) {
101 // TODO(asvitkine): Implement this. http://crbug.com/131618 101 // TODO(asvitkine): Implement this. http://crbug.com/131618
102 return index; 102 return index;
103 } 103 }
104 104
105 bool RenderTextMac::IsValidCursorIndex(size_t index) { 105 bool RenderTextMac::IsValidCursorIndex(size_t index) {
106 // TODO(asvitkine): Implement this. http://crbug.com/131618 106 // TODO(asvitkine): Implement this. http://crbug.com/131618
107 return IsValidLogicalIndex(index); 107 return IsValidLogicalIndex(index);
108 } 108 }
109 109
110 void RenderTextMac::OnLayoutTextAttributeChanged(bool text_changed) { 110 void RenderTextMac::OnLayoutTextAttributeChanged(bool text_changed) {
111 DCHECK(!multiline()) << "RenderTextMac does not support multi line"; 111 DCHECK(!multiline()) << "RenderTextMac does not support multi line";
112 string_size_.reset();
112 if (text_changed) { 113 if (text_changed) {
113 if (elide_behavior() != NO_ELIDE && 114 if (elide_behavior() != NO_ELIDE &&
114 elide_behavior() != FADE_TAIL && 115 elide_behavior() != FADE_TAIL &&
115 !layout_text().empty()) { 116 !layout_text().empty()) {
116 UpdateDisplayText(GetContentWidth()); 117 UpdateDisplayText(GetContentWidth());
117 } else { 118 } else {
118 UpdateDisplayText(0); 119 UpdateDisplayText(0);
119 } 120 }
120 } 121 }
121 line_.reset(); 122 line_.reset();
122 attributes_.reset(); 123 attributes_.reset();
123 runs_.clear(); 124 runs_.clear();
124 runs_valid_ = false; 125 runs_valid_ = false;
125 } 126 }
126 127
127 void RenderTextMac::OnDisplayTextAttributeChanged() { 128 void RenderTextMac::OnDisplayTextAttributeChanged() {
128 OnLayoutTextAttributeChanged(true); 129 OnLayoutTextAttributeChanged(true);
129 } 130 }
130 131
131 void RenderTextMac::EnsureLayout() { 132 void RenderTextMac::EnsureLayout() {
132 if (line_.get()) 133 if (line_.get())
133 return; 134 return;
134 runs_.clear(); 135 runs_.clear();
135 runs_valid_ = false; 136 runs_valid_ = false;
136 137
137 CTFontRef ct_font = base::mac::NSToCFCast( 138 EnsureStringSize();
138 font_list().GetPrimaryFont().GetNativeFont()); 139 EnsureLayoutInternal(GetDisplayText(), &line_, &attributes_);
139
140 const void* keys[] = { kCTFontAttributeName };
141 const void* values[] = { ct_font };
142 base::ScopedCFTypeRef<CFDictionaryRef> attributes(
143 CFDictionaryCreate(NULL,
144 keys,
145 values,
146 arraysize(keys),
147 NULL,
148 &kCFTypeDictionaryValueCallBacks));
149
150 base::ScopedCFTypeRef<CFStringRef> cf_text(
151 base::SysUTF16ToCFStringRef(text()));
152 base::ScopedCFTypeRef<CFAttributedStringRef> attr_text(
153 CFAttributedStringCreate(NULL, cf_text, attributes));
154 base::ScopedCFTypeRef<CFMutableAttributedStringRef> attr_text_mutable(
155 CFAttributedStringCreateMutableCopy(NULL, 0, attr_text));
156
157 // TODO(asvitkine|msw): Respect GetTextDirection(), which may not match the
158 // natural text direction. See kCTTypesetterOptionForcedEmbeddingLevel, etc.
159
160 ApplyStyles(attr_text_mutable, ct_font);
161 line_.reset(CTLineCreateWithAttributedString(attr_text_mutable));
162
163 CGFloat ascent = 0;
164 CGFloat descent = 0;
165 CGFloat leading = 0;
166 // TODO(asvitkine): Consider using CTLineGetBoundsWithOptions() on 10.8+.
167 double width = CTLineGetTypographicBounds(line_, &ascent, &descent, &leading);
168 // Ensure ascent and descent are not smaller than ones of the font list.
169 // Keep them tall enough to draw often-used characters.
170 // For example, if a text field contains a Japanese character, which is
171 // smaller than Latin ones, and then later a Latin one is inserted, this
172 // ensures that the text baseline does not shift.
173 CGFloat font_list_height = font_list().GetHeight();
174 CGFloat font_list_baseline = font_list().GetBaseline();
175 ascent = std::max(ascent, font_list_baseline);
176 descent = std::max(descent, font_list_height - font_list_baseline);
177 string_size_ =
178 SizeF(width, std::max(ascent + descent + leading,
179 static_cast<CGFloat>(min_line_height())));
180 common_baseline_ = ascent;
181 } 140 }
182 141
183 void RenderTextMac::DrawVisualText(Canvas* canvas) { 142 void RenderTextMac::DrawVisualText(Canvas* canvas) {
184 DCHECK(line_); 143 DCHECK(line_);
185 if (!runs_valid_) 144 if (!runs_valid_)
186 ComputeRuns(); 145 ComputeRuns();
187 146
188 internal::SkiaTextRenderer renderer(canvas); 147 internal::SkiaTextRenderer renderer(canvas);
189 ApplyFadeEffects(&renderer); 148 ApplyFadeEffects(&renderer);
190 ApplyTextShadows(&renderer); 149 ApplyTextShadows(&renderer);
(...skipping 20 matching lines...) Expand all
211 text_size(0), 170 text_size(0),
212 foreground(SK_ColorBLACK), 171 foreground(SK_ColorBLACK),
213 underline(false), 172 underline(false),
214 strike(false), 173 strike(false),
215 diagonal_strike(false) { 174 diagonal_strike(false) {
216 } 175 }
217 176
218 RenderTextMac::TextRun::~TextRun() { 177 RenderTextMac::TextRun::~TextRun() {
219 } 178 }
220 179
221 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, 180 void RenderTextMac::EnsureStringSize() {
222 CTFontRef font) { 181 if (string_size_)
182 return;
183
184 base::ScopedCFTypeRef<CTLineRef> line;
185 base::ScopedCFTypeRef<CFMutableArrayRef> attributes_owner;
186 EnsureLayoutInternal(layout_text(), &line, &attributes_owner);
187
188 CGFloat ascent = 0;
189 CGFloat descent = 0;
190 CGFloat leading = 0;
191 // TODO(asvitkine): Consider using CTLineGetBoundsWithOptions() on 10.8+.
192 double width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
193 // Ensure ascent and descent are not smaller than ones of the font list.
194 // Keep them tall enough to draw often-used characters.
195 // For example, if a text field contains a Japanese character, which is
196 // smaller than Latin ones, and then later a Latin one is inserted, this
197 // ensures that the text baseline does not shift.
198 CGFloat font_list_height = font_list().GetHeight();
199 CGFloat font_list_baseline = font_list().GetBaseline();
200 ascent = std::max(ascent, font_list_baseline);
201 descent = std::max(descent, font_list_height - font_list_baseline);
202 string_size_.reset(new SizeF(
203 width, std::max(ascent + descent + leading,
204 static_cast<CGFloat>(min_line_height()))));
205 common_baseline_ = ascent;
206 }
207
208 void RenderTextMac::EnsureLayoutInternal(
209 const base::string16& text,
210 base::ScopedCFTypeRef<CTLineRef>* line,
211 base::ScopedCFTypeRef<CFMutableArrayRef>* attributes_owner) {
212 CTFontRef ct_font = base::mac::NSToCFCast(
213 font_list().GetPrimaryFont().GetNativeFont());
214
215 const void* keys[] = { kCTFontAttributeName };
216 const void* values[] = { ct_font };
217 base::ScopedCFTypeRef<CFDictionaryRef> attributes(
218 CFDictionaryCreate(NULL,
219 keys,
220 values,
221 arraysize(keys),
222 NULL,
223 &kCFTypeDictionaryValueCallBacks));
224
225 base::ScopedCFTypeRef<CFStringRef> cf_text(
226 base::SysUTF16ToCFStringRef(text));
227 base::ScopedCFTypeRef<CFAttributedStringRef> attr_text(
228 CFAttributedStringCreate(NULL, cf_text, attributes));
229 base::ScopedCFTypeRef<CFMutableAttributedStringRef> attr_text_mutable(
230 CFAttributedStringCreateMutableCopy(NULL, 0, attr_text));
231
232 // TODO(asvitkine|msw): Respect GetTextDirection(), which may not match the
233 // natural text direction. See kCTTypesetterOptionForcedEmbeddingLevel, etc.
234
235 ApplyStyles(attr_text_mutable, ct_font, attributes_owner);
236 line->reset(CTLineCreateWithAttributedString(attr_text_mutable));
237 }
238
239 void RenderTextMac::ApplyStyles(
240 CFMutableAttributedStringRef attr_string,
241 CTFontRef font,
242 base::ScopedCFTypeRef<CFMutableArrayRef>* attributes_owner) {
223 // Temporarily apply composition underlines and selection colors. 243 // Temporarily apply composition underlines and selection colors.
224 ApplyCompositionAndSelectionStyles(); 244 ApplyCompositionAndSelectionStyles();
225 245
226 // Note: CFAttributedStringSetAttribute() does not appear to retain the values 246 // Note: CFAttributedStringSetAttribute() does not appear to retain the values
227 // passed in, as can be verified via CFGetRetainCount(). To ensure the 247 // passed in, as can be verified via CFGetRetainCount(). To ensure the
228 // attribute objects do not leak, they are saved to |attributes_|. 248 // attribute objects do not leak, they are saved to |attributes_|.
229 // Clear the attributes storage. 249 // Clear the attributes storage.
230 attributes_.reset(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); 250 attributes_owner->reset(
251 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
231 252
232 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor eText_StringAttributes_Ref/Reference/reference.html 253 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor eText_StringAttributes_Ref/Reference/reference.html
233 internal::StyleIterator style(colors(), styles()); 254 internal::StyleIterator style(colors(), styles());
234 const size_t layout_text_length = GetDisplayText().length(); 255 const size_t layout_text_length = CFAttributedStringGetLength(attr_string);
235 for (size_t i = 0, end = 0; i < layout_text_length; i = end) { 256 for (size_t i = 0, end = 0; i < layout_text_length; i = end) {
236 end = TextIndexToDisplayIndex(style.GetRange().end()); 257 end = std::min(style.GetRange().end(), layout_text_length);
237 const CFRange range = CFRangeMake(i, end - i); 258 const CFRange range = CFRangeMake(i, end - i);
238 base::ScopedCFTypeRef<CGColorRef> foreground( 259 base::ScopedCFTypeRef<CGColorRef> foreground(
239 CGColorCreateFromSkColor(style.color())); 260 CGColorCreateFromSkColor(style.color()));
240 CFAttributedStringSetAttribute(attr_string, range, 261 CFAttributedStringSetAttribute(attr_string, range,
241 kCTForegroundColorAttributeName, foreground); 262 kCTForegroundColorAttributeName, foreground);
242 CFArrayAppendValue(attributes_, foreground); 263 CFArrayAppendValue(*attributes_owner, foreground);
243 264
244 if (style.style(UNDERLINE)) { 265 if (style.style(UNDERLINE)) {
245 CTUnderlineStyle value = kCTUnderlineStyleSingle; 266 CTUnderlineStyle value = kCTUnderlineStyleSingle;
246 base::ScopedCFTypeRef<CFNumberRef> underline_value( 267 base::ScopedCFTypeRef<CFNumberRef> underline_value(
247 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); 268 CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
248 CFAttributedStringSetAttribute(attr_string, range, 269 CFAttributedStringSetAttribute(attr_string, range,
249 kCTUnderlineStyleAttributeName, 270 kCTUnderlineStyleAttributeName,
250 underline_value); 271 underline_value);
251 CFArrayAppendValue(attributes_, underline_value); 272 CFArrayAppendValue(*attributes_owner, underline_value);
252 } 273 }
253 274
254 const int traits = (style.style(BOLD) ? kCTFontBoldTrait : 0) | 275 const int traits = (style.style(BOLD) ? kCTFontBoldTrait : 0) |
255 (style.style(ITALIC) ? kCTFontItalicTrait : 0); 276 (style.style(ITALIC) ? kCTFontItalicTrait : 0);
256 if (traits != 0) { 277 if (traits != 0) {
257 base::ScopedCFTypeRef<CTFontRef> styled_font( 278 base::ScopedCFTypeRef<CTFontRef> styled_font(
258 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits)); 279 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits));
259 // TODO(asvitkine): Handle |styled_font| == NULL case better. 280 // TODO(asvitkine): Handle |styled_font| == NULL case better.
260 if (styled_font) { 281 if (styled_font) {
261 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, 282 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName,
262 styled_font); 283 styled_font);
263 CFArrayAppendValue(attributes_, styled_font); 284 CFArrayAppendValue(*attributes_owner, styled_font);
264 } 285 }
265 } 286 }
266 287
267 style.UpdatePosition(DisplayIndexToTextIndex(end)); 288 style.UpdatePosition(DisplayIndexToTextIndex(end));
268 } 289 }
269 290
270 // Undo the temporarily applied composition underlines and selection colors. 291 // Undo the temporarily applied composition underlines and selection colors.
271 UndoCompositionAndSelectionStyles(); 292 UndoCompositionAndSelectionStyles();
272 } 293 }
273 294
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 CTUnderlineStyle value = kCTUnderlineStyleNone; 379 CTUnderlineStyle value = kCTUnderlineStyleNone;
359 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value)) 380 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value))
360 run->underline = (value == kCTUnderlineStyleSingle); 381 run->underline = (value == kCTUnderlineStyleSingle);
361 382
362 run_origin.offset(run_width, 0); 383 run_origin.offset(run_width, 0);
363 } 384 }
364 runs_valid_ = true; 385 runs_valid_ = true;
365 } 386 }
366 387
367 } // namespace gfx 388 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698