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

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

Issue 10228009: Fix CJK font linking size on Windows XP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 | « ui/gfx/platform_font_win.h ('k') | ui/gfx/platform_font_win_unittest.cc » ('j') | 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/platform_font_win.h" 5 #include "ui/gfx/platform_font_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <math.h> 8 #include <math.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <string> 11 #include <string>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/sys_string_conversions.h" 15 #include "base/sys_string_conversions.h"
16 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
17 #include "base/win/scoped_hdc.h" 17 #include "base/win/scoped_hdc.h"
18 #include "base/win/scoped_select_object.h" 18 #include "base/win/scoped_select_object.h"
19 #include "base/win/win_util.h" 19 #include "base/win/win_util.h"
20 #include "ui/base/win/scoped_set_map_mode.h" 20 #include "ui/base/win/scoped_set_map_mode.h"
21 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/font.h" 22 #include "ui/gfx/font.h"
23 23
24 namespace { 24 namespace {
25 25
26 // If the tmWeight field of a TEXTMETRIC structure has a value >= this, the 26 // If the tmWeight field of a TEXTMETRIC structure has a value >= this, the
27 // font is bold. 27 // font is bold.
28 const int kTextMetricWeightBold = 700; 28 const int kTextMetricWeightBold = 700;
29 29
30 // Returns the minimum font size, using the minimum size callback, if set.
31 int GetMinimumFontSize() {
32 int min_font_size = 0;
33 if (gfx::PlatformFontWin::get_minimum_font_size_callback)
34 min_font_size = gfx::PlatformFontWin::get_minimum_font_size_callback();
35 return min_font_size;
36 }
37
30 // Returns either minimum font allowed for a current locale or 38 // Returns either minimum font allowed for a current locale or
31 // lf_height + size_delta value. 39 // lf_height + size_delta value.
32 int AdjustFontSize(int lf_height, int size_delta) { 40 int AdjustFontSize(int lf_height, int size_delta) {
33 if (lf_height < 0) { 41 if (lf_height < 0) {
34 lf_height -= size_delta; 42 lf_height -= size_delta;
35 } else { 43 } else {
36 lf_height += size_delta; 44 lf_height += size_delta;
37 } 45 }
38 int min_font_size = 0; 46 const int min_font_size = GetMinimumFontSize();
39 if (gfx::PlatformFontWin::get_minimum_font_size_callback)
40 min_font_size = gfx::PlatformFontWin::get_minimum_font_size_callback();
41 // Make sure lf_height is not smaller than allowed min font size for current 47 // Make sure lf_height is not smaller than allowed min font size for current
42 // locale. 48 // locale.
43 if (abs(lf_height) < min_font_size) { 49 if (abs(lf_height) < min_font_size) {
44 return lf_height < 0 ? -min_font_size : min_font_size; 50 return lf_height < 0 ? -min_font_size : min_font_size;
45 } else { 51 } else {
46 return lf_height; 52 return lf_height;
47 } 53 }
48 } 54 }
49 55
56 // Sets style properties on |font_info| based on |font_style|.
57 void SetLogFontStyle(int font_style, LOGFONT* font_info) {
58 font_info->lfUnderline = (font_style & gfx::Font::UNDERLINED) != 0;
59 font_info->lfItalic = (font_style & gfx::Font::ITALIC) != 0;
60 font_info->lfWeight = (font_style & gfx::Font::BOLD) ? FW_BOLD : FW_NORMAL;
61 }
62
50 } // namespace 63 } // namespace
51 64
52 namespace gfx { 65 namespace gfx {
53 66
54 // static 67 // static
55 PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_; 68 PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_;
56 69
57 // static 70 // static
58 PlatformFontWin::AdjustFontCallback 71 PlatformFontWin::AdjustFontCallback
59 PlatformFontWin::adjust_font_callback = NULL; 72 PlatformFontWin::adjust_font_callback = NULL;
60 PlatformFontWin::GetMinimumFontSizeCallback 73 PlatformFontWin::GetMinimumFontSizeCallback
61 PlatformFontWin::get_minimum_font_size_callback = NULL; 74 PlatformFontWin::get_minimum_font_size_callback = NULL;
62 75
63 //////////////////////////////////////////////////////////////////////////////// 76 ////////////////////////////////////////////////////////////////////////////////
64 // PlatformFontWin, public 77 // PlatformFontWin, public
65 78
66 PlatformFontWin::PlatformFontWin() : font_ref_(GetBaseFontRef()) { 79 PlatformFontWin::PlatformFontWin() : font_ref_(GetBaseFontRef()) {
67 } 80 }
68 81
69 PlatformFontWin::PlatformFontWin(NativeFont native_font) { 82 PlatformFontWin::PlatformFontWin(NativeFont native_font) {
70 InitWithCopyOfHFONT(native_font); 83 InitWithCopyOfHFONT(native_font);
71 } 84 }
72 85
73 PlatformFontWin::PlatformFontWin(const std::string& font_name, 86 PlatformFontWin::PlatformFontWin(const std::string& font_name,
74 int font_size) { 87 int font_size) {
75 InitWithFontNameAndSize(font_name, font_size); 88 InitWithFontNameAndSize(font_name, font_size);
76 } 89 }
77 90
91 Font PlatformFontWin::DeriveFontWithHeight(int height, int style) {
92 DCHECK_GE(height, 0);
93 if (GetHeight() == height && GetStyle() == style)
94 return Font(this);
95
96 // CreateFontIndirect() doesn't return the largest size for the given height
97 // when decreasing the height. Iterate to find it.
98 if (GetHeight() > height) {
99 const int min_font_size = GetMinimumFontSize();
100 Font font = DeriveFont(-1, style);
101 while (font.GetHeight() > height && font.GetFontSize() != min_font_size) {
msw 2012/04/30 19:30:23 optionally: font.GetFontSize() >= min_font_size ?
102 font = font.DeriveFont(-1, style);
103 }
104 return font;
105 }
106
107 LOGFONT font_info;
108 GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info);
109 font_info.lfHeight = height;
110 SetLogFontStyle(style, &font_info);
111
112 HFONT hfont = CreateFontIndirect(&font_info);
113 return Font(new PlatformFontWin(CreateHFontRef(hfont)));
114 }
115
78 //////////////////////////////////////////////////////////////////////////////// 116 ////////////////////////////////////////////////////////////////////////////////
79 // PlatformFontWin, PlatformFont implementation: 117 // PlatformFontWin, PlatformFont implementation:
80 118
81 Font PlatformFontWin::DeriveFont(int size_delta, int style) const { 119 Font PlatformFontWin::DeriveFont(int size_delta, int style) const {
82 LOGFONT font_info; 120 LOGFONT font_info;
83 GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info); 121 GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info);
84 font_info.lfHeight = AdjustFontSize(font_info.lfHeight, size_delta); 122 const int requested_font_size = font_ref_->requested_font_size();
85 font_info.lfUnderline = 123 font_info.lfHeight = AdjustFontSize(-requested_font_size, size_delta);
86 ((style & gfx::Font::UNDERLINED) == gfx::Font::UNDERLINED); 124 SetLogFontStyle(style, &font_info);
87 font_info.lfItalic = ((style & gfx::Font::ITALIC) == gfx::Font::ITALIC);
88 font_info.lfWeight = (style & gfx::Font::BOLD) ? FW_BOLD : FW_NORMAL;
89 125
90 HFONT hfont = CreateFontIndirect(&font_info); 126 HFONT hfont = CreateFontIndirect(&font_info);
91 return Font(new PlatformFontWin(CreateHFontRef(hfont))); 127 return Font(new PlatformFontWin(CreateHFontRef(hfont)));
92 } 128 }
93 129
94 int PlatformFontWin::GetHeight() const { 130 int PlatformFontWin::GetHeight() const {
95 return font_ref_->height(); 131 return font_ref_->height();
96 } 132 }
97 133
98 int PlatformFontWin::GetBaseline() const { 134 int PlatformFontWin::GetBaseline() const {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { 220 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) {
185 TEXTMETRIC font_metrics; 221 TEXTMETRIC font_metrics;
186 222
187 { 223 {
188 base::win::ScopedGetDC screen_dc(NULL); 224 base::win::ScopedGetDC screen_dc(NULL);
189 base::win::ScopedSelectObject font(screen_dc, font); 225 base::win::ScopedSelectObject font(screen_dc, font);
190 ui::ScopedSetMapMode mode(screen_dc, MM_TEXT); 226 ui::ScopedSetMapMode mode(screen_dc, MM_TEXT);
191 GetTextMetrics(screen_dc, &font_metrics); 227 GetTextMetrics(screen_dc, &font_metrics);
192 } 228 }
193 229
194 const int height = std::max(1, static_cast<int>(font_metrics.tmHeight)); 230 const int height = std::max<int>(1, font_metrics.tmHeight);
195 const int baseline = std::max(1, static_cast<int>(font_metrics.tmAscent)); 231 const int baseline = std::max<int>(1, font_metrics.tmAscent);
196 const int ave_char_width = 232 const int ave_char_width = std::max<int>(1, font_metrics.tmAveCharWidth);
197 std::max(1, static_cast<int>(font_metrics.tmAveCharWidth)); 233 const int font_size =
234 std::max<int>(1, font_metrics.tmHeight - font_metrics.tmInternalLeading);
198 int style = 0; 235 int style = 0;
199 if (font_metrics.tmItalic) 236 if (font_metrics.tmItalic)
200 style |= Font::ITALIC; 237 style |= Font::ITALIC;
201 if (font_metrics.tmUnderlined) 238 if (font_metrics.tmUnderlined)
202 style |= Font::UNDERLINED; 239 style |= Font::UNDERLINED;
203 if (font_metrics.tmWeight >= kTextMetricWeightBold) 240 if (font_metrics.tmWeight >= kTextMetricWeightBold)
204 style |= Font::BOLD; 241 style |= Font::BOLD;
205 242
206 return new HFontRef(font, height, baseline, ave_char_width, style); 243 return new HFontRef(font, font_size, height, baseline, ave_char_width, style);
207 } 244 }
208 245
209 PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { 246 PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) {
210 } 247 }
211 248
212 //////////////////////////////////////////////////////////////////////////////// 249 ////////////////////////////////////////////////////////////////////////////////
213 // PlatformFontWin::HFontRef: 250 // PlatformFontWin::HFontRef:
214 251
215 PlatformFontWin::HFontRef::HFontRef(HFONT hfont, 252 PlatformFontWin::HFontRef::HFontRef(HFONT hfont,
253 int font_size,
216 int height, 254 int height,
217 int baseline, 255 int baseline,
218 int ave_char_width, 256 int ave_char_width,
219 int style) 257 int style)
220 : hfont_(hfont), 258 : hfont_(hfont),
259 font_size_(font_size),
221 height_(height), 260 height_(height),
222 baseline_(baseline), 261 baseline_(baseline),
223 ave_char_width_(ave_char_width), 262 ave_char_width_(ave_char_width),
224 style_(style), 263 style_(style),
225 dlu_base_x_(-1) { 264 dlu_base_x_(-1),
265 requested_font_size_(font_size) {
226 DLOG_ASSERT(hfont); 266 DLOG_ASSERT(hfont);
227 267
228 LOGFONT font_info; 268 LOGFONT font_info;
229 GetObject(hfont_, sizeof(LOGFONT), &font_info); 269 GetObject(hfont_, sizeof(LOGFONT), &font_info);
230 font_name_ = UTF16ToUTF8(string16(font_info.lfFaceName)); 270 font_name_ = UTF16ToUTF8(string16(font_info.lfFaceName));
231 DCHECK_LT(font_info.lfHeight, 0); 271 if (font_info.lfHeight < 0)
232 font_size_ = -font_info.lfHeight; 272 requested_font_size_ = -font_info.lfHeight;
233 } 273 }
234 274
235 int PlatformFontWin::HFontRef::GetDluBaseX() { 275 int PlatformFontWin::HFontRef::GetDluBaseX() {
236 if (dlu_base_x_ != -1) 276 if (dlu_base_x_ != -1)
237 return dlu_base_x_; 277 return dlu_base_x_;
238 278
239 base::win::ScopedGetDC screen_dc(NULL); 279 base::win::ScopedGetDC screen_dc(NULL);
240 base::win::ScopedSelectObject font(screen_dc, hfont_); 280 base::win::ScopedSelectObject font(screen_dc, hfont_);
241 ui::ScopedSetMapMode mode(screen_dc, MM_TEXT); 281 ui::ScopedSetMapMode mode(screen_dc, MM_TEXT);
242 282
(...skipping 26 matching lines...) Expand all
269 return new PlatformFontWin(native_font); 309 return new PlatformFontWin(native_font);
270 } 310 }
271 311
272 // static 312 // static
273 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, 313 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
274 int font_size) { 314 int font_size) {
275 return new PlatformFontWin(font_name, font_size); 315 return new PlatformFontWin(font_name, font_size);
276 } 316 }
277 317
278 } // namespace gfx 318 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/platform_font_win.h ('k') | ui/gfx/platform_font_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698