1/*
2 * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
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 "FontPlatformData.h"
28
29#include "FontDescription.h"
30#include "PlatformString.h"
31#include <wx/defs.h>
32#include <wx/gdicmn.h>
33#include <wx/font.h>
34
35namespace WebCore {
36
37static wxFontFamily fontFamilyToWxFontFamily(const int family)
38{
39    switch (family) {
40        case FontDescription::StandardFamily:
41            return wxFONTFAMILY_DEFAULT;
42        case FontDescription::SerifFamily:
43            return wxFONTFAMILY_ROMAN;
44        case FontDescription::SansSerifFamily:
45            return wxFONTFAMILY_MODERN;
46        case FontDescription::MonospaceFamily:
47            return wxFONTFAMILY_TELETYPE; // TODO: Check these are equivalent
48        case FontDescription::CursiveFamily:
49            return wxFONTFAMILY_SCRIPT;
50        case FontDescription::FantasyFamily:
51            return wxFONTFAMILY_DECORATIVE;
52        default:
53            return wxFONTFAMILY_DEFAULT;
54    }
55}
56
57static wxFontWeight fontWeightToWxFontWeight(FontWeight weight)
58{
59    if (weight >= FontWeight600)
60        return wxFONTWEIGHT_BOLD;
61
62    if (weight <= FontWeight300)
63        return wxFONTWEIGHT_LIGHT;
64
65    return wxFONTWEIGHT_NORMAL;
66}
67
68static int italicToWxFontStyle(bool isItalic)
69{
70    if (isItalic)
71        return wxFONTSTYLE_ITALIC;
72
73    return wxFONTSTYLE_NORMAL;
74}
75
76FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicString& family)
77{
78// NB: The Windows wxFont constructor has two forms, one taking a wxSize (with pixels)
79// and one taking an int (points). When points are used, Windows calculates
80// a pixel size using an algorithm which causes the size to be way off. However,
81// this is a moot issue on Linux and Mac as they only accept the point argument. So,
82// we use the pixel size constructor on Windows, but we use point size on Linux and Mac.
83#if __WXMSW__
84    m_font = adoptRef(new FontHolder(new wxFont(   wxSize(0, -desc.computedPixelSize()),
85                                fontFamilyToWxFontFamily(desc.genericFamily()),
86                                italicToWxFontStyle(desc.italic()),
87                                fontWeightToWxFontWeight(desc.weight()),
88                                false,
89                                family.string()
90                            )
91                        ));
92#else
93    m_font = adoptRef(new FontHolder(new wxFont(   desc.computedPixelSize(),
94                                fontFamilyToWxFontFamily(desc.genericFamily()),
95                                italicToWxFontStyle(desc.italic()),
96                                fontWeightToWxFontWeight(desc.weight()),
97                                false,
98                                family.string()
99                            )
100                        ));
101#endif
102#if OS(DARWIN)
103#if !wxOSX_USE_CORE_TEXT
104#if wxCHECK_VERSION(2,9,0)
105    m_atsuFontID = m_font->font()->OSXGetATSUFontID();
106#else
107    m_atsuFontID = m_font->font()->MacGetATSUFontID();
108#endif
109#endif
110    m_nsFont = 0;
111    cacheNSFont();
112#endif
113    m_size = desc.computedPixelSize();
114    m_fontState = VALID;
115    m_size = desc.computedPixelSize();
116}
117
118unsigned FontPlatformData::computeHash() const
119{
120    wxFont* thisFont = m_font->font();
121    ASSERT(thisFont && thisFont->IsOk());
122
123    // make a hash that is unique for this font, but not globally unique - that is,
124    // a font whose properties are equal should generate the same hash
125    uintptr_t hashCodes[6] = {
126        thisFont->GetPointSize(),
127        thisFont->GetFamily(),
128        thisFont->GetStyle(),
129        thisFont->GetWeight(),
130        thisFont->GetUnderlined(),
131        StringHasher::computeHash(thisFont->GetFaceName().utf8_str().data())
132    };
133
134    return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
135}
136
137FontPlatformData::~FontPlatformData()
138{
139    m_fontState = UNINITIALIZED;
140    m_font = 0;
141}
142
143#ifndef NDEBUG
144String FontPlatformData::description() const
145{
146    return String();
147}
148#endif
149
150#if OS(WINDOWS)
151bool FontPlatformData::useGDI() const
152{
153    return true;
154}
155
156HFONT FontPlatformData::hfont() const
157{
158    return static_cast<HFONT>(m_font->font()->GetHFONT());
159}
160#endif
161
162#if OS(DARWIN)
163CGFontRef FontPlatformData::cgFont() const
164{
165    CGFontRef cgFont = 0;
166#ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
167    cgFont = CTFontCopyGraphicsFont((CTFontRef)m_font->font()->OSXGetCTFont(), 0);
168#else
169    ATSFontRef fontRef;
170
171    fontRef = FMGetATSFontRefFromFont(m_atsuFontID);
172
173    if (fontRef)
174        cgFont = CGFontCreateWithPlatformFont((void*)&fontRef);
175#endif
176    return cgFont;
177}
178#endif
179
180
181
182}
183