| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 return std::vector<Rect>(); | 148 return std::vector<Rect>(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 bool RenderTextMac::IsCursorablePosition(size_t position) { | 151 bool RenderTextMac::IsCursorablePosition(size_t position) { |
| 152 // TODO(asvitkine): Implement this. http://crbug.com/131618 | 152 // TODO(asvitkine): Implement this. http://crbug.com/131618 |
| 153 return false; | 153 return false; |
| 154 } | 154 } |
| 155 | 155 |
| 156 void RenderTextMac::ResetLayout() { | 156 void RenderTextMac::ResetLayout() { |
| 157 line_.reset(); | 157 line_.reset(); |
| 158 attributes_.reset(); |
| 158 runs_.clear(); | 159 runs_.clear(); |
| 159 runs_valid_ = false; | 160 runs_valid_ = false; |
| 160 } | 161 } |
| 161 | 162 |
| 162 void RenderTextMac::EnsureLayout() { | 163 void RenderTextMac::EnsureLayout() { |
| 163 if (line_.get()) | 164 if (line_.get()) |
| 164 return; | 165 return; |
| 165 runs_.clear(); | 166 runs_.clear(); |
| 166 runs_valid_ = false; | 167 runs_valid_ = false; |
| 167 | 168 |
| 168 const Font& font = GetFont(); | 169 const Font& font = GetFont(); |
| 169 CTFontRef ct_font = | 170 CTFontRef ct_font = |
| 170 CreateCTFontWithPixelSize(font.GetFontName(), font.GetFontSize()); | 171 CreateCTFontWithPixelSize(font.GetFontName(), font.GetFontSize()); |
| 171 | 172 |
| 172 const void* keys[] = { kCTFontAttributeName }; | 173 const void* keys[] = { kCTFontAttributeName }; |
| 173 const void* values[] = { ct_font }; | 174 const void* values[] = { ct_font }; |
| 174 base::mac::ScopedCFTypeRef<CFDictionaryRef> attributes( | 175 base::mac::ScopedCFTypeRef<CFDictionaryRef> attributes( |
| 175 CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL, NULL)); | 176 CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL, |
| 177 &kCFTypeDictionaryValueCallBacks)); |
| 176 | 178 |
| 177 base::mac::ScopedCFTypeRef<CFStringRef> cf_text( | 179 base::mac::ScopedCFTypeRef<CFStringRef> cf_text( |
| 178 base::SysUTF16ToCFStringRef(text())); | 180 base::SysUTF16ToCFStringRef(text())); |
| 179 base::mac::ScopedCFTypeRef<CFAttributedStringRef> attr_text( | 181 base::mac::ScopedCFTypeRef<CFAttributedStringRef> attr_text( |
| 180 CFAttributedStringCreate(NULL, cf_text, attributes)); | 182 CFAttributedStringCreate(NULL, cf_text, attributes)); |
| 181 base::mac::ScopedCFTypeRef<CFMutableAttributedStringRef> attr_text_mutable( | 183 base::mac::ScopedCFTypeRef<CFMutableAttributedStringRef> attr_text_mutable( |
| 182 CFAttributedStringCreateMutableCopy(NULL, 0, attr_text)); | 184 CFAttributedStringCreateMutableCopy(NULL, 0, attr_text)); |
| 183 | 185 |
| 184 ApplyStyles(attr_text_mutable, ct_font); | 186 ApplyStyles(attr_text_mutable, ct_font); |
| 185 line_.reset(CTLineCreateWithAttributedString(attr_text_mutable)); | 187 line_.reset(CTLineCreateWithAttributedString(attr_text_mutable)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 font_style(Font::NORMAL), | 223 font_style(Font::NORMAL), |
| 222 text_size(0), | 224 text_size(0), |
| 223 foreground(SK_ColorBLACK) { | 225 foreground(SK_ColorBLACK) { |
| 224 } | 226 } |
| 225 | 227 |
| 226 RenderTextMac::TextRun::~TextRun() { | 228 RenderTextMac::TextRun::~TextRun() { |
| 227 } | 229 } |
| 228 | 230 |
| 229 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, | 231 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
| 230 CTFontRef font) { | 232 CTFontRef font) { |
| 233 // Clear attributes and reserve space to hold the maximum number of entries, |
| 234 // which is at most three per style range per the code below. |
| 235 attributes_.reset(CFArrayCreateMutable(NULL, 3 * style_ranges().size(), |
| 236 &kCFTypeArrayCallBacks)); |
| 237 |
| 231 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor
eText_StringAttributes_Ref/Reference/reference.html | 238 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor
eText_StringAttributes_Ref/Reference/reference.html |
| 232 for (size_t i = 0; i < style_ranges().size(); ++i) { | 239 for (size_t i = 0; i < style_ranges().size(); ++i) { |
| 233 const StyleRange& style = style_ranges()[i]; | 240 const StyleRange& style = style_ranges()[i]; |
| 234 const CFRange range = CFRangeMake(style.range.start(), | 241 const CFRange range = CFRangeMake(style.range.start(), |
| 235 style.range.length()); | 242 style.range.length()); |
| 236 | 243 |
| 237 // Note: CFAttributedStringSetAttribute() does not appear to retain the | 244 // Note: CFAttributedStringSetAttribute() does not appear to retain the |
| 238 // values passed in, as can be verified via CFGetRetainCount(). | 245 // values passed in, as can be verified via CFGetRetainCount(). To ensure |
| 239 // | 246 // the attribute objects do not leak, they are saved to |attributes_|. |
| 240 // TODO(asvitkine): The attributed string appears to hold weak refs to these | |
| 241 // objects (it does not release them either), so we need to keep track of | |
| 242 // them ourselves and release them at an appropriate time. | |
| 243 | 247 |
| 244 CGColorRef foreground = gfx::SkColorToCGColorRef(style.foreground); | 248 base::mac::ScopedCFTypeRef<CGColorRef> foreground( |
| 249 gfx::CGColorCreateFromSkColor(style.foreground)); |
| 245 CFAttributedStringSetAttribute(attr_string, range, | 250 CFAttributedStringSetAttribute(attr_string, range, |
| 246 kCTForegroundColorAttributeName, | 251 kCTForegroundColorAttributeName, |
| 247 foreground); | 252 foreground); |
| 253 CFArrayAppendValue(attributes_, foreground); |
| 248 | 254 |
| 249 if (style.underline) { | 255 if (style.underline) { |
| 250 CTUnderlineStyle value = kCTUnderlineStyleSingle; | 256 CTUnderlineStyle value = kCTUnderlineStyleSingle; |
| 251 CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type, &value); | 257 base::mac::ScopedCFTypeRef<CFNumberRef> underline( |
| 258 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); |
| 252 CFAttributedStringSetAttribute(attr_string, range, | 259 CFAttributedStringSetAttribute(attr_string, range, |
| 253 kCTUnderlineStyleAttributeName, | 260 kCTUnderlineStyleAttributeName, |
| 254 underline); | 261 underline); |
| 262 CFArrayAppendValue(attributes_, underline); |
| 255 } | 263 } |
| 256 | 264 |
| 257 if (style.font_style & (Font::BOLD | Font::ITALIC)) { | 265 if (style.font_style & (Font::BOLD | Font::ITALIC)) { |
| 258 int traits = 0; | 266 int traits = 0; |
| 259 if (style.font_style & Font::BOLD) | 267 if (style.font_style & Font::BOLD) |
| 260 traits |= kCTFontBoldTrait; | 268 traits |= kCTFontBoldTrait; |
| 261 if (style.font_style & Font::ITALIC) | 269 if (style.font_style & Font::ITALIC) |
| 262 traits |= kCTFontItalicTrait; | 270 traits |= kCTFontItalicTrait; |
| 263 CTFontRef styled_font = | 271 base::mac::ScopedCFTypeRef<CTFontRef> styled_font( |
| 264 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits); | 272 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits)); |
| 265 // TODO(asvitkine): Handle |styled_font| == NULL case better. | 273 // TODO(asvitkine): Handle |styled_font| == NULL case better. |
| 266 if (styled_font) { | 274 if (styled_font) { |
| 267 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, | 275 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, |
| 268 styled_font); | 276 styled_font); |
| 277 CFArrayAppendValue(attributes_, styled_font); |
| 269 } | 278 } |
| 270 } | 279 } |
| 271 } | 280 } |
| 272 } | 281 } |
| 273 | 282 |
| 274 void RenderTextMac::ComputeRuns() { | 283 void RenderTextMac::ComputeRuns() { |
| 275 DCHECK(line_); | 284 DCHECK(line_); |
| 276 | 285 |
| 277 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_); | 286 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_); |
| 278 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs); | 287 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 run_origin.offset(run_width, 0); | 369 run_origin.offset(run_width, 0); |
| 361 } | 370 } |
| 362 runs_valid_ = true; | 371 runs_valid_ = true; |
| 363 } | 372 } |
| 364 | 373 |
| 365 RenderText* RenderText::CreateInstance() { | 374 RenderText* RenderText::CreateInstance() { |
| 366 return new RenderTextMac; | 375 return new RenderTextMac; |
| 367 } | 376 } |
| 368 | 377 |
| 369 } // namespace gfx | 378 } // namespace gfx |
| OLD | NEW |