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 "core/CSSValueKeywords.h" 30 #include "platform/fonts/FontDescription.h" 31 #include "platform/win/HWndDC.h" 32 #include "platform/win/SystemInfo.h" 33 #include "wtf/text/WTFString.h" 34 #include <windows.h> 35 36 #define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \ 37 offsetof(structName, member) + \ 38 (sizeof static_cast<structName*>(0)->member) 39 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \ 40 SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) 41 42 namespace blink { 43 44 static FontDescription& smallSystemFont() 45 { 46 DEFINE_STATIC_LOCAL(FontDescription, font, ()); 47 return font; 48 } 49 50 static FontDescription& menuFont() 51 { 52 DEFINE_STATIC_LOCAL(FontDescription, font, ()); 53 return font; 54 } 55 56 static FontDescription& labelFont() 57 { 58 DEFINE_STATIC_LOCAL(FontDescription, font, ()); 59 return font; 60 } 61 62 // Converts |points| to pixels. One point is 1/72 of an inch. 63 static float pointsToPixels(float points) 64 { 65 static float pixelsPerInch = 0.0f; 66 if (!pixelsPerInch) { 67 HWndDC hdc(0); // What about printing? Is this the right DC? 68 if (hdc) // Can this ever actually be 0? 69 pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY); 70 else 71 pixelsPerInch = 96.0f; 72 } 73 74 static const float pointsPerInch = 72.0f; 75 return points / pointsPerInch * pixelsPerInch; 76 } 77 78 static void getNonClientMetrics(NONCLIENTMETRICS* metrics) 79 { 80 static UINT size = isWindowsVistaOrGreater() ? 81 sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA; 82 metrics->cbSize = size; 83 bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, size, metrics, 0); 84 ASSERT(success); 85 } 86 87 // Return the height of system font |font| in pixels. We use this size by 88 // default for some non-form-control elements. 89 static float systemFontSize(const LOGFONT& font) 90 { 91 float size = -font.lfHeight; 92 if (size < 0) { 93 HFONT hFont = CreateFontIndirect(&font); 94 if (hFont) { 95 HWndDC hdc(0); // What about printing? Is this the right DC? 96 if (hdc) { 97 HGDIOBJ hObject = SelectObject(hdc, hFont); 98 TEXTMETRIC tm; 99 GetTextMetrics(hdc, &tm); 100 SelectObject(hdc, hObject); 101 size = tm.tmAscent; 102 } 103 DeleteObject(hFont); 104 } 105 } 106 107 // The "codepage 936" bit here is from Gecko; apparently this helps make 108 // fonts more legible in Simplified Chinese where the default font size is 109 // too small. 110 // 111 // FIXME: http://b/1119883 Since this is only used for "small caption", 112 // "menu", and "status bar" objects, I'm not sure how much this even 113 // matters. Plus the Gecko patch went in back in 2002, and maybe this 114 // isn't even relevant anymore. We should investigate whether this should 115 // be removed, or perhaps broadened to be "any CJK locale". 116 // 117 return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size; 118 } 119 120 // static 121 void RenderThemeChromiumFontProvider::systemFont(CSSValueID valueID, FontDescription& fontDescription) 122 { 123 // This logic owes much to RenderThemeSafari.cpp. 124 FontDescription* cachedDesc = 0; 125 AtomicString faceName; 126 float fontSize = 0; 127 switch (valueID) { 128 case CSSValueSmallCaption: 129 cachedDesc = &smallSystemFont(); 130 if (!smallSystemFont().isAbsoluteSize()) { 131 NONCLIENTMETRICS metrics; 132 getNonClientMetrics(&metrics); 133 faceName = AtomicString(metrics.lfSmCaptionFont.lfFaceName, wcslen(metrics.lfSmCaptionFont.lfFaceName)); 134 fontSize = systemFontSize(metrics.lfSmCaptionFont); 135 } 136 break; 137 case CSSValueMenu: 138 cachedDesc = &menuFont(); 139 if (!menuFont().isAbsoluteSize()) { 140 NONCLIENTMETRICS metrics; 141 getNonClientMetrics(&metrics); 142 faceName = AtomicString(metrics.lfMenuFont.lfFaceName, wcslen(metrics.lfMenuFont.lfFaceName)); 143 fontSize = systemFontSize(metrics.lfMenuFont); 144 } 145 break; 146 case CSSValueStatusBar: 147 cachedDesc = &labelFont(); 148 if (!labelFont().isAbsoluteSize()) { 149 NONCLIENTMETRICS metrics; 150 getNonClientMetrics(&metrics); 151 faceName = metrics.lfStatusFont.lfFaceName; 152 fontSize = systemFontSize(metrics.lfStatusFont); 153 } 154 break; 155 case CSSValueWebkitMiniControl: 156 case CSSValueWebkitSmallControl: 157 case CSSValueWebkitControl: 158 faceName = defaultGUIFont(); 159 // Why 2 points smaller? Because that's what Gecko does. 160 fontSize = s_defaultFontSize - pointsToPixels(2); 161 break; 162 default: 163 faceName = defaultGUIFont(); 164 fontSize = s_defaultFontSize; 165 break; 166 } 167 168 if (!cachedDesc) 169 cachedDesc = &fontDescription; 170 171 if (fontSize) { 172 cachedDesc->firstFamily().setFamily(faceName); 173 cachedDesc->setIsAbsoluteSize(true); 174 cachedDesc->setGenericFamily(FontDescription::NoFamily); 175 cachedDesc->setSpecifiedSize(fontSize); 176 cachedDesc->setWeight(FontWeightNormal); 177 cachedDesc->setStyle(FontStyleNormal); 178 } 179 fontDescription = *cachedDesc; 180 } 181 182 // static 183 void RenderThemeChromiumFontProvider::setDefaultFontSize(int fontSize) 184 { 185 s_defaultFontSize = static_cast<float>(fontSize); 186 187 // Reset cached fonts. 188 smallSystemFont() = menuFont() = labelFont() = FontDescription(); 189 } 190 191 } // namespace blink 192