📄 qfontdatabase.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qdir.h>#include "qfontdatabase.h"#include "qdebug.h"#include "qalgorithms.h"#include "qapplication.h"#include "qvarlengtharray.h" // here or earlier - workaround for VC++6#include "private/qunicodetables_p.h"#include "qfontengine_p.h"#include "qopentype_p.h"#ifdef Q_WS_X11#include <locale.h>#endif#include <stdlib.h>#include <limits.h>// #define QFONTDATABASE_DEBUG#ifdef QFONTDATABASE_DEBUG# define FD_DEBUG qDebug#else# define FD_DEBUG if (false) qDebug#endif// #define FONT_MATCH_DEBUG#ifdef FONT_MATCH_DEBUG# define FM_DEBUG qDebug#else# define FM_DEBUG if (false) qDebug#endif#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)# define for if(0){}else for#endifextern int qt_defaultDpiY(); // in qfont.cppQ_GUI_EXPORT bool qt_enable_test_font = false;static int getFontWeight(const QString &weightString){ QString s = weightString.toLower(); // Test in decreasing order of commonness if (s == QLatin1String("medium") || s == QLatin1String("normal") || s.compare(qApp->translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0) return QFont::Normal; if (s == QLatin1String("bold") || s.compare(qApp->translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0) return QFont::Bold; if (s == QLatin1String("demibold") || s == QLatin1String("demi bold") || s.compare(qApp->translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0) return QFont::DemiBold; if (s == QLatin1String("black") || s.compare(qApp->translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) return QFont::Black; if (s == QLatin1String("light")) return QFont::Light; if (s.contains(QLatin1String("bold")) || s.contains(qApp->translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) { if (s.contains(QLatin1String("demi")) || s.compare(qApp->translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0) return (int) QFont::DemiBold; return (int) QFont::Bold; } if (s.contains(QLatin1String("light")) || s.compare(qApp->translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0) return (int) QFont::Light; if (s.contains(QLatin1String("black")) || s.compare(qApp->translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) return (int) QFont::Black; return (int) QFont::Normal;}struct QtFontEncoding{ signed int encoding : 16; uint xpoint : 16; uint xres : 8; uint yres : 8; uint avgwidth : 16; uchar pitch : 8;};struct QtFontSize{ unsigned short pixelSize;#ifdef Q_WS_X11 int count; QtFontEncoding *encodings; QtFontEncoding *encodingID(int id, uint xpoint = 0, uint xres = 0, uint yres = 0, uint avgwidth = 0, bool add = false);#endif // Q_WS_X11#ifdef Q_WS_QWS QByteArray fileName; int fileIndex;#endif};#ifdef Q_WS_X11QtFontEncoding *QtFontSize::encodingID(int id, uint xpoint, uint xres, uint yres, uint avgwidth, bool add){ // we don't match using the xpoint, xres and yres parameters, only the id for (int i = 0; i < count; ++i) { if (encodings[i].encoding == id) return encodings + i; } if (!add) return 0; if (!(count % 4)) encodings = (QtFontEncoding *) realloc(encodings, (((count+4) >> 2) << 2) * sizeof(QtFontEncoding)); encodings[count].encoding = id; encodings[count].xpoint = xpoint; encodings[count].xres = xres; encodings[count].yres = yres; encodings[count].avgwidth = avgwidth; encodings[count].pitch = '*'; return encodings + count++;}#endif // Q_WS_X11struct QtFontStyle{ struct Key { Key(const QString &styleString); Key() : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0) { } Key(const Key &o) : style(o.style), weight(o.weight), stretch(o.stretch) { } uint style : 2; signed int weight : 8; signed int stretch : 12; bool operator==(const Key & other) { return (style == other.style && weight == other.weight && (stretch == 0 || other.stretch == 0 || stretch == other.stretch)); } bool operator!=(const Key &other) { return !operator==(other); } bool operator <(const Key &o) { int x = (style << 12) + (weight << 14) + stretch; int y = (o.style << 12) + (o.weight << 14) + o.stretch; return (x < y); } }; QtFontStyle(const Key &k) : key(k), bitmapScalable(false), smoothScalable(false), count(0), pixelSizes(0) {#if defined(Q_WS_X11) weightName = setwidthName = 0;#endif // Q_WS_X11 } ~QtFontStyle() {#ifdef Q_WS_X11 delete [] weightName; delete [] setwidthName;#endif#if defined(Q_WS_X11) || defined(Q_WS_QWS) while (count--) {#ifdef Q_WS_X11 free(pixelSizes[count].encodings);#endif#ifdef Q_WS_QWS pixelSizes[count].fileName.~QByteArray();#endif }#endif free(pixelSizes); } Key key; bool bitmapScalable : 1; bool smoothScalable : 1; signed int count : 30; QtFontSize *pixelSizes;#ifdef Q_WS_X11 const char *weightName; const char *setwidthName;#endif // Q_WS_X11#ifdef Q_WS_QWS bool antialiased;#endif QtFontSize *pixelSize(unsigned short size, bool = false);};QtFontStyle::Key::Key(const QString &styleString) : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0){ weight = getFontWeight(styleString); if (styleString.contains(QLatin1String("Italic")) || styleString.contains(qApp->translate("QFontDatabase", "Italic"))) style = QFont::StyleItalic; else if (styleString.contains(QLatin1String("Oblique")) || styleString.contains(qApp->translate("QFontDatabase", "Oblique"))) style = QFont::StyleOblique;}QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add){ for (int i = 0; i < count; i++) { if (pixelSizes[i].pixelSize == size) return pixelSizes + i; } if (!add) return 0; if (!(count % 8)) pixelSizes = (QtFontSize *) realloc(pixelSizes, (((count+8) >> 3) << 3) * sizeof(QtFontSize)); pixelSizes[count].pixelSize = size;#ifdef Q_WS_X11 pixelSizes[count].count = 0; pixelSizes[count].encodings = 0;#endif#ifdef Q_WS_QWS new (&pixelSizes[count].fileName) QByteArray; pixelSizes[count].fileIndex = 0;#endif return pixelSizes + (count++);}struct QtFontFoundry{ QtFontFoundry(const QString &n) : name(n), count(0), styles(0) {} ~QtFontFoundry() { while (count--) delete styles[count]; free(styles); } QString name; int count; QtFontStyle **styles; QtFontStyle *style(const QtFontStyle::Key &, bool = false);};QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create){ int pos = 0; if (count) { int low = 0; int high = count; pos = count / 2; while (high > low) { if (styles[pos]->key == key) return styles[pos]; if (styles[pos]->key < key) low = pos + 1; else high = pos; pos = (high + low) / 2; }; pos = low; } if (!create) return 0;// qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos); if (!(count % 8)) styles = (QtFontStyle **) realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *)); memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *)); styles[pos] = new QtFontStyle(key); count++; return styles[pos];}struct QtFontFamily{ enum WritingSystemStatus { Unknown = 0, Supported = 1, UnsupportedFT = 2, UnsupportedXLFD = 4, Unsupported = UnsupportedFT | UnsupportedXLFD }; QtFontFamily(const QString &n) :#ifdef Q_WS_X11 fixedPitch(true), ftWritingSystemCheck(false), xlfdLoaded(false), synthetic(false), symbol_checked(false),#else fixedPitch(false),#endif#ifdef Q_WS_WIN writingSystemCheck(false), loaded(false),#endif#if !defined(QWS) && defined(Q_OS_MAC) fixedPitchComputed(false),#endif name(n), count(0), foundries(0)#if defined(Q_WS_QWS) , bogusWritingSystems(false)#endif { memset(writingSystems, 0, sizeof(writingSystems)); } ~QtFontFamily() { while (count--) delete foundries[count]; free(foundries); } bool fixedPitch : 1;#ifdef Q_WS_X11 bool ftWritingSystemCheck : 1; bool xlfdLoaded : 1; bool synthetic : 1;#endif#ifdef Q_WS_WIN bool writingSystemCheck : 1; bool loaded : 1;#endif#if !defined(QWS) && defined(Q_OS_MAC) bool fixedPitchComputed : 1;#endif#ifdef Q_WS_X11 bool symbol_checked;#endif QString name; QString rawName;#ifdef Q_WS_X11 QByteArray fontFilename; int fontFileIndex;#endif#ifdef Q_WS_WIN QString english_name;#endif int count; QtFontFoundry **foundries;#ifdef Q_WS_QWS bool bogusWritingSystems; QStringList fallbackFamilies;#endif unsigned char writingSystems[QFontDatabase::WritingSystemsCount]; QtFontFoundry *foundry(const QString &f, bool = false);};#if !defined(QWS) && defined(Q_OS_MAC)inline static void qt_mac_get_fixed_pitch(QtFontFamily *f){ if(f && !f->fixedPitchComputed) { QFontMetrics fm(f->name); f->fixedPitch = fm.width(QLatin1Char('i')) == fm.width(QLatin1Char('m')); f->fixedPitchComputed = true; }}#endifQtFontFoundry *QtFontFamily::foundry(const QString &f, bool create){ if (f.isNull() && count == 1) return foundries[0]; for (int i = 0; i < count; i++) { if (foundries[i]->name.compare(f, Qt::CaseInsensitive) == 0) return foundries[i]; } if (!create) return 0; if (!(count % 8)) foundries = (QtFontFoundry **) realloc(foundries, (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *)); foundries[count] = new QtFontFoundry(f); return foundries[count++];}// ### copied to tools/makeqpf/qpf2.cpp#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_WS_MAC)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -