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

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: Add GetNextBreak and AdvanceIterators convenience methods; cleanup. Created 7 years, 10 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 // Temporarily apply composition underlines and selection colors.
180 // which is at most three per style range per the code below. 183 ApplyCompositionAndSelectionStyles();
181 attributes_.reset(CFArrayCreateMutable(NULL, 3 * style_ranges().size(), 184
185 // Track the current color and style with iterators.
186 BreakList<SkColor>::const_iterator color = colors().list().begin();
187 size_t max_style_count = colors().list().size();
188 BreakList<bool>::const_iterator style[NUM_TEXT_STYLES];
189 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) {
190 style[i] = styles(static_cast<TextStyle>(i)).list().begin();
191 max_style_count += styles(static_cast<TextStyle>(i)).list().size();
192 }
193
194 // Clear attributes and reserve space to hold the maximum number of entries.
195 // Note: CFAttributedStringSetAttribute() does not appear to retain the values
196 // passed in, as can be verified via CFGetRetainCount(). To ensure the
197 // attribute objects do not leak, they are saved to |attributes_|.
198 attributes_.reset(CFArrayCreateMutable(NULL, max_style_count,
Alexei Svitkine (slow) 2013/01/28 20:52:30 Please put the "Note:" comment above the current f
msw 2013/01/29 17:17:25 Done (but potentially reverting in the subsequent
182 &kCFTypeArrayCallBacks)); 199 &kCFTypeArrayCallBacks));
183 200
184 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor eText_StringAttributes_Ref/Reference/reference.html 201 // 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) { 202 for (size_t i = 0, end = 0; i < text().length(); i = end) {
186 const StyleRange& style = style_ranges()[i]; 203 end = GetNextBreak(color, style);
187 const CFRange range = CFRangeMake(style.range.start(), 204 const CFRange range = CFRangeMake(i, end - i);
188 style.range.length());
189
190 // Note: CFAttributedStringSetAttribute() does not appear to retain the
191 // values passed in, as can be verified via CFGetRetainCount(). To ensure
192 // the attribute objects do not leak, they are saved to |attributes_|.
193
194 base::mac::ScopedCFTypeRef<CGColorRef> foreground( 205 base::mac::ScopedCFTypeRef<CGColorRef> foreground(
195 gfx::CGColorCreateFromSkColor(style.foreground)); 206 gfx::CGColorCreateFromSkColor(color->second));
196 CFAttributedStringSetAttribute(attr_string, range, 207 CFAttributedStringSetAttribute(attr_string, range,
197 kCTForegroundColorAttributeName, 208 kCTForegroundColorAttributeName, foreground);
198 foreground);
199 CFArrayAppendValue(attributes_, foreground); 209 CFArrayAppendValue(attributes_, foreground);
200 210
201 if (style.underline) { 211 if (style[UNDERLINE]->second) {
202 CTUnderlineStyle value = kCTUnderlineStyleSingle; 212 CTUnderlineStyle value = kCTUnderlineStyleSingle;
203 base::mac::ScopedCFTypeRef<CFNumberRef> underline( 213 base::mac::ScopedCFTypeRef<CFNumberRef> underline_value(
204 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); 214 CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
205 CFAttributedStringSetAttribute(attr_string, range, 215 CFAttributedStringSetAttribute(attr_string, range,
206 kCTUnderlineStyleAttributeName, 216 kCTUnderlineStyleAttributeName, underline_value);
Alexei Svitkine (slow) 2013/01/28 20:52:30 Nit: This is actually against the style guide, se
msw 2013/01/29 17:17:25 Done.
207 underline); 217 CFArrayAppendValue(attributes_, underline_value);
208 CFArrayAppendValue(attributes_, underline);
209 } 218 }
210 219
211 if (style.font_style & (Font::BOLD | Font::ITALIC)) { 220 const int traits = (style[BOLD]->second ? kCTFontBoldTrait : 0) |
212 int traits = 0; 221 (style[ITALIC]->second ? kCTFontItalicTrait : 0);
213 if (style.font_style & Font::BOLD) 222 if (traits != 0) {
214 traits |= kCTFontBoldTrait;
215 if (style.font_style & Font::ITALIC)
216 traits |= kCTFontItalicTrait;
217 base::mac::ScopedCFTypeRef<CTFontRef> styled_font( 223 base::mac::ScopedCFTypeRef<CTFontRef> styled_font(
218 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits)); 224 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits));
219 // TODO(asvitkine): Handle |styled_font| == NULL case better. 225 // TODO(asvitkine): Handle |styled_font| == NULL case better.
220 if (styled_font) { 226 if (styled_font) {
221 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, 227 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName,
222 styled_font); 228 styled_font);
223 CFArrayAppendValue(attributes_, styled_font); 229 CFArrayAppendValue(attributes_, styled_font);
224 } 230 }
225 } 231 }
232
233 AdvanceIterators(end, &color, style);
226 } 234 }
235
236 // Undo the temporarily applied composition underlines and selection colors.
237 UndoCompositionAndSelectionStyles();
227 } 238 }
228 239
229 void RenderTextMac::ComputeRuns() { 240 void RenderTextMac::ComputeRuns() {
230 DCHECK(line_); 241 DCHECK(line_);
231 242
232 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_); 243 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_);
233 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs); 244 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs);
234 245
235 gfx::Vector2d text_offset = GetTextOffset(); 246 gfx::Vector2d text_offset = GetTextOffset();
236 // Skia will draw glyphs with respect to the baseline. 247 // Skia will draw glyphs with respect to the baseline.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 CTRunGetPositions(ct_run, empty_cf_range, &positions[0]); 287 CTRunGetPositions(ct_run, empty_cf_range, &positions[0]);
277 positions_ptr = &positions[0]; 288 positions_ptr = &positions[0];
278 } 289 }
279 for (size_t glyph = 0; glyph < glyph_count; glyph++) { 290 for (size_t glyph = 0; glyph < glyph_count; glyph++) {
280 SkPoint* point = &run->glyph_positions[glyph]; 291 SkPoint* point = &run->glyph_positions[glyph];
281 point->set(x + SkDoubleToScalar(positions_ptr[glyph].x), 292 point->set(x + SkDoubleToScalar(positions_ptr[glyph].x),
282 y + SkDoubleToScalar(positions_ptr[glyph].y)); 293 y + SkDoubleToScalar(positions_ptr[glyph].y));
283 } 294 }
284 295
285 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle 296 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle
286 // this better. 297 // this better. Also, support strike and diagonal_strike.
287 CFDictionaryRef attributes = CTRunGetAttributes(ct_run); 298 CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
288 CTFontRef ct_font = 299 CTFontRef ct_font =
289 base::mac::GetValueFromDictionary<CTFontRef>(attributes, 300 base::mac::GetValueFromDictionary<CTFontRef>(attributes,
290 kCTFontAttributeName); 301 kCTFontAttributeName);
291 base::mac::ScopedCFTypeRef<CFStringRef> font_name_ref( 302 base::mac::ScopedCFTypeRef<CFStringRef> font_name_ref(
292 CTFontCopyFamilyName(ct_font)); 303 CTFontCopyFamilyName(ct_font));
293 run->font_name = base::SysCFStringRefToUTF8(font_name_ref); 304 run->font_name = base::SysCFStringRefToUTF8(font_name_ref);
294 run->text_size = CTFontGetSize(ct_font); 305 run->text_size = CTFontGetSize(ct_font);
295 306
296 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font); 307 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font);
297 if (traits & kCTFontBoldTrait) 308 if (traits & kCTFontBoldTrait)
298 run->font_style |= Font::BOLD; 309 run->font_style |= Font::BOLD;
299 if (traits & kCTFontItalicTrait) 310 if (traits & kCTFontItalicTrait)
300 run->font_style |= Font::ITALIC; 311 run->font_style |= Font::ITALIC;
301 312
302 const CGColorRef foreground = 313 const CGColorRef foreground =
303 base::mac::GetValueFromDictionary<CGColorRef>( 314 base::mac::GetValueFromDictionary<CGColorRef>(
304 attributes, kCTForegroundColorAttributeName); 315 attributes, kCTForegroundColorAttributeName);
305 if (foreground) 316 if (foreground)
306 run->foreground = gfx::CGColorRefToSkColor(foreground); 317 run->foreground = gfx::CGColorRefToSkColor(foreground);
307 318
308 const CFNumberRef underline = 319 const CFNumberRef underline =
309 base::mac::GetValueFromDictionary<CFNumberRef>( 320 base::mac::GetValueFromDictionary<CFNumberRef>(
310 attributes, kCTUnderlineStyleAttributeName); 321 attributes, kCTUnderlineStyleAttributeName);
311 CTUnderlineStyle value = kCTUnderlineStyleNone; 322 CTUnderlineStyle value = kCTUnderlineStyleNone;
312 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value)) 323 if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value))
313 run->style.underline = (value == kCTUnderlineStyleSingle); 324 run->underline = (value == kCTUnderlineStyleSingle);
314 325
315 run_origin.offset(run_width, 0); 326 run_origin.offset(run_width, 0);
316 } 327 }
317 runs_valid_ = true; 328 runs_valid_ = true;
318 } 329 }
319 330
320 RenderText* RenderText::CreateInstance() { 331 RenderText* RenderText::CreateInstance() {
321 return new RenderTextMac; 332 return new RenderTextMac;
322 } 333 }
323 334
324 } // namespace gfx 335 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698