Remove unused Mac specific font code in widgets

Change-Id: If7a81b8b59aedcc0ba54c735787a220bab9ca535
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
Jiang Jiang 2011-12-01 11:30:35 +01:00 committed by Qt by Nokia
parent d05b6b6e95
commit 25be03f046
6 changed files with 0 additions and 1427 deletions

View File

@ -1,150 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfont.h"
#include "qfont_p.h"
#include "qfontengine_p.h"
#include "qfontengine_mac_p.h"
#include "qfontengine_coretext_p.h"
#include "qfontinfo.h"
#include "qfontmetrics.h"
#include "qpaintdevice.h"
#include "qstring.h"
#include <private/qt_mac_p.h>
#include <private/qtextengine_p.h>
#include <private/qunicodetables_p.h>
#include <qapplication.h>
#include "qfontdatabase.h"
#include <qpainter.h>
#include "qtextengine_p.h"
#include <stdlib.h>
QT_BEGIN_NAMESPACE
extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
int qt_mac_pixelsize(const QFontDef &def, int dpi)
{
float ret;
if(def.pixelSize == -1)
ret = def.pointSize * dpi / qt_mac_defaultDpi_x();
else
ret = def.pixelSize;
return qRound(ret);
}
int qt_mac_pointsize(const QFontDef &def, int dpi)
{
float ret;
if(def.pointSize < 0)
ret = def.pixelSize * qt_mac_defaultDpi_x() / float(dpi);
else
ret = def.pointSize;
return qRound(ret);
}
QString QFont::rawName() const
{
return family();
}
void QFont::setRawName(const QString &name)
{
setFamily(name);
}
void QFont::cleanup()
{
QFontCache::cleanup();
}
/*!
Returns an ATSUFontID
*/
quint32 QFont::macFontID() const // ### need 64-bit version
{
return 0;
}
// Returns an ATSUFonFamilyRef
Qt::HANDLE QFont::handle() const
{
QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
if (fe && fe->type() == QFontEngine::Multi)
return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID();
return 0;
}
void QFont::initialize()
{ }
QString QFont::defaultFamily() const
{
switch(d->request.styleHint) {
case QFont::Times:
return QString::fromLatin1("Times New Roman");
case QFont::Courier:
return QString::fromLatin1("Courier New");
case QFont::Monospace:
return QString::fromLatin1("Courier");
case QFont::Decorative:
return QString::fromLatin1("Bookman Old Style");
case QFont::Cursive:
return QString::fromLatin1("Apple Chancery");
case QFont::Fantasy:
return QString::fromLatin1("Papyrus");
case QFont::Helvetica:
case QFont::System:
default:
return QString::fromLatin1("Helvetica");
}
}
QString QFont::lastResortFamily() const
{
return QString::fromLatin1("Helvetica");
}
QString QFont::lastResortFont() const
{
return QString::fromLatin1("Geneva");
}
QT_END_NAMESPACE

View File

