Skip to content

Commit ea3682d

Browse files
author
Steve Simpson
committed
Added Freetype support for Windows platforms
This commit comes from a patch submitted to the qt dev team: https://codereview.qt-project.org/100430 The patch was reviewed and rejected because Qt4 was in maintenance mode and this was quite a large change. Nevertheless, the patch has been used successfully with both MSVC 2008 and MSVC 2010. In particular, it has been used to create Qt opensource builds for Windows CE using VS2008. The patch was based on changes in Qt5 to support Freetype on Windows. ================ Known problems / concerns: - Some Windows code under examples does not build due to assumptions - about the FontEngine. Just needs fixing.. - text.pri is a mess - Had to modify one line in Freetype source bundled with Qt. - Did I add leaky abstractions??? - MS's 2008 CRTL is very weak and buggy. Can it be trusted? - Regressions to MingGW / GCC cross compilation. - Did not explicitly follow Qt coding standard, but this can be easily - addressed later. ================
1 parent 0a2f238 commit ea3682d

19 files changed

+1221
-91
lines changed

src/3rdparty/freetype/src/gzip/zutil.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ typedef unsigned long ulg;
182182
#endif
183183

184184
/* Diagnostic functions */
185-
#ifdef DEBUG
185+
#if defined(DEBUG) && !defined(_WIN32_WCE)
186186
# include <stdio.h>
187187
extern int z_verbose;
188188
extern void z_error OF((char *m));

src/gui/kernel/qapplication_p.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,41 @@
8282
#include "QtGui/qplatformintegration_qpa.h"
8383
#endif
8484

85+
#if defined (Q_OS_WIN32) || defined(Q_OS_WINCE)
86+
# include "QtCore/qthreadstorage.h"
87+
#endif
88+
8589
QT_BEGIN_NAMESPACE
8690

91+
#if defined (Q_OS_WIN32) || defined(Q_OS_WINCE)
92+
93+
// common DC for all fonts
94+
95+
class QtHDC
96+
{
97+
HDC _hdc;
98+
public:
99+
QtHDC()
100+
{
101+
HDC displayDC = GetDC(0);
102+
_hdc = CreateCompatibleDC(displayDC);
103+
ReleaseDC(0, displayDC);
104+
}
105+
~QtHDC()
106+
{
107+
if (_hdc)
108+
DeleteDC(_hdc);
109+
}
110+
HDC hdc() const
111+
{
112+
return _hdc;
113+
}
114+
};
115+
116+
HDC shared_dc();
117+
118+
#endif
119+
87120
class QClipboard;
88121
class QGraphicsScene;
89122
class QGraphicsSystem;

src/gui/kernel/qapplication_win.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,22 @@ typedef struct tagTOUCHINPUT
194194
#endif
195195
QT_BEGIN_NAMESPACE
196196

197+
#ifndef QT_NO_THREAD
198+
Q_GLOBAL_STATIC(QThreadStorage<QtHDC *>, local_shared_dc)
199+
HDC shared_dc()
200+
{
201+
QtHDC *&hdc = local_shared_dc()->localData();
202+
if (!hdc)
203+
hdc = new QtHDC;
204+
return hdc->hdc();
205+
}
206+
#else
207+
HDC shared_dc()
208+
{
209+
return 0;
210+
}
211+
#endif
212+
197213
#ifdef Q_WS_WINCE
198214
#ifndef SHRG_RETURNCMD
199215
struct SHRGINFO {
@@ -499,7 +515,22 @@ class QETWidget : public QWidget // event translator widget
499515
// need to get default font?
500516
extern bool qt_app_has_font;
501517

502-
extern QFont qt_LOGFONTtoQFont(LOGFONT& lf,bool scale);
518+
extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
519+
520+
QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/)
521+
{
522+
QString family = QString::fromWCharArray(lf.lfFaceName);
523+
QFont qf(family);
524+
qf.setItalic(lf.lfItalic);
525+
if (lf.lfWeight != FW_DONTCARE)
526+
qf.setWeight(weightFromInteger(lf.lfWeight));
527+
int lfh = qAbs(lf.lfHeight);
528+
qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY));
529+
qf.setUnderline(false);
530+
qf.setOverline(false);
531+
qf.setStrikeOut(false);
532+
return qf;
533+
}
503534

504535
static void qt_set_windows_color_resources()
505536
{

src/gui/kernel/qguifunctions_wince.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ typedef struct tagTTPOLYCURVE
124124
#define TT_PRIM_CSPLINE 3
125125
#define ANSI_VAR_FONT 12
126126

127+
#ifndef DEVICE_FONTTYPE
128+
#define DEVICE_FONTTYPE 0x0002
129+
#endif
130+
131+
#ifndef RASTER_FONTTYPE
132+
#define RASTER_FONTTYPE 0x0001
133+
#endif
134+
127135
HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR operation, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd);
128136
#define ShellExecute(a,b,c,d,e,f) qt_wince_ShellExecute(a,b,c,d,e,f)
129137

