Chromium Code Reviews| 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 |
| 186 attributes_.reset(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); | |
|
Nico
2012/07/23 19:23:32
nit: If you did this in ApplyStyles(), you could p
Alexei Svitkine (slow)
2012/07/23 19:35:55
Good call, done!
| |
| 184 ApplyStyles(attr_text_mutable, ct_font); | 187 ApplyStyles(attr_text_mutable, ct_font); |
| 185 line_.reset(CTLineCreateWithAttributedString(attr_text_mutable)); | 188 line_.reset(CTLineCreateWithAttributedString(attr_text_mutable)); |
| 186 | 189 |
| 187 CGFloat ascent = 0; | 190 CGFloat ascent = 0; |
| 188 CGFloat descent = 0; | 191 CGFloat descent = 0; |
| 189 CGFloat leading = 0; | 192 CGFloat leading = 0; |
| 190 // TODO(asvitkine): Consider using CTLineGetBoundsWithOptions() on 10.8+. | 193 // TODO(asvitkine): Consider using CTLineGetBoundsWithOptions() on 10.8+. |
| 191 double width = CTLineGetTypographicBounds(line_, &ascent, &descent, &leading); | 194 double width = CTLineGetTypographicBounds(line_, &ascent, &descent, &leading); |
| 192 string_size_ = Size(width, ascent + descent + leading); | 195 string_size_ = Size(width, ascent + descent + leading); |
| 193 common_baseline_ = ascent; | 196 common_baseline_ = ascent; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 | 231 |
| 229 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, | 232 void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string, |
| 230 CTFontRef font) { | 233 CTFontRef font) { |
| 231 // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/Cor eText_StringAttributes_Ref/Reference/reference.html | 234 // 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) { | 235 for (size_t i = 0; i < style_ranges().size(); ++i) { |
| 233 const StyleRange& style = style_ranges()[i]; | 236 const StyleRange& style = style_ranges()[i]; |
| 234 const CFRange range = CFRangeMake(style.range.start(), | 237 const CFRange range = CFRangeMake(style.range.start(), |
| 235 style.range.length()); | 238 style.range.length()); |
| 236 | 239 |
| 237 // Note: CFAttributedStringSetAttribute() does not appear to retain the | 240 // Note: CFAttributedStringSetAttribute() does not appear to retain the |
| 238 // values passed in, as can be verified via CFGetRetainCount(). | 241 // values passed in, as can be verified via CFGetRetainCount(). To ensure |
| 239 // | 242 // 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 | 243 |
| 244 CGColorRef foreground = gfx::SkColorToCGColorRef(style.foreground); | 244 base::mac::ScopedCFTypeRef<CGColorRef> foreground( |
| 245 gfx::CGColorCreateFromSkColor(style.foreground)); | |
| 245 CFAttributedStringSetAttribute(attr_string, range, | 246 CFAttributedStringSetAttribute(attr_string, range, |
| 246 kCTForegroundColorAttributeName, | 247 kCTForegroundColorAttributeName, |
| 247 foreground); | 248 foreground); |
| 249 CFArrayAppendValue(attributes_, foreground); | |
| 248 | 250 |
| 249 if (style.underline) { | 251 if (style.underline) { |
| 250 CTUnderlineStyle value = kCTUnderlineStyleSingle; | 252 CTUnderlineStyle value = kCTUnderlineStyleSingle; |
| 251 CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type, &value); | 253 base::mac::ScopedCFTypeRef<CFNumberRef> underline( |
| 254 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); | |
| 252 CFAttributedStringSetAttribute(attr_string, range, | 255 CFAttributedStringSetAttribute(attr_string, range, |
| 253 kCTUnderlineStyleAttributeName, | 256 kCTUnderlineStyleAttributeName, |
| 254 underline); | 257 underline); |
| 258 CFArrayAppendValue(attributes_, underline); | |
| 255 } | 259 } |
| 256 | 260 |
| 257 if (style.font_style & (Font::BOLD | Font::ITALIC)) { | 261 if (style.font_style & (Font::BOLD | Font::ITALIC)) { |
| 258 int traits = 0; | 262 int traits = 0; |
| 259 if (style.font_style & Font::BOLD) | 263 if (style.font_style & Font::BOLD) |
| 260 traits |= kCTFontBoldTrait; | 264 traits |= kCTFontBoldTrait; |
| 261 if (style.font_style & Font::ITALIC) | 265 if (style.font_style & Font::ITALIC) |
| 262 traits |= kCTFontItalicTrait; | 266 traits |= kCTFontItalicTrait; |
| 263 CTFontRef styled_font = | 267 base::mac::ScopedCFTypeRef<CTFontRef> styled_font( |
| 264 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits); | 268 CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits)); |
| 265 // TODO(asvitkine): Handle |styled_font| == NULL case better. | 269 // TODO(asvitkine): Handle |styled_font| == NULL case better. |
| 266 if (styled_font) { | 270 if (styled_font) { |
| 267 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, | 271 CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName, |
| 268 styled_font); | 272 styled_font); |
| 273 CFArrayAppendValue(attributes_, styled_font); | |
| 269 } | 274 } |
| 270 } | 275 } |
| 271 } | 276 } |
| 272 } | 277 } |
| 273 | 278 |
| 274 void RenderTextMac::ComputeRuns() { | 279 void RenderTextMac::ComputeRuns() { |
| 275 DCHECK(line_); | 280 DCHECK(line_); |
| 276 | 281 |
| 277 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_); | 282 CFArrayRef ct_runs = CTLineGetGlyphRuns(line_); |
| 278 const CFIndex ct_runs_count = CFArrayGetCount(ct_runs); | 283 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); | 365 run_origin.offset(run_width, 0); |
| 361 } | 366 } |
| 362 runs_valid_ = true; | 367 runs_valid_ = true; |
| 363 } | 368 } |
| 364 | 369 |
| 365 RenderText* RenderText::CreateInstance() { | 370 RenderText* RenderText::CreateInstance() { |
| 366 return new RenderTextMac; | 371 return new RenderTextMac; |
| 367 } | 372 } |
| 368 | 373 |
| 369 } // namespace gfx | 374 } // namespace gfx |
| OLD | NEW |