@ -1,370 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <private/qt_mac_p.h>
#include "qfontengine_p.h"
#include <qfile.h>
#include <qabstractfileengine.h>
#include <stdlib.h>
#include <qendian.h>
#include <private/qfontengine_coretext_p.h>
#include <private/qfontengine_mac_p.h>
QT_BEGIN_NAMESPACE
int qt_mac_pixelsize(const QFontDef &def, int dpi); //qfont_mac.cpp
int qt_mac_pointsize(const QFontDef &def, int dpi); //qfont_mac.cpp
static void initializeDb()
{
QFontDatabasePrivate *db = privateDb();
if(!db || db->count)
return;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
if(!collection)
return;
QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
if(!fonts)
return;
QString foundry_name = "CoreText";
const int numFonts = CFArrayGetCount(fonts);
for(int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
QCFString style_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
QtFontFamily *family = db->family(family_name, true);
for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws)
family->writingSystems[ws] = QtFontFamily::Supported;
QtFontFoundry *foundry = family->foundry(foundry_name, true);
QtFontStyle::Key styleKey;
QString styleName = style_name;
if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
Q_ASSERT(CFNumberIsFloatType(weight));
double d;
if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) {
//qDebug() << "BOLD" << (QString)family_name << d;
styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
}
}
if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
Q_ASSERT(CFNumberIsFloatType(italic));
double d;
if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
//qDebug() << "ITALIC" << (QString)family_name << d;
if (d > 0.0)
styleKey.style = QFont::StyleItalic;
}
}
}
QtFontStyle *style = foundry->style(styleKey, styleName, true);
style->smoothScalable = true;
if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
//qDebug() << "WHEE";
int pixel_size=0;
if(CFNumberIsFloatType(size)) {
double d;
CFNumberGetValue(size, kCFNumberDoubleType, &d);
pixel_size = d;
} else {
CFNumberGetValue(size, kCFNumberIntType, &pixel_size);
}
//qDebug() << "SIZE" << (QString)family_name << pixel_size;
if(pixel_size)
style->pixelSize(pixel_size, true);
} else {
//qDebug() << "WTF?";
}
}
} else
#endif
{
}
}
static inline void load(const QString & = QString(), int = -1)
{
initializeDb();
}
static const char *styleHint(const QFontDef &request)
{
const char *stylehint = 0;
switch (request.styleHint) {
case QFont::SansSerif:
stylehint = "Arial";
break;
case QFont::Serif:
stylehint = "Times New Roman";
break;
case QFont::TypeWriter:
stylehint = "Courier New";
break;
default:
if (request.fixedPitch)
stylehint = "Courier New";
break;
}
return stylehint;
}
static inline float weightToFloat(unsigned int weight)
{
return (weight - 50) / 100.0;
}
static QFontEngine *loadFromDatabase(const QFontDef &req, const QFontPrivate *d)
{
QCFString fontName = NULL;
QStringList family_list = familyList(req);
const char *stylehint = styleHint(req);
if (stylehint)
family_list << QLatin1String(stylehint);
// add QFont::defaultFamily() to the list, for compatibility with previous versions
family_list << QApplication::font().defaultFamily();
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
if (!db->count)
initializeDb();
for (int i = 0; i < family_list.size(); ++i) {
for (int k = 0; k < db->count; ++k) {
if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
QByteArray family_name = db->families[k]->name.toUtf8();
QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
if (ctFont) {
fontName = CTFontCopyFullName(ctFont);
goto found;
}
}
}
}
found:
if (fontName)
return new QCoreTextFontEngineMulti(fontName, req, d->kerning);
return NULL;
}
void QFontDatabase::load(const QFontPrivate *d, int script)
{
// sanity checks
if(!qApp)
qWarning("QFont: Must construct a QApplication before a QFont");
Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
Q_UNUSED(script);
QFontDef req = d->request;
req.pixelSize = qt_mac_pixelsize(req, d->dpi);
// set the point size to 0 to get better caching
req.pointSize = 0;
QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen);
if(!(d->engineData = QFontCache::instance()->findEngineData(key))) {
d->engineData = new QFontEngineData;
QFontCache::instance()->insertEngineData(key, d->engineData);
} else {
d->engineData->ref.ref();
}
if(d->engineData->engine) // already loaded
return;
// set it to the actual pointsize, so QFontInfo will do the right thing
req.pointSize = qt_mac_pointsize(d->request, d->dpi);
QFontEngine *e = QFontCache::instance()->findEngine(key);
if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
e = new QTestFontEngine(req.pixelSize);
e->fontDef = req;
}
if(e) {
e->ref.ref();
d->engineData->engine = e;
return; // the font info and fontdef should already be filled
}
QFontEngine *engine = NULL;
// Shortcut to get the font directly without going through the font database
if (!req.family.isEmpty() && !req.styleName.isEmpty()) {
QCFString expectedFamily = QCFString(req.family);
QCFString expectedStyle = QCFString(req.styleName);
QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily);
CFDictionaryAddValue(attributes, kCTFontStyleNameAttribute, expectedStyle);
QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
CGAffineTransform transform = qt_transform_from_fontdef(req);
QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, req.pixelSize, &transform);
if (ctFont) {
QCFString familyName = CTFontCopyFamilyName(ctFont);
// Only accept the font if the family name is exactly the same as we specified
if (CFEqual(expectedFamily, familyName)) {
engine = new QCoreTextFontEngineMulti(ctFont, req, d->kerning);
}
}
}
if (!engine)
engine = loadFromDatabase(req, d);
if (engine) {
d->engineData->engine = engine;
engine->ref.ref();
QFontCache::instance()->insertEngine(key, engine);
}
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
ATSFontContainerRef handle;
OSStatus e = noErr;
if(fnt->data.isEmpty()) {
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
FSRef ref;
if(qt_mac_create_fsref(fnt->fileName, &ref) != noErr)
return;
ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
} else
#endif
{
#ifndef Q_WS_MAC64
extern Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &, FSSpec *); // global.cpp
FSSpec spec;
if(qt_mac_create_fsspec(fnt->fileName, &spec) != noErr)
return;
e = ATSFontActivateFromFileSpecification(&spec, kATSFontContextLocal, kATSFontFormatUnspecified,
0, kATSOptionFlagsDefault, &handle);
#endif
}
} else {
e = ATSFontActivateFromMemory((void *)fnt->data.constData(), fnt->data.size(), kATSFontContextLocal,
kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
fnt->data = QByteArray();
}
if(e != noErr)
return;
ItemCount fontCount = 0;
e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, 0, 0, &fontCount);
if(e != noErr)
return;
QVarLengthArray<ATSFontRef> containedFonts(fontCount);
e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
if(e != noErr)
return;
fnt->families.clear();
// Make sure that the family name set on the font matches what
// kCTFontFamilyNameAttribute returns in initializeDb().
// So far the best solution seems find the installed font
// using CoreText and get the family name from it.
// (ATSFontFamilyGetName appears to be the correct API, but also
// returns the font display name.)
for(int i = 0; i < containedFonts.size(); ++i) {
QCFString fontPostScriptName;
ATSFontGetPostScriptName(containedFonts[i], kATSOptionFlagsDefault, &fontPostScriptName);
QCFType<CTFontDescriptorRef> font = CTFontDescriptorCreateWithNameAndSize(fontPostScriptName, 14);
QCFString familyName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
fnt->families.append(familyName);
}
fnt->handle = handle;
}
bool QFontDatabase::removeApplicationFont(int handle)
{
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
if(handle < 0 || handle >= db->applicationFonts.count())
return false;
OSStatus e = ATSFontDeactivate(db->applicationFonts.at(handle).handle,
/*iRefCon=*/0, kATSOptionFlagsDefault);
if(e != noErr)
return false;
db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
db->invalidate();
return true;
}
bool QFontDatabase::removeAllApplicationFonts()
{
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
for(int i = 0; i < db->applicationFonts.count(); ++i) {
if(!removeApplicationFont(i))
return false;
}
return true;
}
bool QFontDatabase::supportsThreadedFontRendering()
{
return true;
}
QT_END_NAMESPACE

