1/*
2 * Copyright (C) 2008 Apple 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 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "SimpleFontData.h"
31
32#include <windows.h>
33
34#include "Font.h"
35#include "FontCache.h"
36#include "FontDescription.h"
37#include "HWndDC.h"
38#include <cairo.h>
39#include <cairo-win32.h>
40#include <mlang.h>
41#include <wtf/MathExtras.h>
42
43namespace WebCore {
44
45void SimpleFontData::platformInit()
46{
47    m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
48    m_scriptCache = 0;
49    m_scriptFontProperties = 0;
50    m_isSystemFont = false;
51
52    if (m_platformData.useGDI())
53       return initGDIFont();
54
55    if (!m_platformData.size()) {
56        m_fontMetrics.reset();
57        m_avgCharWidth = 0;
58        m_maxCharWidth = 0;
59        m_isSystemFont = false;
60        m_scriptCache = 0;
61        m_scriptFontProperties = 0;
62        return;
63    }
64
65    HWndDC dc(0);
66    SaveDC(dc);
67
68    cairo_scaled_font_t* scaledFont = m_platformData.scaledFont();
69    const double metricsMultiplier = cairo_win32_scaled_font_get_metrics_factor(scaledFont) * m_platformData.size();
70
71    cairo_win32_scaled_font_select_font(scaledFont, dc);
72
73    TEXTMETRIC textMetrics;
74    GetTextMetrics(dc, &textMetrics);
75    float ascent = textMetrics.tmAscent * metricsMultiplier;
76    float descent = textMetrics.tmDescent * metricsMultiplier;
77    float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
78    float lineGap = textMetrics.tmExternalLeading * metricsMultiplier;
79
80    int faceLength = ::GetTextFace(dc, 0, 0);
81    Vector<WCHAR> faceName(faceLength);
82    ::GetTextFace(dc, faceLength, faceName.data());
83    m_isSystemFont = !wcscmp(faceName.data(), L"Lucida Grande");
84
85    ascent = ascentConsideringMacAscentHack(faceName.data(), ascent, descent);
86
87    m_fontMetrics.setAscent(ascent);
88    m_fontMetrics.setDescent(descent);
89    m_fontMetrics.setLineGap(lineGap);
90    m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
91    m_avgCharWidth = textMetrics.tmAveCharWidth * metricsMultiplier;
92    m_maxCharWidth = textMetrics.tmMaxCharWidth * metricsMultiplier;
93
94    cairo_text_extents_t extents;
95    cairo_scaled_font_text_extents(scaledFont, "x", &extents);
96    xHeight = -extents.y_bearing;
97
98    m_fontMetrics.setXHeight(xHeight);
99    cairo_win32_scaled_font_done_font(scaledFont);
100
101    m_scriptCache = 0;
102    m_scriptFontProperties = 0;
103
104    RestoreDC(dc, -1);
105}
106
107FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
108{
109    if (m_platformData.useGDI())
110        return boundsForGDIGlyph(glyph);
111    //FIXME: Implement this
112    return FloatRect();
113}
114
115float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
116{
117    if (m_platformData.useGDI())
118       return widthForGDIGlyph(glyph);
119
120    if (!m_platformData.size())
121        return 0;
122
123    HWndDC dc(0);
124    SaveDC(dc);
125
126    cairo_scaled_font_t* scaledFont = m_platformData.scaledFont();
127    cairo_win32_scaled_font_select_font(scaledFont, dc);
128
129    int width;
130    GetCharWidthI(dc, glyph, 1, 0, &width);
131
132    cairo_win32_scaled_font_done_font(scaledFont);
133
134    RestoreDC(dc, -1);
135
136    const double metricsMultiplier = cairo_win32_scaled_font_get_metrics_factor(scaledFont) * m_platformData.size();
137    return width * metricsMultiplier;
138}
139
140}
141