src/gui/painting/qpaintengine_raster.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@
7979
#if defined(Q_WS_WIN)
8080
# include <qt_windows.h>
8181
# include <qvarlengtharray.h>
82-
# include <private/qfontengine_p.h>
82+
# if defined(QT_WIN_FREETYPE)
83+
# include <private/qfontengine_ft_p.h>
84+
# else
85+
# include <private/qfontengine_p.h>
86+
# endif
8387
# if defined(Q_OS_WINCE)
8488
# include "qguifunctions_wince.h"
8589
# endif
@@ -3421,7 +3425,7 @@ bool QRasterPaintEngine::supportsTransformations(const QFontEngine *fontEngine)
34213425
if (!state()->WxF)
34223426
return false;
34233427
const QTransform &m = state()->matrix;
3424-
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
3428+
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) && !defined(QT_WIN_FREETYPE)
34253429
QFontEngine::Type fontEngineType = fontEngine->type();
34263430
if ((fontEngineType == QFontEngine::Win && !((QFontEngineWin *) fontEngine)->ttf && m.type() > QTransform::TxTranslate)
34273431
|| (m.type() <= QTransform::TxTranslate

src/gui/painting/qpdf.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1936,7 +1936,7 @@ void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &t
19361936
currentPage->fonts.append(font->object_id);
19371937

19381938
qreal size = ti.fontEngine->fontDef.pixelSize;
1939-
#ifdef Q_WS_WIN
1939+
#if defined(Q_WS_WIN) && !defined(QT_WIN_FREETYPE)
19401940
if (ti.fontEngine->type() == QFontEngine::Win) {
19411941
QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine);
19421942
size = fe->tm.tmHeight;

src/gui/text/qfont.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#include <QtCore/qstring.h>
4747
#include <QtCore/qsharedpointer.h>
4848

49-
#if defined(Q_WS_X11) || defined(Q_WS_QWS)
49+
#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(QT_WIN_FREETYPE)
5050
typedef struct FT_FaceRec_* FT_Face;
5151
#endif
5252

@@ -248,13 +248,13 @@ class Q_GUI_EXPORT QFont
248248

249249
#ifdef Q_WS_WIN
250250
HFONT handle() const;
251-
#else // !Q_WS_WIN
251+
#else
252252
Qt::HANDLE handle() const;
253253
#endif // Q_WS_WIN
254254
#ifdef Q_WS_MAC
255255
quint32 macFontID() const;
256256
#endif
257-
#if defined(Q_WS_X11) || defined(Q_WS_QWS)
257+
#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(QT_WIN_FREETYPE)
258258
FT_Face freetypeFace() const;
259259
#endif
260260

src/gui/text/qfont_win.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,6 @@
5757

5858
QT_BEGIN_NAMESPACE
5959

60-
extern HDC shared_dc(); // common dc for all fonts
61-
extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
62-
63-
// ### maybe move to qapplication_win
64-
QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/)
65-
{
66-
QString family = QString::fromWCharArray(lf.lfFaceName);
67-
QFont qf(family);
68-
qf.setItalic(lf.lfItalic);
69-
if (lf.lfWeight != FW_DONTCARE)
70-
qf.setWeight(weightFromInteger(lf.lfWeight));
71-
int lfh = qAbs(lf.lfHeight);
72-
qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY));
73-
qf.setUnderline(false);
74-
qf.setOverline(false);
75-
qf.setStrikeOut(false);
76-
return qf;
77-
}
78-
7960

8061
static inline float pixelSize(const QFontDef &request, int dpi)
8162
{

src/gui/text/qfont_win_ft.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
#include "qfont.h"
43+
#include "qfont_p.h"
44+
#include "qfontengine_p.h"
45+
#include "qtextengine_p.h"
46+
#include "qfontmetrics.h"
47+
#include "qfontinfo.h"
48+
49+
#include "qwidget.h"
50+
#include "qpainter.h"
51+
#include <limits.h>
52+
#include "qt_windows.h"
53+
#include <private/qapplication_p.h>
54+
#include "qapplication.h"
55+
#include <private/qunicodetables_p.h>
56+
#include <qfontdatabase.h>
57+
58+
QT_BEGIN_NAMESPACE
59+
60+
/*****************************************************************************
61+
QFont member functions
62+
*****************************************************************************/
63+
64+
void QFont::initialize()
65+
{
66+
}
67+
68+
void QFont::cleanup()
69+
{
70+
QFontCache::cleanup();
71+
}
72+
73+
HFONT QFont::handle() const // called by QWinInputContext to set composition font
74+
{
75+
return NULL; // hack. what we need is a QWinFTInputContext class... but that's too much work now
76+
}
77+
78+
FT_Face QFont::freetypeFace() const
79+
{
80+
QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
81+
if (engine->type() == QFontEngine::Multi)
82+
engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
83+
if (engine->type() == QFontEngine::Freetype) {
84+
const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
85+
return ft->non_locked_face();
86+
}
87+
return 0;
88+
}
89+
90+
QString QFont::rawName() const
91+
{
92+
return family();
93+
}
94+
95+
void QFont::setRawName(const QString &name)
96+
{
97+
setFamily(name);
98+
}
99+
100+
QString QFont::defaultFamily() const
101+
{
102+
switch (d->request.styleHint) {
103+
case QFont::Times:
104+
return QString::fromLatin1("Times New Roman");
105+
case QFont::Courier:
106+
case QFont::Monospace:
107+
return QString::fromLatin1("Courier New");
108+
case QFont::Decorative:
109+
return QString::fromLatin1("Bookman Old Style");
110+
case QFont::Cursive:
111+
return QString::fromLatin1("Comic Sans MS");
112+
case QFont::Fantasy:
113+
return QString::fromLatin1("Impact");
114+
case QFont::Helvetica:
115+
return QString::fromLatin1("Arial");
116+
case QFont::System:
117+
default:
118+
return QString::fromLatin1("MS Sans Serif");
119+
}
120+
}
121+
122+
QString QFont::lastResortFamily() const
123+
{
124+
return QString::fromLatin1("helvetica");
125+
}
126+
127+
QString QFont::lastResortFont() const
128+
{
129+
return QString::fromLatin1("arial");
130+
}
131+
132+
QT_END_NAMESPACE

0 commit comments

Comments
 (0)