View File

@ -1,124 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfontengine_mac_p.h"
#include <private/qapplication_p.h>
#include <private/qfontengine_p.h>
#include <private/qpainter_p.h>
#include <private/qtextengine_p.h>
#include <qbitmap.h>
#include <private/qpaintengine_mac_p.h>
#include <private/qprintengine_mac_p.h>
#include <qglobal.h>
#include <qpixmap.h>
#include <qpixmapcache.h>
#include <qvarlengtharray.h>
#include <qdebug.h>
#include <qendian.h>
#include <qmath.h>
#include <private/qimage_p.h>
#include <ApplicationServices/ApplicationServices.h>
#include <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
/*****************************************************************************
QFontEngine debug facilities
*****************************************************************************/
//#define DEBUG_ADVANCES
extern int qt_antialiasing_threshold; // QApplication.cpp
#ifndef FixedToQFixed
#define FixedToQFixed(a) QFixed::fromFixed((a) >> 10)
#define QFixedToFixed(x) ((x).value() << 10)
#endif
class QMacFontPath
{
float x, y;
QPainterPath *path;
public:
inline QMacFontPath(float _x, float _y, QPainterPath *_path) : x(_x), y(_y), path(_path) { }
inline void setPosition(float _x, float _y) { x = _x; y = _y; }
inline void advance(float _x) { x += _x; }
static OSStatus lineTo(const Float32Point *, void *);
static OSStatus cubicTo(const Float32Point *, const Float32Point *,
const Float32Point *, void *);
static OSStatus moveTo(const Float32Point *, void *);
static OSStatus closePath(void *);
};
OSStatus QMacFontPath::lineTo(const Float32Point *pt, void *data)
{
QMacFontPath *p = static_cast<QMacFontPath*>(data);
p->path->lineTo(p->x + pt->x, p->y + pt->y);
return noErr;
}
OSStatus QMacFontPath::cubicTo(const Float32Point *cp1, const Float32Point *cp2,
const Float32Point *ep, void *data)
{
QMacFontPath *p = static_cast<QMacFontPath*>(data);
p->path->cubicTo(p->x + cp1->x, p->y + cp1->y,
p->x + cp2->x, p->y + cp2->y,
p->x + ep->x, p->y + ep->y);
return noErr;
}
OSStatus QMacFontPath::moveTo(const Float32Point *pt, void *data)
{
QMacFontPath *p = static_cast<QMacFontPath*>(data);
p->path->moveTo(p->x + pt->x, p->y + pt->y);
return noErr;
}
OSStatus QMacFontPath::closePath(void *data)
{
static_cast<QMacFontPath*>(data)->path->closeSubpath();
return noErr;
}
QT_END_NAMESPACE

