Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / RenderThemeChromiumFontProviderWin.cpp
1 /*
2  * Copyright (C) 2012 Google Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "core/rendering/RenderThemeChromiumFontProvider.h"
28
29 #include <windows.h>
30
31 #include "CSSValueKeywords.h"
32 #include "platform/fonts/FontDescription.h"
33 #include "platform/win/HWndDC.h"
34 #include "platform/win/SystemInfo.h"
35 #include "wtf/text/WTFString.h"
36
37 #define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \
38     offsetof(structName, member) + \
39     (sizeof static_cast<structName*>(0)->member)
40 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \
41     SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
42
43 namespace WebCore {
44
45 static FontDescription& smallSystemFont()
46 {
47     DEFINE_STATIC_LOCAL(FontDescription, font, ());
48     return font;
49 }
50
51 static FontDescription& menuFont()
52 {
53     DEFINE_STATIC_LOCAL(FontDescription, font, ());
54     return font;
55 }
56
57 static FontDescription& labelFont()
58 {
59     DEFINE_STATIC_LOCAL(FontDescription, font, ());
60     return font;
61 }
62
63 // Converts |points| to pixels. One point is 1/72 of an inch.
64 static float pointsToPixels(float points)
65 {
66     static float pixelsPerInch = 0.0f;
67     if (!pixelsPerInch) {
68         HWndDC hdc(0); // What about printing? Is this the right DC?
69         if (hdc) // Can this ever actually be 0?
70             pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
71         else
72             pixelsPerInch = 96.0f;
73     }
74
75     static const float pointsPerInch = 72.0f;
76     return points / pointsPerInch * pixelsPerInch;
77 }
78
79 static void getNonClientMetrics(NONCLIENTMETRICS* metrics)
80 {
81     static UINT size = isWindowsVistaOrGreater() ?
82         sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
83     metrics->cbSize = size;
84     bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, size, metrics, 0);
85     ASSERT(success);
86 }
87
88 // Return the height of system font |font| in pixels. We use this size by
89 // default for some non-form-control elements.
90 static float systemFontSize(const LOGFONT& font)
91 {
92     float size = -font.lfHeight;
93     if (size < 0) {
94         HFONT hFont = CreateFontIndirect(&font);
95         if (hFont) {
96             HWndDC hdc(0); // What about printing? Is this the right DC?
97             if (hdc) {
98                 HGDIOBJ hObject = SelectObject(hdc, hFont);
99                 TEXTMETRIC tm;
100                 GetTextMetrics(hdc, &tm);
101                 SelectObject(hdc, hObject);
102                 size = tm.tmAscent;
103             }
104             DeleteObject(hFont);
105         }
106     }
107
108     // The "codepage 936" bit here is from Gecko; apparently this helps make
109     // fonts more legible in Simplified Chinese where the default font size is
110     // too small.
111     //
112     // FIXME: http://b/1119883 Since this is only used for "small caption",
113     // "menu", and "status bar" objects, I'm not sure how much this even
114     // matters. Plus the Gecko patch went in back in 2002, and maybe this
115     // isn't even relevant anymore. We should investigate whether this should
116     // be removed, or perhaps broadened to be "any CJK locale".
117     //
118     return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size;
119 }
120
121 // static
122 void RenderThemeChromiumFontProvider::systemFont(CSSValueID valueID, FontDescription& fontDescription)
123 {
124     // This logic owes much to RenderThemeSafari.cpp.
125     FontDescription* cachedDesc = 0;
126     AtomicString faceName;
127     float fontSize = 0;
128     switch (valueID) {
129     case CSSValueSmallCaption:
130         cachedDesc = &smallSystemFont();
131         if (!smallSystemFont().isAbsoluteSize()) {
132             NONCLIENTMETRICS metrics;
133             getNonClientMetrics(&metrics);
134             faceName = AtomicString(metrics.lfSmCaptionFont.lfFaceName, wcslen(metrics.lfSmCaptionFont.lfFaceName));
135             fontSize = systemFontSize(metrics.lfSmCaptionFont);
136         }
137         break;
138     case CSSValueMenu:
139         cachedDesc = &menuFont();
140         if (!menuFont().isAbsoluteSize()) {
141             NONCLIENTMETRICS metrics;
142             getNonClientMetrics(&metrics);
143             faceName = AtomicString(metrics.lfMenuFont.lfFaceName, wcslen(metrics.lfMenuFont.lfFaceName));
144             fontSize = systemFontSize(metrics.lfMenuFont);
145         }
146         break;
147     case CSSValueStatusBar:
148         cachedDesc = &labelFont();
149         if (!labelFont().isAbsoluteSize()) {
150             NONCLIENTMETRICS metrics;
151             getNonClientMetrics(&metrics);
152             faceName = metrics.lfStatusFont.lfFaceName;
153             fontSize = systemFontSize(metrics.lfStatusFont);
154         }
155         break;
156     case CSSValueWebkitMiniControl:
157     case CSSValueWebkitSmallControl:
158     case CSSValueWebkitControl:
159         faceName = defaultGUIFont();
160         // Why 2 points smaller? Because that's what Gecko does.
161         fontSize = s_defaultFontSize - pointsToPixels(2);
162         break;
163     default:
164         faceName = defaultGUIFont();
165         fontSize = s_defaultFontSize;
166         break;
167     }
168
169     if (!cachedDesc)
170         cachedDesc = &fontDescription;
171
172     if (fontSize) {
173         cachedDesc->firstFamily().setFamily(faceName);
174         cachedDesc->setIsAbsoluteSize(true);
175         cachedDesc->setGenericFamily(FontDescription::NoFamily);
176         cachedDesc->setSpecifiedSize(fontSize);
177         cachedDesc->setWeight(FontWeightNormal);
178         cachedDesc->setStyle(false);
179     }
180     fontDescription = *cachedDesc;
181 }
182
183 // static
184 void RenderThemeChromiumFontProvider::setDefaultFontSize(int fontSize)
185 {
186     s_defaultFontSize = static_cast<float>(fontSize);
187
188     // Reset cached fonts.
189     smallSystemFont() = menuFont() = labelFont() = FontDescription();
190 }
191
192 } // namespace WebCore