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

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

Issue 10874066: Switch RenderTextMac to use point font sizes instead of pixel font sizes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>
11 11
12 #include "base/mac/foundation_util.h" 12 #include "base/mac/foundation_util.h"
13 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
14 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
15 #include "skia/ext/skia_utils_mac.h" 15 #include "skia/ext/skia_utils_mac.h"
16 16
17 namespace {
18
19 // Returns the pixel height of |ct_font|.
20 CGFloat GetCTFontPixelSize(CTFontRef ct_font) {
21 return CTFontGetAscent(ct_font) + CTFontGetDescent(ct_font);
22 }
23
24 // Creates a CTFont with the given font name and pixel size. Ownership is
25 // transferred to the caller.
26 //
27 // Note: This code makes use of pixel sizes (rather than view coordinate sizes)
28 // because it draws to an underlying Skia canvas, which is normally pixel based.
29 CTFontRef CreateCTFontWithPixelSize(const std::string& font_name,
30 const int target_pixel_size) {
31 // Epsilon value used for comparing font sizes.
32 const CGFloat kEpsilon = 0.001;
33 // The observed pixel to points ratio for Lucida Grande on 10.6. Other fonts
34 // have other ratios and the documentation doesn't provide a guarantee that
35 // the relation is linear. So this ratio is used as a first try before
36 // falling back to the bisection method.
37 const CGFloat kPixelsToPointsRatio = 0.849088;
38
39 base::mac::ScopedCFTypeRef<CFStringRef> font_name_cf_string(
40 base::SysUTF8ToCFStringRef(font_name));
41
42 // First, try using |kPixelsToPointsRatio|.
43 CGFloat point_size = target_pixel_size * kPixelsToPointsRatio;
44 base::mac::ScopedCFTypeRef<CTFontRef> ct_font(
45 CTFontCreateWithName(font_name_cf_string, point_size, NULL));
46 CGFloat actual_pixel_size = GetCTFontPixelSize(ct_font);
47 if (std::fabs(actual_pixel_size - target_pixel_size) < kEpsilon)
48 return ct_font.release();
49
50 // |kPixelsToPointsRatio| wasn't correct. Use the bisection method to find the
51 // right size.
52
53 // First, find the initial bisection range, so that the point size that
54 // corresponds to |target_pixel_size| is between |lo| and |hi|.
55 CGFloat lo = 0;
56 CGFloat hi = point_size;
57 while (actual_pixel_size < target_pixel_size) {
58 lo = hi;
59 hi *= 2;
60 ct_font.reset(CTFontCreateWithName(font_name_cf_string, hi, NULL));
61 actual_pixel_size = GetCTFontPixelSize(ct_font);
62 }
63
64 // Now, bisect to find the right size.
65 while (lo < hi) {
66 point_size = (hi - lo) * 0.5 + lo;
67 ct_font.reset(CTFontCreateWithName(font_name_cf_string, point_size, NULL));
68 actual_pixel_size = GetCTFontPixelSize(ct_font);
69 if (std::fabs(actual_pixel_size - target_pixel_size) < kEpsilon)
70 break;
71 if (target_pixel_size > actual_pixel_size)
72 lo = point_size;
73 else
74 hi = point_size;
75 }
76
77 return ct_font.release();
78 }
79
80 } // namespace
81
82 namespace gfx { 17 namespace gfx {
83 18
84 RenderTextMac::RenderTextMac() : common_baseline_(0), runs_valid_(false) { 19 RenderTextMac::RenderTextMac() : common_baseline_(0), runs_valid_(false) {
85 } 20 }
86 21
87 RenderTextMac::~RenderTextMac() { 22 RenderTextMac::~RenderTextMac() {
88 } 23 }
89 24
90 Size RenderTextMac::GetStringSize() { 25 Size RenderTextMac::GetStringSize() {
91 EnsureLayout(); 26 EnsureLayout();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 runs_valid_ = false; 91 runs_valid_ = false;
157 } 92 }
158 93
159 void RenderTextMac::EnsureLayout() { 94 void RenderTextMac::EnsureLayout() {
160 if (line_.get()) 95 if (line_.get())
161 return; 96 return;
162 runs_.clear(); 97 runs_.clear();
163 runs_valid_ = false; 98 runs_valid_ = false;
164 99
165 const Font& font = GetFont(); 100 const Font& font = GetFont();
101 base::mac::ScopedCFTypeRef<CFStringRef> font_name_cf_string(
102 base::SysUTF8ToCFStringRef(font.GetFontName()));
166 base::mac::ScopedCFTypeRef<CTFontRef> ct_font( 103 base::mac::ScopedCFTypeRef<CTFontRef> ct_font(
167 CreateCTFontWithPixelSize(font.GetFontName(), font.GetFontSize())); 104 CTFontCreateWithName(font_name_cf_string, font.GetFontSize(), NULL));
168 105
169 const void* keys[] = { kCTFontAttributeName }; 106 const void* keys[] = { kCTFontAttributeName };
170 const void* values[] = { ct_font }; 107 const void* values[] = { ct_font };
171 base::mac::ScopedCFTypeRef<CFDictionaryRef> attributes( 108 base::mac::ScopedCFTypeRef<CFDictionaryRef> attributes(
172 CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL, 109 CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL,
173 &kCFTypeDictionaryValueCallBacks)); 110 &kCFTypeDictionaryValueCallBacks));
174 111
175 base::mac::ScopedCFTypeRef<CFStringRef> cf_text( 112 base::mac::ScopedCFTypeRef<CFStringRef> cf_text(
176 base::SysUTF16ToCFStringRef(text())); 113 base::SysUTF16ToCFStringRef(text()));
177 base::mac::ScopedCFTypeRef<CFAttributedStringRef> attr_text( 114 base::mac::ScopedCFTypeRef<CFAttributedStringRef> attr_text(
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 274
338 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle 275 // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle
339 // this better. 276 // this better.
340 CFDictionaryRef attributes = CTRunGetAttributes(ct_run); 277 CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
341 CTFontRef ct_font = 278 CTFontRef ct_font =
342 base::mac::GetValueFromDictionary<CTFontRef>(attributes, 279 base::mac::GetValueFromDictionary<CTFontRef>(attributes,
343 kCTFontAttributeName); 280 kCTFontAttributeName);
344 base::mac::ScopedCFTypeRef<CFStringRef> font_name_ref( 281 base::mac::ScopedCFTypeRef<CFStringRef> font_name_ref(
345 CTFontCopyFamilyName(ct_font)); 282 CTFontCopyFamilyName(ct_font));
346 run->font_name = base::SysCFStringRefToUTF8(font_name_ref); 283 run->font_name = base::SysCFStringRefToUTF8(font_name_ref);
347 run->text_size = GetCTFontPixelSize(ct_font); 284 run->text_size = CTFontGetSize(ct_font);
348 285
349 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font); 286 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ct_font);
350 if (traits & kCTFontBoldTrait) 287 if (traits & kCTFontBoldTrait)
351 run->font_style |= Font::BOLD; 288 run->font_style |= Font::BOLD;
352 if (traits & kCTFontItalicTrait) 289 if (traits & kCTFontItalicTrait)
353 run->font_style |= Font::ITALIC; 290 run->font_style |= Font::ITALIC;
354 291
355 const CGColorRef foreground = 292 const CGColorRef foreground =
356 base::mac::GetValueFromDictionary<CGColorRef>( 293 base::mac::GetValueFromDictionary<CGColorRef>(
357 attributes, kCTForegroundColorAttributeName); 294 attributes, kCTForegroundColorAttributeName);
(...skipping 10 matching lines...) Expand all
368 run_origin.offset(run_width, 0); 305 run_origin.offset(run_width, 0);
369 } 306 }
370 runs_valid_ = true; 307 runs_valid_ = true;
371 } 308 }
372 309
373 RenderText* RenderText::CreateInstance() { 310 RenderText* RenderText::CreateInstance() {
374 return new RenderTextMac; 311 return new RenderTextMac;
375 } 312 }
376 313
377 } // namespace gfx 314 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698