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

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

Issue 11535014: Replace StyleRange with BreakList; update RenderText, etc. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simplify OmniboxResultView; Rename StyleBreak; cleanup. Created 7 years, 11 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 | Annotate | Revision Log
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 <cmath> 9 #include <cmath>
10 #include <utility> 10 #include <utility>
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 ApplyTextShadows(&renderer); 151 ApplyTextShadows(&renderer);
152 152
153 for (size_t i = 0; i < runs_.size(); ++i) { 153 for (size_t i = 0; i < runs_.size(); ++i) {
154 const TextRun& run = runs_[i]; 154 const TextRun& run = runs_[i];
155 renderer.SetForegroundColor(run.foreground); 155 renderer.SetForegroundColor(run.foreground);
156 renderer.SetTextSize(run.text_size); 156 renderer.SetTextSize(run.text_size);
157 renderer.SetFontFamilyWithStyle(run.font_name, run.font_style); 157 renderer.SetFontFamilyWithStyle(run.font_name, run.font_style);
158 renderer.DrawPosText(&run.glyph_positions[0], &run.glyphs[0], 158 renderer.DrawPosText(&run.glyph_positions[0], &run.glyphs[0],
159 run.glyphs.size()); 159 run.glyphs.size());
160 renderer.DrawDecorations(run.origin.x(), run.origin.y(), run.width, 160 renderer.DrawDecorations(run.origin.x(), run.origin.y(), run.width,
161 run.style); 161 run.underline, run.strike, run.diagonal_strike);
162 } 162 }
163 } 163 }
164 164
165 RenderTextMac::TextRun::TextRun() 165 RenderTextMac::TextRun::TextRun()
166 : ct_run(NULL), 166 : ct_run(NULL),
167 origin(SkPoint::Make(0, 0)), 167 origin(SkPoint::Make(0, 0)),
168 width(0), 168 width(0),
169 font_style(Font::NORMAL), 169 font_style(Font::NORMAL),
170 text_size(0), 170 text_size(0),
171 foreground(SK_ColorBLACK) { 171 foreground(SK_ColorBLACK),
172 underline(false),
173 strike(false),
174 diagonal_strike(false) {
172 } 175 }
173 176
174 RenderTextMac::TextRun::~TextRun() { 177 RenderTextMac::TextRun::~TextRun() {
175 } 178 }
176 179
177 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, 180 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
178 CTFontRef font) { 181 CTFontRef font) {
179 // Clear attributes and reserve space to hold the maximum number of entries, 182 // Adjust the text colors to reflect the selection range.
180 // which is at most three per style range per the code below. 183 ColorBreaks adjusted_colors(colors());
181 attributes_.reset(CFArrayCreateMutable(NULL, 3 * style_ranges().size(), 184 ApplySelectionColor(&adjusted_colors);
185
186 // Adjust the underline styling to reflect composition ranges.
187 const StyleBreaks* adjusted_styles[NUM_TEXT_STYLES];
188 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
189 adjusted_styles[i] = &styles(static_cast<TextStyle>(i));
190 StyleBreaks adjusted_underlines(styles(UNDERLINE));
191 ApplyCompositionStyle(&adjusted_underlines);
192 adjusted_styles[UNDERLINE] = &adjusted_underlines;
193
194 // Track the current color and style with iterators; get the max style count.
195 ColorBreaks::const_iterator color = adjusted_colors.begin();
196 StyleBreaks::const_iterator style[NUM_TEXT_STYLES];
197 size_t max_style_count = adjusted_colors.size();
198 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) {
199 style[i] = adjusted_styles[i]->begin();
200 max_style_count += adjusted_styles[i]->size();
201 }
202 size_t style_end[NUM_TEXT_STYLES];
203
204 // Clear attributes and reserve space to hold the maximum number of entries.
205 attributes_.reset(CFArrayCreateMutable(NULL, max_style_count,
182 &kCFTypeArrayCallBacks)); 206 &kCFTypeArrayCallBacks));
183 207
184 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor eText_StringAttributes_Ref/Reference/reference.html 208 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor eText_StringAttributes_Ref/Reference/reference.html
185 for (size_t i = 0; i < style_ranges().size(); ++i) { 209 for (size_t i = 0, end = 0; i < text().length(); i = end) {
186 const StyleRange& style = style_ranges()[i]; 210 // Find the end of this ranged style.
187 const CFRange range = CFRangeMake(style.range.start(), 211 const size_t color_end = TextIndexToLayoutIndex(
188 style.range.length()); 212 GetBreakEnd(adjusted_colors, color));
213 end = color_end;
214 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) {
215 style_end[i] = TextIndexToLayoutIndex(
216 GetBreakEnd(*adjusted_styles[i], style[i]));
217 end = std::min(end, style_end[i]);
Alexei Svitkine (slow) 2013/01/22 19:41:03 I find requiring this logic to RenderText subclass
msw 2013/01/22 22:27:24 I agree, and have a TODO in the CL description for
218 }
189 219
190 // Note: CFAttributedStringSetAttribute() does not appear to retain the 220 // Note: CFAttributedStringSetAttribute() does not appear to retain the
191 // values passed in, as can be verified via CFGetRetainCount(). To ensure 221 // values passed in, as can be verified via CFGetRetainCount(). To ensure
192 // the attribute objects do not leak, they are saved to |attributes_|. 222 // the attribute objects do not leak, they are saved to |attributes_|.
193 223
224 const CFRange range = CFRangeMake(i, end - i);
194 base::mac::ScopedCFTypeRef<CGColorRef> foreground( 225 base::mac::ScopedCFTypeRef<CGColorRef> foreground(
195 gfx::CGColorCreateFromSkColor(style.foreground)); 226 gfx::CGColorCreateFromSkColor(color->second));
196 CFAttributedStringSetAttribute(attr_string, range, 227 CFAttributedStringSetAttribute(attr_string, range,
197 kCTForegroundColorAttributeName, 228 kCTForegroundColorAttributeName,
198 foreground); 229 foreground);
199 CFArrayAppendValue(attributes_, foreground); 230 CFArrayAppendValue(attributes_, foreground);
200 231
201 if (style.underline) { 232 if (style[UNDERLINE]->second) {
202 CTUnderlineStyle value = kCTUnderlineStyleSingle; 233 CTUnderlineStyle value = kCTUnderlineStyleSingle;
203 base::mac::ScopedCFTypeRef<CFNumberRef> underline( 234 base::mac::ScopedCFTypeRef<CFNumberRef> underline_value(
204 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); 235 CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
205 CFAttributedStringSetAttribute(attr_string, range, 236 CFAttributedStringSetAttribute(attr_string, range,
206 kCTUnderlineStyleAttributeName, 237 kCTUnderlineStyleAttributeName,
207 underline); 238 underline_value);
208 CFArrayAppendValue(attributes_, underline); 239 CFArrayAppendValue(attributes_, underline_value);
209 } 240 }
210 241
211 if (style.font_style & (Font::BOLD | Font::ITALIC)) { 242 const int traits = (style[BOLD]->second ? kCTFontBoldTrait : 0) |
212 int traits = 0; 243 (style[ITALIC]->second ? kCTFontItalicTrait : 0);
213 if (style.font_style & Font::BOLD) 244 if (traits != 0) {
214 traits |= kCTFontBoldTrait;
215 if (style.font_style & Font::ITALIC)
216 traits |= kCTFontItalicTrait;
217 base::mac::ScopedCFTypeRef<CTFontRef> styled_font( 245 base::mac::ScopedCFTypeRef<CTFontRef> styled_font(
218 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits)); 246 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits));
219 // TODO(asvitkine): Handle |styled_font| == NULL case better. 247 // TODO(asvitkine): Handle |styled_font| == NULL case better.
220 if (styled_font) { 248 if (styled_font) {
221 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, 249 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName,
222 styled_font); 250 styled_font);
223 CFArrayAppendValue(attributes_, styled_font); 251 CFArrayAppendValue(attributes_, styled_font);
224 } 252 }
225 } 253 }
254
255 // Advance the color and style iterators as needed.
256 color += color_end == end ? 1 : 0;
257 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
258 style[i] += style_end[i] == end ? 1 : 0;
226 } 259 }
227 } 260 }
228 261
229 void RenderTextMac::ComputeRuns() { 262 void RenderTextMac::ComputeRuns() {
230 DCHECK(line_); 263 DCHECK(line_);
231 264
232 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_); 265 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_);
233 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs); 266 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs);
234 267
235 gfx::Vector2d text_offset = GetTextOffset(); 268 gfx::Vector2d text_offset = GetTextOffset();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 CTRunGetPositions(ct_run, empty_cf_range, &positions[0]); 309 CTRunGetPositions(ct_run, empty_cf_range, &positions[0]);
277 positions_ptr = &positions[0]; 310 positions_ptr = &positions[0];
278 } 311 }
279 for (size_t glyph = 0; glyph < glyph_count; glyph++) { 312 for (size_t glyph = 0; glyph < glyph_count; glyph++) {
280 SkPoint* point = &run->glyph_positions[glyph]; 313 SkPoint* point = &run->glyph_positions[glyph];
281 point->set(x + SkDoubleToScalar(positions_ptr[glyph].x), 314 point->set(x + SkDoubleToScalar(positions_ptr[glyph].x),
282 y + SkDoubleToScalar(positions_ptr[glyph].y)); 315 y + SkDoubleToScalar(positions_ptr[glyph].y));
283 } 316 }
284 317
285 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle 318 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle
286 // this better. 319 // this better. Also, support strike and diagonal_strike.
287 CFDictionaryRef attributes = CTRunGetAttributes(ct_run); 320 CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
288 CTFontRef ct_font = 321 CTFontRef ct_font =
289 base::mac::GetValueFromDictionary<CTFontRef>(attributes, 322 base::mac::GetValueFromDictionary<CTFontRef>(attributes,
290 kCTFontAttributeName); 323 kCTFontAttributeName);
291 base::mac::ScopedCFTypeRef<CFStringRef> font_name_ref( 324 base::mac::ScopedCFTypeRef<CFStringRef> font_name_ref(
292 CTFontCopyFamilyName(ct_font)); 325 CTFontCopyFamilyName(ct_font));
293 run->font_name = base::SysCFStringRefToUTF8(font_name_ref); 326 run->font_name = base::SysCFStringRefToUTF8(font_name_ref);
294 run->text_size = CTFontGetSize(ct_font); 327 run->text_size = CTFontGetSize(ct_font);
295 328
296 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font); 329 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font);
297 if (traits & kCTFontBoldTrait) 330 if (traits & kCTFontBoldTrait)
298 run->font_style |= Font::BOLD; 331 run->font_style |= Font::BOLD;
299 if (traits & kCTFontItalicTrait) 332 if (traits & kCTFontItalicTrait)
300 run->font_style |= Font::ITALIC; 333 run->font_style |= Font::ITALIC;
301 334
302 const CGColorRef foreground = 335 const CGColorRef foreground =
303 base::mac::GetValueFromDictionary<CGColorRef>( 336 base::mac::GetValueFromDictionary<CGColorRef>(
304 attributes, kCTForegroundColorAttributeName); 337 attributes, kCTForegroundColorAttributeName);
305 if (foreground) 338 if (foreground)
306 run->foreground = gfx::CGColorRefToSkColor(foreground); 339 run->foreground = gfx::CGColorRefToSkColor(foreground);
307 340
308 const CFNumberRef underline = 341 const CFNumberRef underline =
309 base::mac::GetValueFromDictionary<CFNumberRef>( 342 base::mac::GetValueFromDictionary<CFNumberRef>(
310 attributes, kCTUnderlineStyleAttributeName); 343 attributes, kCTUnderlineStyleAttributeName);
311 CTUnderlineStyle value = kCTUnderlineStyleNone; 344 CTUnderlineStyle value = kCTUnderlineStyleNone;
312 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value)) 345 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value))
313 run->style.underline = (value == kCTUnderlineStyleSingle); 346 run->underline = (value == kCTUnderlineStyleSingle);
314 347
315 run_origin.offset(run_width, 0); 348 run_origin.offset(run_width, 0);
316 } 349 }
317 runs_valid_ = true; 350 runs_valid_ = true;
318 } 351 }
319 352
320 RenderText* RenderText::CreateInstance() { 353 RenderText* RenderText::CreateInstance() {
321 return new RenderTextMac; 354 return new RenderTextMac;
322 } 355 }
323 356
324 } // namespace gfx 357 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698