1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QFONT_P_H
43#define QFONT_P_H
44
45//
46// W A R N I N G
47// -------------
48//
49// This file is not part of the Qt API. It exists for the convenience
50// of internal files. This header file may change from version to version
51// without notice, or even be removed.
52//
53// We mean it.
54//
55
56#include "QtGui/qfont.h"
57#include "QtCore/qmap.h"
58#include "QtCore/qobject.h"
59#include <private/qunicodetables_p.h>
60#include <QtGui/qfontdatabase.h>
61#include "private/qfixed_p.h"
62
63QT_BEGIN_NAMESPACE
64
65// forwards
66class QFontCache;
67class QFontEngine;
68
69struct QFontDef
70{
71 inline QFontDef()
72 : pointSize(-1.0), pixelSize(-1),
73 styleStrategy(QFont::PreferDefault), styleHint(QFont::AnyStyle),
74 weight(50), fixedPitch(false), style(QFont::StyleNormal), stretch(100),
75 ignorePitch(true), hintingPreference(QFont::PreferDefaultHinting)
76#ifdef Q_WS_MAC
77 ,fixedPitchComputed(false)
78#endif
79 {
80 }
81
82 QString family;
83 QString styleName;
84
85#ifdef Q_WS_X11
86 QString addStyle;
87#endif // Q_WS_X11
88
89 qreal pointSize;
90 qreal pixelSize;
91
92 uint styleStrategy : 16;
93 uint styleHint : 8;
94
95 uint weight : 7; // 0-99
96 uint fixedPitch : 1;
97 uint style : 2;
98 uint stretch : 12; // 0-400
99
100 uint ignorePitch : 1;
101 uint hintingPreference : 2;
102 uint fixedPitchComputed : 1; // for Mac OS X only
103 int reserved : 14; // for future extensions
104
105 bool exactMatch(const QFontDef &other) const;
106 bool operator==(const QFontDef &other) const
107 {
108 return pixelSize == other.pixelSize
109 && weight == other.weight
110 && style == other.style
111 && stretch == other.stretch
112 && styleHint == other.styleHint
113 && styleStrategy == other.styleStrategy
114 && ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
115 && family == other.family
116 && (styleName.isEmpty() || other.styleName.isEmpty() || styleName == other.styleName)
117 && hintingPreference == other.hintingPreference
118#ifdef Q_WS_X11
119 && addStyle == other.addStyle
120#endif
121 ;
122 }
123 inline bool operator<(const QFontDef &other) const
124 {
125 if (pixelSize != other.pixelSize) return pixelSize < other.pixelSize;
126 if (weight != other.weight) return weight < other.weight;
127 if (style != other.style) return style < other.style;
128 if (stretch != other.stretch) return stretch < other.stretch;
129 if (styleHint != other.styleHint) return styleHint < other.styleHint;
130 if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
131 if (family != other.family) return family < other.family;
132 if (!styleName.isEmpty() && !other.styleName.isEmpty() && styleName != other.styleName)
133 return styleName < other.styleName;
134 if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
135
136#ifdef Q_WS_X11
137 if (addStyle != other.addStyle) return addStyle < other.addStyle;
138#endif // Q_WS_X11
139
140 if (ignorePitch != other.ignorePitch) return ignorePitch < other.ignorePitch;
141 if (fixedPitch != other.fixedPitch) return fixedPitch < other.fixedPitch;
142 return false;
143 }
144};
145
146class QFontEngineData
147{
148public:
149 QFontEngineData();
150 ~QFontEngineData();
151
152 QAtomicInt ref;
153 QFontCache *fontCache;
154
155#if !defined(Q_WS_MAC)
156 QFontEngine *engines[QUnicodeTables::ScriptCount];
157#else
158 QFontEngine *engine;
159#endif
160};
161
162
163class Q_GUI_EXPORT QFontPrivate
164{
165public:
166#ifdef Q_WS_X11
167 static int defaultEncodingID;
168#endif // Q_WS_X11
169
170 QFontPrivate();
171 QFontPrivate(const QFontPrivate &other);
172 ~QFontPrivate();
173
174 QFontEngine *engineForScript(int script) const;
175 void alterCharForCapitalization(QChar &c) const;
176
177 QAtomicInt ref;
178 QFontDef request;
179 mutable QFontEngineData *engineData;
180 int dpi;
181 int screen;
182
183#ifdef Q_WS_WIN
184 HDC hdc;
185#endif
186
187 uint rawMode : 1;
188 uint underline : 1;
189 uint overline : 1;
190 uint strikeOut : 1;
191 uint kerning : 1;
192 uint capital : 3;
193 bool letterSpacingIsAbsolute : 1;
194
195 QFixed letterSpacing;
196 QFixed wordSpacing;
197
198 mutable QFontPrivate *scFont;
199 QFont smallCapsFont() const { return QFont(smallCapsFontPrivate()); }
200 QFontPrivate *smallCapsFontPrivate() const;
201
202 static QFontPrivate *get(const QFont &font)
203 {
204 return font.d.data();
205 }
206
207 void resolve(uint mask, const QFontPrivate *other);
208private:
209 QFontPrivate &operator=(const QFontPrivate &) { return *this; }
210};
211
212
213class QFontCache : public QObject
214{
215 Q_OBJECT
216public:
217 // note: these static functions work on a per-thread basis
218 static QFontCache *instance();
219 static void cleanup();
220
221 QFontCache();
222 ~QFontCache();
223
224 void clear();
225#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2)
226 void removeEngineForFont(const QByteArray &fontName);
227#endif
228 // universal key structure. QFontEngineDatas and QFontEngines are cached using
229 // the same keys
230 struct Key {
231 Key() : script(0), screen(0) { }
232 Key(const QFontDef &d, int c, int s = 0)
233 : def(d), script(c), screen(s) { }
234
235 QFontDef def;
236 int script;
237 int screen;
238
239 inline bool operator<(const Key &other) const
240 {
241 if (script != other.script) return script < other.script;
242 if (screen != other.screen) return screen < other.screen;
243 return def < other.def;
244 }
245 inline bool operator==(const Key &other) const
246 { return def == other.def && script == other.script && screen == other.screen; }
247 };
248
249 // QFontEngineData cache
250 typedef QMap<Key,QFontEngineData*> EngineDataCache;
251 EngineDataCache engineDataCache;
252
253 QFontEngineData *findEngineData(const Key &key) const;
254 void insertEngineData(const Key &key, QFontEngineData *engineData);
255
256 // QFontEngine cache
257 struct Engine {
258 Engine() : data(0), timestamp(0), hits(0) { }
259 Engine(QFontEngine *d) : data(d), timestamp(0), hits(0) { }
260
261 QFontEngine *data;
262 uint timestamp;
263 uint hits;
264 };
265
266 typedef QMap<Key,Engine> EngineCache;
267 EngineCache engineCache;
268
269 QFontEngine *findEngine(const Key &key);
270 void insertEngine(const Key &key, QFontEngine *engine);
271
272#if defined(Q_WS_WIN) || defined(Q_WS_QWS)
273 void cleanupPrinterFonts();
274#endif
275
276 private:
277 void increaseCost(uint cost);
278 void decreaseCost(uint cost);
279 void timerEvent(QTimerEvent *event);
280
281 static const uint min_cost;
282 uint total_cost, max_cost;
283 uint current_timestamp;
284 bool fast;
285 int timer_id;
286};
287
288Q_GUI_EXPORT int qt_defaultDpiX();
289Q_GUI_EXPORT int qt_defaultDpiY();
290Q_GUI_EXPORT int qt_defaultDpi();
291
292QT_END_NAMESPACE
293
294#endif // QFONT_P_H
295