View File

@ -1,48 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QFONTENGINE_MAC_P_H
#define QFONTENGINE_MAC_P_H
#include <private/qfontengine_p.h>
#endif // QFONTENGINE_MAC_P_H

View File

@ -1,83 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qglobal.h>
#if !defined(QT_NO_RAWFONT)
#include "qrawfont_p.h"
#include "qfontengine_coretext_p.h"
QT_BEGIN_NAMESPACE
void QRawFontPrivate::platformCleanUp()
{
}
extern int qt_defaultDpi();
void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
// Mac OS X ignores it
Q_UNUSED(hintingPreference);
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(NULL,
fontData.constData(), fontData.size(), NULL);
CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider);
if (cgFont == NULL) {
qWarning("QRawFont::platformLoadFromData: CGFontCreateWithDataProvider failed");
} else {
QFontDef def;
def.pixelSize = pixelSize;
def.pointSize = pixelSize * 72.0 / qt_defaultDpi();
fontEngine = new QCoreTextFontEngine(cgFont, def);
CFRelease(cgFont);
fontEngine->ref.ref();
}
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -1,652 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtextengine_p.h"
#include <private/qfontengine_coretext_p.h>
#include <private/qfontengine_mac_p.h>
QT_BEGIN_NAMESPACE
// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs
// and no reordering.
// also computes logClusters heuristically
static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayout *glyphs, unsigned short *logClusters, int num_glyphs)
{
// ### zeroWidth and justification are missing here!!!!!
Q_UNUSED(num_glyphs);
// qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
const bool symbolFont = false; // ####
glyphs->attributes[0].mark = false;
glyphs->attributes[0].clusterStart = true;
glyphs->attributes[0].dontPrint = (!symbolFont && uc[0].unicode() == 0x00ad) || qIsControlChar(uc[0].unicode());
int pos = 0;
int lastCat = QChar::category(uc[0].unicode());
for (int i = 1; i < length; ++i) {
if (logClusters[i] == pos)
// same glyph
continue;
++pos;
while (pos < logClusters[i]) {
++pos;
}
// hide soft-hyphens by default
if ((!symbolFont && uc[i].unicode() == 0x00ad) || qIsControlChar(uc[i].unicode()))
glyphs->attributes[pos].dontPrint = true;
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc[i].unicode());
int cat = prop->category;
// one gets an inter character justification point if the current char is not a non spacing mark.
// as then the current char belongs to the last one and one gets a space justification point
// after the space char.
if (lastCat == QChar::Separator_Space)
glyphs->attributes[pos-1].justification = HB_Space;
else if (cat != QChar::Mark_NonSpacing)
glyphs->attributes[pos-1].justification = HB_Character;
else
glyphs->attributes[pos-1].justification = HB_NoJustification;
lastCat = cat;
}
pos = logClusters[length-1];
if (lastCat == QChar::Separator_Space)
glyphs->attributes[pos].justification = HB_Space;
else
glyphs->attributes[pos].justification = HB_Character;
}
struct QArabicProperties {
unsigned char shape;
unsigned char justification;
};
Q_DECLARE_TYPEINFO(QArabicProperties, Q_PRIMITIVE_TYPE);
enum QArabicShape {
XIsolated,
XFinal,
XInitial,
XMedial,
// intermediate state
XCausing
};
// these groups correspond to the groups defined in the Unicode standard.
// Some of these groups are equal with regards to both joining and line breaking behaviour,
// and thus have the same enum value
//
// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as
// I couldn't find any better document I'll hope for the best.
enum ArabicGroup {
// NonJoining
ArabicNone,
ArabicSpace,
// Transparent
Transparent,
// Causing
Center,
Kashida,
// Arabic
// Dual
Beh,
Noon,
Meem = Noon,
Heh = Noon,
KnottedHeh = Noon,
HehGoal = Noon,
SwashKaf = Noon,
Yeh,
Hah,
Seen,
Sad = Seen,
Tah,
Kaf = Tah,
Gaf = Tah,
Lam = Tah,
Ain,
Feh = Ain,
Qaf = Ain,
// Right
Alef,
Waw,
Dal,
TehMarbuta = Dal,
Reh,
HamzaOnHehGoal,
YehWithTail = HamzaOnHehGoal,
YehBarre = HamzaOnHehGoal,
// Syriac
// Dual
Beth = Beh,
Gamal = Ain,
Heth = Noon,
Teth = Hah,
Yudh = Noon,
Kaph = Noon,
Lamadh = Lam,
Mim = Noon,
Nun = Noon,
Semakh = Noon,
FinalSemakh = Noon,
SyriacE = Ain,
Pe = Ain,
ReversedPe = Hah,
Qaph = Noon,
Shin = Noon,
Fe = Ain,
// Right
Alaph = Alef,
Dalath = Dal,
He = Dal,
SyriacWaw = Waw,
Zain = Alef,
YudhHe = Waw,
Sadhe = HamzaOnHehGoal,
Taw = Dal,
// Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1.
Dummy = HamzaOnHehGoal,
ArabicGroupsEnd
};
static const unsigned char arabic_group[0x150] = {
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, Alef, Alef,
Waw, Alef, Yeh, Alef,
Beh, TehMarbuta, Beh, Beh,
Hah, Hah, Hah, Dal,
Dal, Reh, Reh, Seen,
Seen, Sad, Sad, Tah,
Tah, Ain, Ain, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
// 0x640
Kashida, Feh, Qaf, Kaf,
Lam, Meem, Noon, Heh,
Waw, Yeh, Yeh, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, Beh, Qaf,
Transparent, Alef, Alef, Alef,
ArabicNone, Alef, Waw, Waw,
Yeh, Beh, Beh, Beh,
Beh, Beh, Beh, Beh,
// 0x680
Beh, Hah, Hah, Hah,
Hah, Hah, Hah, Hah,
Dal, Dal, Dal, Dal,
Dal, Dal, Dal, Dal,
Dal, Reh, Reh, Reh,
Reh, Reh, Reh, Reh,
Reh, Reh, Seen, Seen,
Seen, Sad, Sad, Tah,
Ain, Feh, Feh, Feh,
Feh, Feh, Feh, Qaf,
Qaf, Gaf, SwashKaf, Gaf,
Kaf, Kaf, Kaf, Gaf,
Gaf, Gaf, Gaf, Gaf,
Gaf, Lam, Lam, Lam,
Lam, Noon, Noon, Noon,
Noon, Noon, KnottedHeh, Hah,
// 0x6c0
TehMarbuta, HehGoal, HamzaOnHehGoal, HamzaOnHehGoal,
Waw, Waw, Waw, Waw,
Waw, Waw, Waw, Waw,
Yeh, YehWithTail, Yeh, Waw,
Yeh, Yeh, YehBarre, YehBarre,
ArabicNone, TehMarbuta, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, ArabicNone, ArabicNone, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, ArabicNone, ArabicNone, Transparent,
Transparent, ArabicNone, Transparent, Transparent,
Transparent, Transparent, Dal, Reh,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, Seen, Sad,
Ain, ArabicNone, ArabicNone, KnottedHeh,
// 0x700
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
ArabicNone, ArabicNone, ArabicNone, ArabicNone,
Alaph, Transparent, Beth, Gamal,
Gamal, Dalath, Dalath, He,
SyriacWaw, Zain, Heth, Teth,
Teth, Yudh, YudhHe, Kaph,
Lamadh, Mim, Nun, Semakh,
FinalSemakh, SyriacE, Pe, ReversedPe,
Sadhe, Qaph, Dalath, Shin,
Taw, Beth, Gamal, Dalath,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, Transparent,
Transparent, Transparent, Transparent, ArabicNone,
ArabicNone, Zain, Kaph, Fe,
};
static inline ArabicGroup arabicGroup(unsigned short uc)
{
if (uc >= 0x0600 && uc < 0x750)
return (ArabicGroup) arabic_group[uc-0x600];
else if (uc == 0x200d)
return Center;
else if (QChar::category(uc) == QChar::Separator_Space)
return ArabicSpace;
else
return ArabicNone;
}
/*
Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on
arabic).
Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent).
transparent joining is not encoded in QChar::joining(), but applies to all combining marks and format marks.
Right join-causing: dual + center
Left join-causing: dual + right + center
Rules are as follows (for a string already in visual order, as we have it here):
R1 Transparent characters do not affect joining behaviour.
R2 A right joining character, that has a right join-causing char on the right will get form XRight
(R3 A left joining character, that has a left join-causing char on the left will get form XLeft)
Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode
R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on
the right will get form XMedial
R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left
will get form XRight
R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right
will get form XLeft
R7 Otherwise the character will get form XIsolated
Additionally we have to do the minimal ligature support for lam-alef ligatures:
L1 Transparent characters do not affect ligature behaviour.
L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft)
L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated)
The state table below handles rules R1-R7.
*/
enum Joining {
JNone,
JCausing,
JDual,
JRight,
JTransparent
};
static const Joining joining_for_group[ArabicGroupsEnd] = {
// NonJoining
JNone, // ArabicNone
JNone, // ArabicSpace
// Transparent
JTransparent, // Transparent
// Causing
JCausing, // Center
JCausing, // Kashida
// Dual
JDual, // Beh
JDual, // Noon
JDual, // Yeh
JDual, // Hah
JDual, // Seen
JDual, // Tah
JDual, // Ain
// Right
JRight, // Alef
JRight, // Waw
JRight, // Dal
JRight, // Reh
JRight // HamzaOnHehGoal
};
struct JoiningPair {
QArabicShape form1;
QArabicShape form2;
};
static const JoiningPair joining_table[5][4] =
// None, Causing, Dual, Right
{
{ { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, // XIsolated
{ { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, // XFinal
{ { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, // XInitial
{ { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, // XMedial
{ { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, // XCausing
};
/*
According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp
1. Find the priority of the connecting opportunities in each word
2. Add expansion at the highest priority connection opportunity
3. If more than one connection opportunity have the same highest value,
use the opportunity closest to the end of the word.
Following is a chart that provides the priority for connection
opportunities and where expansion occurs. The character group names
are those in table 6.6 of the UNICODE 2.0 book.
PrioritY Glyph Condition Kashida Location
Arabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user
(Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida
automatic kashida.
Arabic_Seen Seen, Sad Connecting to the next character. After the character.
(Initial or medial form).
Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form
of these characters.
Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form
Kaf and Gaf of these characters.
Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa
Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of
these characters.
Arabic_Normal Other connecting Connecting to previous character. Before the final form
characters of these characters.
This seems to imply that we have at most one kashida point per arabic word.
*/
void qt_getArabicProperties(const unsigned short *chars, int len, QArabicProperties *properties)
{
// qDebug("arabicSyriacOpenTypeShape: properties:");
int lastPos = 0;
int lastGroup = ArabicNone;
ArabicGroup group = arabicGroup(chars[0]);
Joining j = joining_for_group[group];
QArabicShape shape = joining_table[XIsolated][j].form2;
properties[0].justification = HB_NoJustification;
for (int i = 1; i < len; ++i) {
// #### fix handling for spaces and punktuation
properties[i].justification = HB_NoJustification;
group = arabicGroup(chars[i]);
j = joining_for_group[group];
if (j == JTransparent) {
properties[i].shape = XIsolated;
continue;
}
properties[lastPos].shape = joining_table[shape][j].form1;
shape = joining_table[shape][j].form2;
switch(lastGroup) {
case Seen:
if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial)
properties[i-1].justification = HB_Arabic_Seen;
break;
case Hah:
if (properties[lastPos].shape == XFinal)
properties[lastPos-1].justification = HB_Arabic_HaaDal;
break;
case Alef:
if (properties[lastPos].shape == XFinal)
properties[lastPos-1].justification = HB_Arabic_Alef;
break;
case Ain:
if (properties[lastPos].shape == XFinal)
properties[lastPos-1].justification = HB_Arabic_Waw;
break;
case Noon:
if (properties[lastPos].shape == XFinal)
properties[lastPos-1].justification = HB_Arabic_Normal;
break;
case ArabicNone:
break;
default:
Q_ASSERT(false);
}
lastGroup = ArabicNone;
switch(group) {
case ArabicNone:
case Transparent:
// ### Center should probably be treated as transparent when it comes to justification.
case Center:
break;
case ArabicSpace:
properties[i].justification = HB_Arabic_Space;
break;
case Kashida:
properties[i].justification = HB_Arabic_Kashida;
break;
case Seen:
lastGroup = Seen;
break;
case Hah:
case Dal:
lastGroup = Hah;
break;
case Alef:
case Tah:
lastGroup = Alef;
break;
case Yeh:
case Reh:
if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh)
properties[lastPos-1].justification = HB_Arabic_BaRa;
break;
case Ain:
case Waw:
lastGroup = Ain;
break;
case Noon:
case Beh:
case HamzaOnHehGoal:
lastGroup = Noon;
break;
case ArabicGroupsEnd:
Q_ASSERT(false);
}
lastPos = i;
}
properties[lastPos].shape = joining_table[shape][JNone].form1;
// for (int i = 0; i < len; ++i)
// qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);
}
void QTextEngine::shapeTextMac(int item) const
{
QScriptItem &si = layoutData->items[item];
si.glyph_data_offset = layoutData->used;
QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
if (font->type() != QFontEngine::Multi) {
shapeTextWithHarfbuzz(item);
return;
}
QCoreTextFontEngineMulti *fe = static_cast<QCoreTextFontEngineMulti *>(font);
QTextEngine::ShaperFlags flags;
if (si.analysis.bidiLevel % 2)
flags |= RightToLeft;
if (option.useDesignMetrics())
flags |= DesignMetrics;
attributes(); // pre-initialize char attributes
const int len = length(item);
int num_glyphs = length(item);
const QChar *str = layoutData->string.unicode() + si.position;
ushort upperCased[256];
if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
|| si.analysis.flags == QScriptAnalysis::Lowercase) {
ushort *uc = upperCased;
if (len > 256)
uc = new ushort[len];
for (int i = 0; i < len; ++i) {
if(si.analysis.flags == QScriptAnalysis::Lowercase)
uc[i] = str[i].toLower().unicode();
else
uc[i] = str[i].toUpper().unicode();
}
str = reinterpret_cast<const QChar *>(uc);
}
ensureSpace(num_glyphs);
num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
QGlyphLayout g = availableGlyphs(&si);
g.numGlyphs = num_glyphs;
unsigned short *log_clusters = logClusters(&si);
bool stringToCMapFailed = false;
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
ensureSpace(num_glyphs);
g = availableGlyphs(&si);
stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
attributes(), &si);
}
if (!stringToCMapFailed) {
heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
si.num_glyphs = num_glyphs;
layoutData->used += si.num_glyphs;
QGlyphLayout g = shapedGlyphs(&si);
if (si.analysis.script == QUnicodeTables::Arabic) {
QVarLengthArray<QArabicProperties> props(len + 2);
QArabicProperties *properties = props.data();
int f = si.position;
int l = len;
if (f > 0) {
--f;
++l;
++properties;
}
if (f + l < layoutData->string.length()) {
++l;
}
qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
unsigned short *log_clusters = logClusters(&si);
for (int i = 0; i < len; ++i) {
int gpos = log_clusters[i];
g.attributes[gpos].justification = properties[i].justification;
}
}
}
const ushort *uc = reinterpret_cast<const ushort *>(str);
if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
|| si.analysis.flags == QScriptAnalysis::Lowercase)
&& uc != upperCased)
delete [] uc;
}
QT_END_NAMESPACE