first version ubuntu qt creator build

This commit is contained in:
John Preston 2014-07-08 14:24:21 +04:00
parent ce84c603c2
commit da0f087404
22 changed files with 2160 additions and 61 deletions

4
.gitignore vendored
View File

@ -25,3 +25,7 @@ ipch/
/Mac/
/Telegram/*.xcodeproj/xcuserdata/
/Telegram/*.xcodeproj/project.xcworkspace/
/Telegram/*.user.*
/Linux/
/Telegram/Makefile

View File

@ -2,14 +2,14 @@ QT += core
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
OBJECTS_DIR = ./../Mac/DebugIntermediateEmoji
OBJECTS_DIR = ./../Linux/DebugIntermediateEmoji
MOC_DIR = ./GeneratedFiles/Debug
DESTDIR = ./../Mac/DebugEmoji
DESTDIR = ./../Linux/DebugEmoji
}
CONFIG(release, debug|release) {
OBJECTS_DIR = ./../Mac/ReleaseIntermediateEmoji
OBJECTS_DIR = ./../Linux/ReleaseIntermediateEmoji
MOC_DIR = ./GeneratedFiles/Release
DESTDIR = ./../Mac/ReleaseEmoji
DESTDIR = ./../Linux/ReleaseEmoji
}
macx {

View File

@ -2,14 +2,14 @@ T += core
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
OBJECTS_DIR = ./../Mac/DebugIntermediateLang
OBJECTS_DIR = ./../Linux/DebugIntermediateLang
MOC_DIR = ./GeneratedFiles/Debug
DESTDIR = ./../Mac/DebugLang
DESTDIR = ./../Linux/DebugLang
}
CONFIG(release, debug|release) {
OBJECTS_DIR = ./../Mac/ReleaseIntermediateLang
OBJECTS_DIR = ./../Linux/ReleaseIntermediateLang
MOC_DIR = ./GeneratedFiles/Release
DESTDIR = ./../Mac/ReleaseLang
DESTDIR = ./../Linux/ReleaseLang
}
macx {

View File

@ -2,14 +2,14 @@ QT += core
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
OBJECTS_DIR = ./../Mac/DebugIntermediateStyle
OBJECTS_DIR = ./../Linux/DebugIntermediateStyle
MOC_DIR = ./GeneratedFiles/Debug
DESTDIR = ./../Mac/DebugStyle
DESTDIR = ./../Linux/DebugStyle
}
CONFIG(release, debug|release) {
OBJECTS_DIR = ./../Mac/ReleaseIntermediateStyle
OBJECTS_DIR = ./../Linux/ReleaseIntermediateStyle
MOC_DIR = ./GeneratedFiles/Release
DESTDIR = ./../Mac/ReleaseStyle
DESTDIR = ./../Linux/ReleaseStyle
}
macx {

View File

@ -2,14 +2,14 @@ QT += core
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
OBJECTS_DIR = ./../Mac/DebugIntermediatePacker
OBJECTS_DIR = ./../Linux/DebugIntermediatePacker
MOC_DIR = ./GeneratedFiles/Debug
DESTDIR = ./../Mac/DebugPacker
DESTDIR = ./../Linux/DebugPacker
}
CONFIG(release, debug|release) {
OBJECTS_DIR = ./../Mac/ReleaseIntermediatePacker
OBJECTS_DIR = ./../Linux/ReleaseIntermediatePacker
MOC_DIR = ./GeneratedFiles/Release
DESTDIR = ./../Mac/ReleasePacker
DESTDIR = ./../Linux/ReleasePacker
}
macx {

View File

@ -321,7 +321,7 @@ namespace App {
case mtpc_userStatusOnline: data->onlineTill = status->c_userStatusOnline().vexpires.v; break;
}
if (data->contact < 0 && !data->phone.isEmpty() && (data->id & 0xFFFFFFFF) != MTP::authedId()) {
if (data->contact < 0 && !data->phone.isEmpty() && int32(data->id & 0xFFFFFFFF) != MTP::authedId()) {
data->contact = 0;
}
if (data->contact > 0 && !wasContact) {

View File

@ -84,14 +84,14 @@ void AboutBox::paintEvent(QPaintEvent *e) {
p.setPen(st::black->p);
p.setFont(st::aboutHeaderFont->f);
p.drawText((_width - (_headerWidth + _subheaderWidth)) / 2, st::aboutHeaderTop + st::aboutHeaderFont->ascent, qsl("Telegram"));
p.drawText((_width - (_headerWidth + _subheaderWidth)) / 2, st::aboutHeaderTop + st::aboutHeaderFont->ascent, qsl("Telegram"));
p.setFont(st::aboutSubheaderFont->f);
p.drawText((_width - (_headerWidth + _subheaderWidth)) / 2 + _headerWidth, st::aboutHeaderTop + st::aboutSubheaderFont->ascent, qsl("Desktop"));
p.drawText((_width - (_headerWidth + _subheaderWidth)) / 2 + _headerWidth, st::aboutHeaderTop + st::aboutSubheaderFont->ascent, qsl("Desktop"));
p.setFont(st::aboutVersionFont->f);
p.setPen(st::aboutVersionColor->p);
p.drawText((_width - _versionWidth) / 2, st::aboutVersionTop + st::aboutVersionFont->ascent, _versionText);
p.drawText((_width - _versionWidth) / 2, st::aboutVersionTop + st::aboutVersionFont->ascent, _versionText);
}
} else {
p.setOpacity(a_opacity.current());

View File

@ -32,7 +32,7 @@ namespace style {
modified[_flags] = Font(this);
f.setPixelSize(size);
f.setBold(_flags & FontBold);
f.setBold(_flags & FontBold);
f.setItalic(_flags & FontItalic);
f.setUnderline(_flags & FontUnderline);
f.setStyleStrategy(QFont::PreferQuality);

View File

@ -1245,9 +1245,9 @@ public:
break;
}
}/**/
for (; _lineEnd > _lineStart + 1; --_lineEnd) {
for (; _lineEnd > _lineStart; --_lineEnd) {
QChar ch = _t->_text.at(_lineEnd - 1);
if (ch != QChar::Space && ch != QChar::LineFeed) {
if ((ch != QChar::Space || _lineEnd == _lineStart + 1) && ch != QChar::LineFeed) {
break;
}
}/**/

View File

@ -16,6 +16,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014 John Preston, https://tdesktop.com
*/
#include "stdafx.h"
#include <iostream>
#include "pspecific.h"
namespace {
@ -71,6 +72,8 @@ void debugLogWrite(const char *file, int32 line, const QString &v) {
OutputDebugString(reinterpret_cast<const wchar_t *>(msg.utf16()));
#elif defined Q_OS_MAC
objc_outputDebugString(msg);
#elif defined Q_OS_LINUX && defined _DEBUG
std::cout << msg.toUtf8().constData();
#endif
}
}

View File

@ -130,7 +130,7 @@ namespace {
bool onErrorDefault(mtpRequestId requestId, const RPCError &error) {
const QString &err(error.type());
QRegularExpressionMatch m;;
QRegularExpressionMatch m;
if ((m = QRegularExpression("^(FILE|PHONE|NETWORK|USER)_MIGRATE_(\\d+)$").match(err)).hasMatch()) {
if (!requestId) return false;

View File

@ -2756,12 +2756,12 @@ void MTProtoConnectionPrivate::authKeyCreated() {
void MTProtoConnectionPrivate::clearAuthKeyData() {
if (authKeyData) {
#ifdef Q_OS_WIN
SecureZeroMemory(authKeyData, sizeof(AuthKeyCreateData));
#ifdef Q_OS_WIN // TODO
// SecureZeroMemory(authKeyData, sizeof(AuthKeyCreateData));
#else
memset(authKeyData, 0, sizeof(AuthKeyCreateData));
// memset(authKeyData, 0, sizeof(AuthKeyCreateData));
#endif
delete authKeyData;
delete authKeyData;
authKeyData = 0;
}
}

View File

@ -26,7 +26,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
#endif
#ifdef Q_OS_LINUX
#include "pspecific_linux.h"
#endif
#ifdef Q_OS_WIN

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,257 @@
/*
This file is part of Telegram Desktop,
an unofficial desktop messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014 John Preston, https://tdesktop.com
*/
#pragma once
inline QString psServerPrefix() {
return qsl("/tmp/");
}
inline void psCheckLocalSocket(const QString &serverName) {
QFile address(serverName);
if (address.exists()) {
address.remove();
}
}
class PsNotifyWindow : public QWidget, public Animated {
Q_OBJECT
public:
PsNotifyWindow(HistoryItem *item, int32 x, int32 y);
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);
void mousePressEvent(QMouseEvent *e);
void paintEvent(QPaintEvent *e);
bool animStep(float64 ms);
void animHide(float64 duration, anim::transition func);
void startHiding();
void stopHiding();
void moveTo(int32 x, int32 y, int32 index = -1);
void updatePeerPhoto();
int32 index() const {
return history ? _index : -1;
}
~PsNotifyWindow();
public slots:
void hideByTimer();
void checkLastInput();
void unlinkHistory(History *hist = 0);
private:
// DWORD started;
History *history;
IconedButton close;
QPixmap pm;
float64 alphaDuration, posDuration;
QTimer hideTimer, inputTimer;
bool hiding;
int32 _index;
anim::fvalue aOpacity;
anim::transition aOpacityFunc;
anim::ivalue aY;
ImagePtr peerPhoto;
};
typedef QList<PsNotifyWindow*> PsNotifyWindows;
class PsMainWindow : public QMainWindow {
Q_OBJECT
public:
PsMainWindow(QWidget *parent = 0);
int32 psResizeRowWidth() const {
return 0;//st::wndResizeAreaWidth;
}
void psInitFrameless();
void psInitSize();
void psFirstShow();
void psInitSysMenu();
void psUpdateSysMenu(Qt::WindowState state);
void psUpdateMargins();
void psUpdatedPosition();
bool psHandleTitle();
void psFlash();
void psNotifySettingGot();
bool psIsActive(int state = -1) const;
bool psIsOnline(int state) const;
void psUpdateWorkmode();
void psRefreshTaskbarIcon();
virtual bool minimizeToTray() {
return false;
}
void psNotify(History *history, MsgId msgId);
void psClearNotify(History *history = 0);
void psClearNotifyFast();
void psShowNextNotify(PsNotifyWindow *remove = 0);
void psActivateNotifies();
void psStopHiding();
void psStartHiding();
void psUpdateNotifies();
bool psPosInited() const {
return posInited;
}
~PsMainWindow();
public slots:
void psStateChanged(Qt::WindowState state);
void psUpdateCounter();
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
void psIdleTimeout();
void psNotifyFire();
protected:
void psNotIdle() const;
bool posInited;
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
QImage icon256;
virtual void setupTrayIcon() {
}
typedef QMap<MsgId, uint64> NotifyWhenMap;
typedef QMap<History*, NotifyWhenMap> NotifyWhenMaps;
NotifyWhenMaps notifyWhenMaps;
struct NotifyWaiter {
NotifyWaiter(MsgId msg, uint64 when) : msg(msg), when(when) {
}
MsgId msg;
uint64 when;
};
typedef QMap<History*, NotifyWaiter> NotifyWaiters;
NotifyWaiters notifyWaiters;
NotifyWaiters notifySettingWaiters;
QTimer notifyWaitTimer;
typedef QSet<uint64> NotifyWhenAlert;
typedef QMap<History*, NotifyWhenAlert> NotifyWhenAlerts;
NotifyWhenAlerts notifyWhenAlerts;
PsNotifyWindows notifyWindows;
QTimer psUpdatedPositionTimer;
private:
mutable bool psIdle;
mutable QTimer psIdleTimer;
};
class PsApplication : public QApplication {
Q_OBJECT
public:
PsApplication(int &argc, char **argv);
void psInstallEventFilter();
~PsApplication();
signals:
void updateChecking();
void updateLatest();
void updateDownloading(qint64 ready, qint64 total);
void updateReady();
void updateFailed();
};
class PsUpdateDownloader : public QObject {
Q_OBJECT
public:
PsUpdateDownloader(QThread *thread, const MTPDhelp_appUpdate &update);
PsUpdateDownloader(QThread *thread, const QString &url);
void unpackUpdate();
int32 ready();
int32 size();
static void deleteDir(const QString &dir);
static void clearAll();
~PsUpdateDownloader();
public slots:
void start();
void partMetaGot();
void partFinished(qint64 got, qint64 total);
void partFailed(QNetworkReply::NetworkError e);
void sendRequest();
private:
void initOutput();
void fatalFail();
QString updateUrl;
QNetworkAccessManager manager;
QNetworkReply *reply;
int32 already, full;
QFile outputFile;
QMutex mutex;
};
void psActivateProcess(uint64 pid);
QString psLocalServerPrefix();
QString psCurrentCountry();
QString psCurrentLanguage();
QString psAppDataPath();
QString psCurrentExeDirectory(int argc, char *argv[]);
void psAutoStart(bool start, bool silent = false);
int psCleanup();
int psFixPrevious();
bool psCheckReadyUpdate();
void psExecUpdater();
void psExecTelegram();
void psPostprocessFile(const QString &name);
void psOpenFile(const QString &name, bool openWith = false);
void psShowInFolder(const QString &name);
void psFinish();

View File

@ -68,8 +68,11 @@ QString gLangFile;
bool gRetina = false;
float64 gRetinaFactor = 1.;
int32 gIntRetinaFactor = 1;
#ifdef Q_OS_MAC
bool gCustomNotifies = false;
#else
bool gCustomNotifies = true;
#endif
uint64 gInstance = 0.;
#ifdef Q_OS_WIN

View File

@ -23,3 +23,6 @@ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
Q_IMPORT_PLUGIN(QWindowsAudioPlugin)
Q_IMPORT_PLUGIN(AccessibleFactory)
#endif
#ifdef Q_OS_LINUX
Q_IMPORT_PLUGIN(QPulseAudioPlugin)
#endif

View File

@ -77,7 +77,7 @@ TitleWidget::TitleWidget(Window *window)
connect(wnd->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(stateChanged(Qt::WindowState)));
connect(App::app(), SIGNAL(updateReady()), this, SLOT(showUpdateBtn()));
if (cPlatform() == dbipMac) {
if (cPlatform() != dbipWindows) {
_minimize.hide();
_maximize.hide();
_restore.hide();
@ -127,7 +127,7 @@ TitleWidget::~TitleWidget() {
void TitleWidget::resizeEvent(QResizeEvent *e) {
QPoint p(width() - ((cPlatform() == dbipWindows && lastMaximized) ? 0 : st::sysBtnDelta), 0);
if (cPlatform() != dbipMac) {
if (cPlatform() == dbipWindows) {
p.setX(p.x() - _close.width());
_close.move(p);

View File

@ -17,11 +17,10 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
*/
#include "stdafx.h"
#ifdef Q_OS_MAC
#ifdef Q_OS_WIN
#elif defined Q_OS_MAC
#include <mach/mach_time.h>
#endif
#ifdef Q_OS_LINUX
#else
#include <time.h>
#endif
@ -175,8 +174,10 @@ namespace {
_msStart = mach_absolute_time();
#else
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
_msStart = 1000000000 * uint64(ts.tv_sec) + uint64(ts.tv_nsec);
clock_gettime(CLOCK_MONOTONIC, &ts);
//_msFreq = 1 / 1000000.;
_msgIdCoef = float64(0xFFFF0000L) / 1000000000.;
_msStart = 1000 * uint64(ts.tv_sec) + (uint64(ts.tv_nsec) / 1000000);
#endif
srand((uint32)(_msStart & 0xFFFFFFFFL));
@ -217,13 +218,13 @@ uint64 getms() {
return (uint64)((msCount - _msStart) * _msFreq);
#else
timespec ts;
int res = clock_gettime(CLOCK_REALTIME, &ts);
int res = clock_gettime(CLOCK_MONOTONIC, &ts);
if (res != 0) {
LOG(("Bad clock_gettime result: %1").arg(res));
return 0;
}
uint64 msCount = 1000000000 * uint64(ts.tv_sec) + uint64(ts.tv_nsec);
return (uint64)((msCount - _msStart) / 1000000);
uint64 msCount = 1000 * uint64(ts.tv_sec) + (uint64(ts.tv_nsec) / 1000000);
return (uint64)(msCount - _msStart);
#endif
}
@ -236,8 +237,10 @@ uint64 msgid() {
uint64 msCount = mach_absolute_time();
uint64 result = _msgIdStart + (uint64)floor((msCount - _msgIdMsStart) * _msgIdCoef);
#else
uint64 result = 0;
//TODO
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64 msCount = 1000000000 * uint64(ts.tv_sec) + uint64(ts.tv_nsec);
uint64 result = _msgIdStart + (uint64)floor((msCount - _msgIdMsStart) * _msgIdCoef);
#endif
result &= ~0x03L;

View File

@ -1,17 +1,19 @@
QT += core gui widgets network multimedia
QT += core gui network multimedia widgets
CONFIG += plugin static
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
OBJECTS_DIR = ./../Mac/DebugIntermediate
OBJECTS_DIR = ./../Linux/DebugIntermediate
MOC_DIR = ./GeneratedFiles/Debug
RCC_DIR = ./GeneratedFiles
DESTDIR = ./../Mac/Debug
DESTDIR = ./../Linux/Debug
}
CONFIG(release, debug|release) {
OBJECTS_DIR = ./../Mac/ReleaseIntermediate
OBJECTS_DIR = ./../Linux/ReleaseIntermediate
MOC_DIR = ./GeneratedFiles/Release
RCC_DIR = ./GeneratedFiles
DESTDIR = ./../Mac/Release
DESTDIR = ./../Linux/Release
}
macx {
@ -21,6 +23,11 @@ macx {
QMAKE_LFLAGS += -framework Cocoa
}
linux {
SOURCES += ./SourceFiles/pspecific_linux.cpp
HEADERS += ./SourceFiles/pspecific_linux.h
}
SOURCES += \
./SourceFiles/main.cpp \
./SourceFiles/stdafx.cpp \
@ -180,17 +187,19 @@ CONFIG += precompile_header
PRECOMPILED_HEADER = ./SourceFiles/stdafx.h
INCLUDEPATH += ./../../Libraries/QtStatic/qtbase/include/QtGui/5.3.0/QtGui\
./../../Libraries/QtStatic/qtbase/include/QtCore/5.3.0/QtCore\
QMAKE_CXXFLAGS += -fno-strict-aliasing
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter -Wno-unused-variable -Wno-switch -Wno-comment -Wno-unused-but-set-variable
INCLUDEPATH += ./../../Libraries/QtStatic/qtbase/include/QtGui/5.3.1/QtGui\
./../../Libraries/QtStatic/qtbase/include/QtCore/5.3.1/QtCore\
./../../Libraries/QtStatic/qtbase/include\
./SourceFiles\
./GeneratedFiles\
./../../Libraries/lzma/C\
./../../Libraries/libexif-0.6.20
LIBS += -lcrypto -lssl -lz
./../../Libraries/libexif-0.6.20\
/usr/local/ssl/include
LIBS += -L/usr/local/ssl/lib -lcrypto -lssl -lz -ldl -llzma
LIBS += ./../../Libraries/libexif-0.6.20/libexif/.libs/libexif.a
LIBS += ./../../Libraries/QtStatic/qtmultimedia/plugins/audio/libqtmedia_pulse.a
RESOURCES += \
./SourceFiles/telegram.qrc

View File

@ -0,0 +1,490 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qbasicfontdatabase_p.h"
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformscreen.h>
#include <QtCore/QFile>
#include <QtCore/QLibraryInfo>
#include <QtCore/QDir>
#include <QtCore/QUuid>
#include <QtCore/QtEndian>
#undef QT_NO_FREETYPE
#include <QtGui/private/qfontengine_ft_p.h>
#include <QtGui/private/qfontengine_p.h>
#include <ft2build.h>
#include FT_TRUETYPE_TABLES_H
#include FT_ERRORS_H
QT_BEGIN_NAMESPACE
typedef struct {
quint16 majorVersion;
quint16 minorVersion;
quint16 numTables;
quint16 searchRange;
quint16 entrySelector;
quint16 rangeShift;
} OFFSET_TABLE;
typedef struct {
quint32 tag;
quint32 checkSum;
quint32 offset;
quint32 length;
} TABLE_DIRECTORY;
typedef struct {
quint16 fontSelector;
quint16 nrCount;
quint16 storageOffset;
} NAME_TABLE_HEADER;
typedef struct {
quint16 platformID;
quint16 encodingID;
quint16 languageID;
quint16 nameID;
quint16 stringLength;
quint16 stringOffset;
} NAME_RECORD;
void QBasicFontDatabase::populateFontDatabase()
{
QString fontpath = fontDir();
if(!QFile::exists(fontpath)) {
qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
qPrintable(fontpath));
}
QDir dir(fontpath);
dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
<< QLatin1String("*.ttc") << QLatin1String("*.pfa")
<< QLatin1String("*.pfb")
<< QLatin1String("*.otf"));
dir.refresh();
for (int i = 0; i < int(dir.count()); ++i) {
const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
// qDebug() << "looking at" << file;
addTTFile(QByteArray(), file);
}
}
QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
fid.filename = QFile::encodeName(fontfile->fileName);
fid.index = fontfile->indexValue;
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
QFontEngineFT *engine = new QFontEngineFT(fontDef);
if (!engine->init(fid, antialias, format) || engine->invalid()) {
delete engine;
engine = 0;
}
return engine;
}
namespace {
class QFontEngineFTRawData: public QFontEngineFT
{
public:
QFontEngineFTRawData(const QFontDef &fontDef) : QFontEngineFT(fontDef)
{
}
void updateFamilyNameAndStyle()
{
fontDef.family = QString::fromLatin1(freetype->face->family_name);
if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)
fontDef.style = QFont::StyleItalic;
if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD)
fontDef.weight = QFont::Bold;
}
bool initFromData(const QByteArray &fontData)
{
FaceId faceId;
faceId.filename = "";
faceId.index = 0;
faceId.uuid = QUuid::createUuid().toByteArray();
return init(faceId, true, Format_None, fontData);
}
};
}
QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
fontDef.hintingPreference = hintingPreference;
QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
if (!fe->initFromData(fontData)) {
delete fe;
return 0;
}
fe->updateFamilyNameAndStyle();
switch (hintingPreference) {
case QFont::PreferNoHinting:
fe->setDefaultHintStyle(QFontEngineFT::HintNone);
break;
case QFont::PreferFullHinting:
fe->setDefaultHintStyle(QFontEngineFT::HintFull);
break;
case QFont::PreferVerticalHinting:
fe->setDefaultHintStyle(QFontEngineFT::HintLight);
break;
default:
// Leave it as it is
break;
}
return fe;
}
QStringList QBasicFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
Q_UNUSED(family);
Q_UNUSED(style);
Q_UNUSED(script);
Q_UNUSED(styleHint);
return QStringList();
}
QStringList QBasicFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
return addTTFile(fontData,fileName.toLocal8Bit());
}
void QBasicFontDatabase::releaseHandle(void *handle)
{
FontFile *file = static_cast<FontFile *>(handle);
delete file;
}
extern FT_Library qt_getFreetype();
// copied from freetype with some modifications
#ifndef FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY
#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG('i', 'g', 'p', 'f')
#endif
#ifndef FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY
#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG('i', 'g', 'p', 's')
#endif
/* there's a Mac-specific extended implementation of FT_New_Face() */
/* in src/base/ftmac.c */
#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
/* documentation is in freetype.h */
FT_Error __ft_New_Face(FT_Library library, const char* pathname, FT_Long face_index, FT_Face *aface) {
FT_Open_Args args;
/* test for valid `library' and `aface' delayed to FT_Open_Face() */
if ( !pathname )
return FT_Err_Invalid_Argument;
FT_Parameter params[2];
params[0].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY;
params[0].data = 0;
params[1].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY;
params[1].data = 0;
args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;
args.pathname = (char*)pathname;
args.stream = NULL;
args.num_params = 2;
args.params = params;
return FT_Open_Face( library, &args, face_index, aface );
}
#else
FT_Error __ft_New_Face(FT_Library library, const char* pathname, FT_Long face_index, FT_Face *aface) {
return FT_New_Face(library, pathname, face_index, aface);
}
#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */
/* documentation is in freetype.h */
FT_Error __ft_New_Memory_Face(FT_Library library, const FT_Byte* file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface) {
FT_Open_Args args;
/* test for valid `library' and `face' delayed to FT_Open_Face() */
if ( !file_base )
return FT_Err_Invalid_Argument;
FT_Parameter params[2];
params[0].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY;
params[0].data = 0;
params[1].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY;
params[1].data = 0;
args.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS;
args.memory_base = file_base;
args.memory_size = file_size;
args.stream = NULL;
args.num_params = 2;
args.params = params;
return FT_Open_Face( library, &args, face_index, aface );
}
// end
QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems)
{
FT_Library library = qt_getFreetype();
int index = 0;
int numFaces = 0;
QStringList families;
do {
FT_Face face;
FT_Error error;
if (!fontData.isEmpty()) {
error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
} else {
error = __ft_New_Face(library, file.constData(), index, &face);
}
if (error != FT_Err_Ok) {
qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
break;
}
numFaces = face->num_faces;
QFont::Weight weight = QFont::Normal;
QFont::Style style = QFont::StyleNormal;
if (face->style_flags & FT_STYLE_FLAG_ITALIC)
style = QFont::StyleItalic;
if (face->style_flags & FT_STYLE_FLAG_BOLD)
weight = QFont::Bold;
bool fixedPitch = (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
QSupportedWritingSystems writingSystems;
// detect symbol fonts
for (int i = 0; i < face->num_charmaps; ++i) {
FT_CharMap cm = face->charmaps[i];
if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
|| cm->encoding == FT_ENCODING_MS_SYMBOL) {
writingSystems.setSupported(QFontDatabase::Symbol);
if (supportedWritingSystems)
supportedWritingSystems->setSupported(QFontDatabase::Symbol);
break;
}
}
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
if (os2) {
quint32 unicodeRange[4] = {
quint32(os2->ulUnicodeRange1),
quint32(os2->ulUnicodeRange2),
quint32(os2->ulUnicodeRange3),
quint32(os2->ulUnicodeRange4)
};
quint32 codePageRange[2] = {
quint32(os2->ulCodePageRange1),
quint32(os2->ulCodePageRange2)
};
writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
if (supportedWritingSystems)
*supportedWritingSystems = writingSystems;
if (os2->usWeightClass == 0)
;
else if (os2->usWeightClass < 350)
weight = QFont::Light;
else if (os2->usWeightClass < 450)
weight = QFont::Normal;
else if (os2->usWeightClass < 650)
weight = QFont::DemiBold;
else if (os2->usWeightClass < 750)
weight = QFont::Bold;
else if (os2->usWeightClass < 1000)
weight = QFont::Black;
if (os2->panose[2] >= 2) {
int w = os2->panose[2];
if (w <= 3)
weight = QFont::Light;
else if (w <= 5)
weight = QFont::Normal;
else if (w <= 7)
weight = QFont::DemiBold;
else if (w <= 8)
weight = QFont::Bold;
else if (w <= 10)
weight = QFont::Black;
}
}
QString family = QString::fromLatin1(face->family_name);
FontFile *fontFile = new FontFile;
fontFile->fileName = QFile::decodeName(file);
fontFile->indexValue = index;
QFont::Stretch stretch = QFont::Unstretched;
registerFont(family,QString::fromLatin1(face->style_name),QString(),weight,style,stretch,true,true,0,fixedPitch,writingSystems,fontFile);
families.append(family);
FT_Done_Face(face);
++index;
} while (index < numFaces);
return families;
}
QString QBasicFontDatabase::fontNameFromTTFile(const QString &filename)
{
QFile f(filename);
QString retVal;
qint64 bytesRead;
qint64 bytesToRead;
if (f.open(QIODevice::ReadOnly)) {
OFFSET_TABLE ttOffsetTable;
bytesToRead = sizeof(OFFSET_TABLE);
bytesRead = f.read((char*)&ttOffsetTable, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
ttOffsetTable.numTables = qFromBigEndian(ttOffsetTable.numTables);
ttOffsetTable.majorVersion = qFromBigEndian(ttOffsetTable.majorVersion);
ttOffsetTable.minorVersion = qFromBigEndian(ttOffsetTable.minorVersion);
if (ttOffsetTable.majorVersion != 1 || ttOffsetTable.minorVersion != 0)
return retVal;
TABLE_DIRECTORY tblDir;
bool found = false;
for (int i = 0; i < ttOffsetTable.numTables; i++) {
bytesToRead = sizeof(TABLE_DIRECTORY);
bytesRead = f.read((char*)&tblDir, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
if (qFromBigEndian(tblDir.tag) == MAKE_TAG('n', 'a', 'm', 'e')) {
found = true;
tblDir.length = qFromBigEndian(tblDir.length);
tblDir.offset = qFromBigEndian(tblDir.offset);
break;
}
}
if (found) {
f.seek(tblDir.offset);
NAME_TABLE_HEADER ttNTHeader;
bytesToRead = sizeof(NAME_TABLE_HEADER);
bytesRead = f.read((char*)&ttNTHeader, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
ttNTHeader.nrCount = qFromBigEndian(ttNTHeader.nrCount);
ttNTHeader.storageOffset = qFromBigEndian(ttNTHeader.storageOffset);
NAME_RECORD ttRecord;
found = false;
for (int i = 0; i < ttNTHeader.nrCount; i++) {
bytesToRead = sizeof(NAME_RECORD);
bytesRead = f.read((char*)&ttRecord, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
ttRecord.nameID = qFromBigEndian(ttRecord.nameID);
if (ttRecord.nameID == 1) {
ttRecord.stringLength = qFromBigEndian(ttRecord.stringLength);
ttRecord.stringOffset = qFromBigEndian(ttRecord.stringOffset);
int nPos = f.pos();
f.seek(tblDir.offset + ttRecord.stringOffset + ttNTHeader.storageOffset);
QByteArray nameByteArray = f.read(ttRecord.stringLength);
if (!nameByteArray.isEmpty()) {
if (ttRecord.encodingID == 256 || ttRecord.encodingID == 768) {
//This is UTF-16 in big endian
int stringLength = ttRecord.stringLength / 2;
retVal.resize(stringLength);
QChar *data = retVal.data();
const ushort *srcData = (const ushort *)nameByteArray.data();
for (int i = 0; i < stringLength; ++i)
data[i] = qFromBigEndian(srcData[i]);
return retVal;
} else if (ttRecord.encodingID == 0) {
//This is Latin1
retVal = QString::fromLatin1(nameByteArray);
} else {
qWarning("Could not retrieve Font name from file: %s", qPrintable(QDir::toNativeSeparators(filename)));
}
break;
}
f.seek(nPos);
}
}
}
f.close();
}
return retVal;
}
QT_END_NAMESPACE

View File

@ -1,16 +1,11 @@
// This file is autogenerated by qmake. It imports static plugin classes for
// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables.
#include <QtPlugin>
//Q_IMPORT_PLUGIN(AVFServicePlugin)
Q_IMPORT_PLUGIN(AVFMediaPlayerServicePlugin)
Q_IMPORT_PLUGIN(QT7ServicePlugin)
Q_IMPORT_PLUGIN(AudioCaptureServicePlugin)
Q_IMPORT_PLUGIN(CoreAudioPlugin)
Q_IMPORT_PLUGIN(QM3uPlaylistPlugin)
Q_IMPORT_PLUGIN(AccessibleFactory)
Q_IMPORT_PLUGIN(QCoreWlanEnginePlugin)
Q_IMPORT_PLUGIN(QGenericEnginePlugin)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
Q_IMPORT_PLUGIN(QDDSPlugin)
Q_IMPORT_PLUGIN(QICNSPlugin)
Q_IMPORT_PLUGIN(QICOPlugin)