OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |