1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2012 Google Inc.  All rights reserved.
3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met:
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderThemeChromiumFontProvider.h"
28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/CSSValueKeywords.h"
30f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/fonts/FontDescription.h"
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/win/HWndDC.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/win/SystemInfo.h"
3302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/text/WTFString.h"
345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include <windows.h>
35926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    offsetof(structName, member) + \
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    (sizeof static_cast<structName*>(0)->member)
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define NONCLIENTMETRICS_SIZE_PRE_VISTA \
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static FontDescription& smallSystemFont()
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DEFINE_STATIC_LOCAL(FontDescription, font, ());
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return font;
48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static FontDescription& menuFont()
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DEFINE_STATIC_LOCAL(FontDescription, font, ());
53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return font;
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static FontDescription& labelFont()
57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DEFINE_STATIC_LOCAL(FontDescription, font, ());
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return font;
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Converts |points| to pixels. One point is 1/72 of an inch.
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static float pointsToPixels(float points)
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    static float pixelsPerInch = 0.0f;
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!pixelsPerInch) {
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        HWndDC hdc(0); // What about printing? Is this the right DC?
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (hdc) // Can this ever actually be 0?
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        else
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            pixelsPerInch = 96.0f;
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    static const float pointsPerInch = 72.0f;
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return points / pointsPerInch * pixelsPerInch;
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static void getNonClientMetrics(NONCLIENTMETRICS* metrics)
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    static UINT size = isWindowsVistaOrGreater() ?
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    metrics->cbSize = size;
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, size, metrics, 0);
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(success);
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Return the height of system font |font| in pixels. We use this size by
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// default for some non-form-control elements.
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static float systemFontSize(const LOGFONT& font)
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float size = -font.lfHeight;
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (size < 0) {
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        HFONT hFont = CreateFontIndirect(&font);
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (hFont) {
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            HWndDC hdc(0); // What about printing? Is this the right DC?
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (hdc) {
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                HGDIOBJ hObject = SelectObject(hdc, hFont);
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                TEXTMETRIC tm;
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                GetTextMetrics(hdc, &tm);
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                SelectObject(hdc, hObject);
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                size = tm.tmAscent;
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            DeleteObject(hFont);
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // The "codepage 936" bit here is from Gecko; apparently this helps make
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // fonts more legible in Simplified Chinese where the default font size is
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // too small.
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    //
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // FIXME: http://b/1119883 Since this is only used for "small caption",
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // "menu", and "status bar" objects, I'm not sure how much this even
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // matters. Plus the Gecko patch went in back in 2002, and maybe this
114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // isn't even relevant anymore. We should investigate whether this should
115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // be removed, or perhaps broadened to be "any CJK locale".
116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    //
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size;
118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// static
1215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void RenderThemeChromiumFontProvider::systemFont(CSSValueID valueID, FontDescription& fontDescription)
122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // This logic owes much to RenderThemeSafari.cpp.
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    FontDescription* cachedDesc = 0;
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    AtomicString faceName;
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float fontSize = 0;
1275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    switch (valueID) {
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case CSSValueSmallCaption:
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc = &smallSystemFont();
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!smallSystemFont().isAbsoluteSize()) {
131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            NONCLIENTMETRICS metrics;
132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            getNonClientMetrics(&metrics);
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            faceName = AtomicString(metrics.lfSmCaptionFont.lfFaceName, wcslen(metrics.lfSmCaptionFont.lfFaceName));
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            fontSize = systemFontSize(metrics.lfSmCaptionFont);
135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case CSSValueMenu:
138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc = &menuFont();
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!menuFont().isAbsoluteSize()) {
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            NONCLIENTMETRICS metrics;
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            getNonClientMetrics(&metrics);
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            faceName = AtomicString(metrics.lfMenuFont.lfFaceName, wcslen(metrics.lfMenuFont.lfFaceName));
143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            fontSize = systemFontSize(metrics.lfMenuFont);
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case CSSValueStatusBar:
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc = &labelFont();
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!labelFont().isAbsoluteSize()) {
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            NONCLIENTMETRICS metrics;
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            getNonClientMetrics(&metrics);
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            faceName = metrics.lfStatusFont.lfFaceName;
152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            fontSize = systemFontSize(metrics.lfStatusFont);
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case CSSValueWebkitMiniControl:
156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case CSSValueWebkitSmallControl:
157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case CSSValueWebkitControl:
158926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        faceName = defaultGUIFont();
159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Why 2 points smaller? Because that's what Gecko does.
160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fontSize = s_defaultFontSize - pointsToPixels(2);
161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    default:
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        faceName = defaultGUIFont();
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fontSize = s_defaultFontSize;
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        break;
166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!cachedDesc)
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc = &fontDescription;
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (fontSize) {
172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc->firstFamily().setFamily(faceName);
173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc->setIsAbsoluteSize(true);
174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc->setGenericFamily(FontDescription::NoFamily);
175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc->setSpecifiedSize(fontSize);
176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cachedDesc->setWeight(FontWeightNormal);
177a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        cachedDesc->setStyle(FontStyleNormal);
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    fontDescription = *cachedDesc;
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// static
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderThemeChromiumFontProvider::setDefaultFontSize(int fontSize)
184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    s_defaultFontSize = static_cast<float>(fontSize);
186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Reset cached fonts.
188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    smallSystemFont() = menuFont() = labelFont() = FontDescription();
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
191c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
192