1 /*
2 Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18
19 This class provides all functionality needed for loading images, style sheets and html
20 pages from the web. It has a memory cache for these objects.
21 */
22 #include "config.h"
23 #include "FontCustomPlatformData.h"
24
25 #include "FontPlatformData.h"
26 #include "SharedBuffer.h"
27 #include "WOFFFileFormat.h"
28 #include <QFontDatabase>
29 #include <QMap>
30 #include <QStringList>
31
32 namespace WebCore {
33
~FontCustomPlatformData()34 FontCustomPlatformData::~FontCustomPlatformData()
35 {
36 QFontDatabase::removeApplicationFont(m_handle);
37 }
38
fontPlatformData(int size,bool syntheticBold,bool syntheticItalic,FontOrientation,TextOrientation,FontWidthVariant,FontRenderingMode)39 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool syntheticBold, bool syntheticItalic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
40 {
41 // Note that syntheticBold and syntheticItalic are only set by CSSFontSelector
42 // (the sole user of this class) if the markup has requested bold or italic
43 // (e.g. <i>text</i>) but the @font-face rule for the font does not specify support
44 // for it (e.g. @font-face { font-family: "font"; font-style: normal;).
45
46 QFont font;
47 QFontDatabase db;
48
49 QString family = QFontDatabase::applicationFontFamilies(m_handle)[0];
50 font.setFamily(family);
51 font.setPixelSize(size);
52 if (m_bold || syntheticBold)
53 font.setWeight(QFont::Bold);
54 font.setItalic(m_italic || syntheticItalic);
55
56 return FontPlatformData(font);
57 }
58
currentStyles(const QStringList & families,const QFontDatabase & db)59 static QMap<QString, QStringList> currentStyles(const QStringList& families, const QFontDatabase& db)
60 {
61 QMap<QString, QStringList> styles;
62 for (int i = 0; i < families.size(); ++i)
63 styles[families.at(i)].append(db.styles(families.at(i)));
64 return styles;
65 }
66
stylesAddedByFont(const QString & familyAdded,const QStringList & stylesAdded,const QMap<QString,QStringList> & styles)67 static QStringList stylesAddedByFont(const QString& familyAdded, const QStringList& stylesAdded, const QMap<QString, QStringList>& styles)
68 {
69 QStringList newStyles = stylesAdded;
70 for (int i = 0; i < styles[familyAdded].size(); ++i)
71 newStyles.removeAll(styles[familyAdded].at(i));
72 return newStyles;
73 }
74
strictlyItalicAddedByFont(const QString & familyAdded,const QStringList & stylesAdded,const QFontDatabase & db)75 static bool strictlyItalicAddedByFont(const QString& familyAdded, const QStringList& stylesAdded, const QFontDatabase& db)
76 {
77 bool italic = false;
78 for (int i = 0; i < stylesAdded.size(); ++i) {
79 if (db.italic(familyAdded, stylesAdded.at(i))) {
80 italic = true;
81 } else if (!db.bold(familyAdded, stylesAdded.at(i)))
82 return false;
83 }
84 return italic;
85 }
86
strictlyBoldAddedByFont(const QString & familyAdded,const QStringList & stylesAdded,const QFontDatabase & db)87 static bool strictlyBoldAddedByFont(const QString& familyAdded, const QStringList& stylesAdded, const QFontDatabase& db)
88 {
89 bool bold = false;
90 for (int i = 0; i < stylesAdded.size(); ++i) {
91 if (db.bold(familyAdded, stylesAdded.at(i))) {
92 bold = true;
93 } else if (!db.italic(familyAdded, stylesAdded.at(i)))
94 return false;
95 }
96 return bold;
97 }
98
createFontCustomPlatformData(SharedBuffer * buffer)99 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
100 {
101 ASSERT_ARG(buffer, buffer);
102 QFontDatabase db;
103
104 // The font families in the font database, and the styles in each,
105 // before we load the new font in buffer.
106 QStringList families = db.families();
107 QMap<QString, QStringList> styles = currentStyles(families, db);
108
109 RefPtr<SharedBuffer> sfntBuffer;
110 if (isWOFF(buffer)) {
111 Vector<char> sfnt;
112 if (!convertWOFFToSfnt(buffer, sfnt))
113 return 0;
114 sfntBuffer = SharedBuffer::adoptVector(sfnt);
115 buffer = sfntBuffer.get();
116 }
117
118 int id = QFontDatabase::addApplicationFontFromData(QByteArray(buffer->data(), buffer->size()));
119 if (id == -1)
120 return 0;
121
122 QString familyAdded = QFontDatabase::applicationFontFamilies(id)[0];
123 QStringList stylesAdded = db.styles(QFontDatabase::applicationFontFamilies(id)[0]);
124
125 // If we already had the family of which this font is a member then
126 // get the styles it added to the family
127 if (families.contains(familyAdded))
128 stylesAdded = stylesAddedByFont(familyAdded, stylesAdded, styles);
129
130 Q_ASSERT(QFontDatabase::applicationFontFamilies(id).size() > 0);
131
132 FontCustomPlatformData *data = new FontCustomPlatformData;
133 data->m_handle = id;
134
135 // If we have created a font that only has bold or italic styles (or both)
136 // then we need to respect it's style(s) when we pass it back as
137 // FontPlatformData above.
138 data->m_italic = strictlyItalicAddedByFont(familyAdded, stylesAdded, db);
139 data->m_bold = strictlyBoldAddedByFont(familyAdded, stylesAdded, db);
140 return data;
141 }
142
supportsFormat(const String & format)143 bool FontCustomPlatformData::supportsFormat(const String& format)
144 {
145 return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff");
146 }
147
148 }
149