Rubber stamped by David.
[WebKit-https.git] / WebCore / platform / graphics / gtk / FontPlatformDataGtk.cpp
1 /*
2  * This file is part of the internal font implementation.  It should not be included by anyone other than
3  * FontMac.cpp, FontWin.cpp and Font.cpp.
4  *
5  * Copyright (C) 2006 Apple Computer, Inc.
6  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
7  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
8  * Copyright (C) 2007 Holger Hans Peter Freyther
9  * All rights reserved.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  *
26  */
27
28 #include "config.h"
29 #include "FontPlatformData.h"
30
31 #include "CString.h"
32 #include "PlatformString.h"
33 #include "FontDescription.h"
34
35 #include <cairo-ft.h>
36 #include <cairo.h>
37 #include <fontconfig/fcfreetype.h>
38
39 namespace WebCore {
40
41 FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
42     : m_pattern(0)
43     , m_fontDescription(fontDescription)
44     , m_scaledFont(0)
45 {
46     FontPlatformData::init();
47
48     CString familyNameString = familyName.domString().utf8();
49     const char* fcfamily = familyNameString.data();
50     int fcslant = FC_SLANT_ROMAN;
51     int fcweight = FC_WEIGHT_NORMAL;
52     float fcsize = fontDescription.computedSize();
53     if (fontDescription.italic())
54         fcslant = FC_SLANT_ITALIC;
55     if (fontDescription.bold())
56         fcweight = FC_WEIGHT_BOLD;
57
58     int type = fontDescription.genericFamily();
59
60     FcPattern* pattern = FcPatternCreate();
61     cairo_font_face_t* fontFace;
62     cairo_font_options_t* options;
63     cairo_matrix_t fontMatrix;
64
65     if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
66         goto freePattern;
67
68     switch (type) {
69         case FontDescription::SerifFamily:
70             fcfamily = "serif";
71             break;
72         case FontDescription::SansSerifFamily:
73             fcfamily = "sans-serif";
74             break;
75         case FontDescription::MonospaceFamily:
76             fcfamily = "monospace";
77             break;
78         case FontDescription::NoFamily:
79         case FontDescription::StandardFamily:
80         default:
81             fcfamily = "sans-serif";
82     }
83
84     if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
85         goto freePattern;
86     if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant))
87         goto freePattern;
88     if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))
89         goto freePattern;
90     if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize))
91         goto freePattern;
92
93     FcConfigSubstitute(NULL, pattern, FcMatchPattern);
94     FcDefaultSubstitute(pattern);
95
96     FcResult fcresult;
97     m_pattern = FcFontMatch(NULL, pattern, &fcresult);
98     // FIXME: should we set some default font?
99     if (!m_pattern)
100         goto freePattern;
101     fontFace = cairo_ft_font_face_create_for_pattern(m_pattern);
102     cairo_matrix_t ctm;
103     cairo_matrix_init_scale(&fontMatrix, m_fontDescription.computedSize(), m_fontDescription.computedSize());
104     cairo_matrix_init_identity(&ctm);
105     options = cairo_font_options_create();
106     m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
107     cairo_font_face_destroy(fontFace);
108     cairo_font_options_destroy(options);
109
110 freePattern:
111     FcPatternDestroy(pattern);
112 }
113
114 bool FontPlatformData::init()
115 {
116     static bool initialized;
117     if (initialized)
118         return true;
119     initialized = true;
120     if (!FcInit()) {
121         fprintf(stderr, "Can't init font config library\n");
122         return false;
123     }
124     return true;
125 }
126
127 FontPlatformData::~FontPlatformData()
128 {
129 }
130
131 bool FontPlatformData::isFixedPitch()
132 {
133     int spacing;
134     if (FcPatternGetInteger(m_pattern, FC_SPACING, 0, &spacing) == FcResultMatch)
135         return spacing == FC_MONO;
136     return false;
137 }
138
139 void FontPlatformData::setFont(cairo_t* cr) const
140 {
141     ASSERT(m_scaledFont);
142
143     cairo_set_scaled_font(cr, m_scaledFont);
144 }
145
146 bool FontPlatformData::operator==(const FontPlatformData& other) const
147 {
148     if (m_pattern == other.m_pattern)
149         return true;
150     if (m_pattern == 0 || m_pattern == reinterpret_cast<FcPattern*>(-1)
151             || other.m_pattern == 0 || other.m_pattern == reinterpret_cast<FcPattern*>(-1))
152         return false;
153     return FcPatternEqual(m_pattern, other.m_pattern);
154 }
155
156 }