remove raw font support

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
Ivailo Monev 2017-08-09 19:23:36 +00:00
parent c937eb3e08
commit d56802c370
37 changed files with 108 additions and 4093 deletions

View file

@ -254,7 +254,6 @@ classlist = {
"QGestureRecognizer",
"QGlobalStatic",
"QGlobalStaticDeleter",
"QGlyphRun",
"QGradientStop",
"QGradientStops",
"QGraphicsAnchor",
@ -514,7 +513,6 @@ classlist = {
"QQueue",
"QRadialGradient",
"QRadioButton",
"QRawFont",
"QReadLocker",
"QReadWriteLock",
"QRect",

View file

@ -92,6 +92,7 @@
#define QT_NO_TABLET
#define QT_NO_TABLETEVENT
#define QT_NO_GCONF2
#define QT_NO_RAWFONT
/* Qt build specs */
#ifndef QT_EDITION
@ -249,7 +250,6 @@
#cmakedefine QT_NO_QOBJECT_CHECK
#cmakedefine QT_NO_QUATERNION
#cmakedefine QT_NO_QUUID_STRING
#cmakedefine QT_NO_RAWFONT
#cmakedefine QT_NO_REGEXP
#cmakedefine QT_NO_REGEXP_ANCHOR_ALT
#cmakedefine QT_NO_REGEXP_BACKREF

View file

@ -74,7 +74,6 @@ set(GUI_PUBLIC_HEADERS
QGenericMatrix
QGesture
QGestureRecognizer
QGlyphRun
QGradientStop
QGradientStops
QGraphicsAnchor
@ -202,7 +201,6 @@ set(GUI_PUBLIC_HEADERS
QQuaternion
QRadialGradient
QRadioButton
QRawFont
QRegion
QRgb
QRubberBand

View file

@ -59,7 +59,6 @@
#ifdef Q_WS_X11
#include "qt_x11_p.h"
#include "qkde_p.h"
#endif
#include "qstylehelper_p.h"

View file

@ -1015,32 +1015,22 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
if (!resFont.isEmpty()
&& !qt_x11Data->has_fontconfig
&& !QApplicationPrivate::sys_font) {
// set application font
// reset the application font to the real font info.
QFont fnt;
fnt.setRawName(resFont);
QFontInfo fontinfo(fnt);
fnt.setFamily(fontinfo.family());
fnt.setItalic(fontinfo.italic());
fnt.setWeight(fontinfo.weight());
fnt.setUnderline(fontinfo.underline());
fnt.setStrikeOut(fontinfo.strikeOut());
fnt.setStyleHint(fontinfo.styleHint());
// the font we get may actually be an alias for another font,
// so we reset the application font to the real font info.
if (! fnt.exactMatch()) {
QFontInfo fontinfo(fnt);
fnt.setFamily(fontinfo.family());
fnt.setRawMode(fontinfo.rawMode());
if (! fnt.rawMode()) {
fnt.setItalic(fontinfo.italic());
fnt.setWeight(fontinfo.weight());
fnt.setUnderline(fontinfo.underline());
fnt.setStrikeOut(fontinfo.strikeOut());
fnt.setStyleHint(fontinfo.styleHint());
if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
// size is all wrong... fix it
qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
if (pointSize <= 0)
pointSize = 12;
fnt.setPointSize(qRound(pointSize));
}
}
if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
// size is all wrong... fix it
qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
if (pointSize <= 0)
pointSize = 12;
fnt.setPointSize(qRound(pointSize));
}
QApplicationPrivate::setSystemFont(fnt);

View file

@ -2222,9 +2222,6 @@ void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
case QFontEngine::Box:
d_func()->drawBoxTextItem(p, ti);
break;
case QFontEngine::XLFD:
drawXLFD(p, ti);
break;
#ifndef QT_NO_FONTCONFIG
case QFontEngine::Freetype:
drawFreetype(p, ti);
@ -2235,45 +2232,6 @@ void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
}
}
void QX11PaintEngine::drawXLFD(const QPointF &p, const QTextItemInt &ti)
{
Q_D(QX11PaintEngine);
if (d->txop > QTransform::TxTranslate) {
// XServer or font don't support server side transformations, need to do it by hand
QPaintEngine::drawTextItem(p, ti);
return;
}
if (!ti.glyphs.numGlyphs)
return;
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
QTransform matrix = d->matrix;
matrix.translate(p.x(), p.y());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
if (glyphs.size() == 0)
return;
QFontEngineXLFD *xlfd = static_cast<QFontEngineXLFD *>(ti.fontEngine);
Qt::HANDLE font_id = xlfd->fontStruct()->fid;
XSetFont(d->dpy, d->gc, font_id);
const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
for (int i = 0; i < glyphs.size(); i++) {
int xp = qRound(positions[i].x + offs);
int yp = qRound(positions[i].y + offs);
if (xp < SHRT_MAX && xp > SHRT_MIN && yp > SHRT_MIN && yp < SHRT_MAX) {
XChar2b ch;
ch.byte1 = glyphs[i] >> 8;
ch.byte2 = glyphs[i] & 0xff;
XDrawString16(d->dpy, d->hd, d->gc, xp, yp, &ch, 1);
}
}
}
#ifndef QT_NO_FONTCONFIG
static QPainterPath path_for_glyphs(const QVarLengthArray<glyph_t> &glyphs,
const QVarLengthArray<QFixedPoint> &positions,

View file

@ -124,7 +124,6 @@ public:
protected:
QX11PaintEngine(QX11PaintEnginePrivate &dptr);
void drawXLFD(const QPointF &p, const QTextItemInt &si);
#ifndef QT_NO_FONTCONFIG
void drawFreetype(const QPointF &p, const QTextItemInt &si);
#endif

View file

@ -61,7 +61,6 @@
#include "qthread.h"
#include "qvarlengtharray.h"
#include "qstatictext.h"
#include "qglyphrun.h"
#include <qfontengine_p.h>
#include <qpaintengine_p.h>
@ -71,9 +70,7 @@
#include <qpaintengine_raster_p.h>
#include <qmath_p.h>
#include <qstatictext_p.h>
#include <qglyphrun_p.h>
#include <qstylehelper_p.h>
#include <qrawfont_p.h>
QT_BEGIN_NAMESPACE
@ -5043,137 +5040,6 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR
d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
}
#if !defined(QT_NO_RAWFONT)
/*!
\fn void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphs)
Draws the specified \a glyphs at the given \a position.
The \a position gives the edge of the baseline for the string of glyphs.
The glyphs will be retrieved from the font selected by \a glyphs and at
offsets given by the positions in \a glyphs.
\since 4.8
\sa QGlyphRun::setRawFont(), QGlyphRun::setPositions(), QGlyphRun::setGlyphIndexes()
*/
void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
{
Q_D(QPainter);
QRawFont font = glyphRun.rawFont();
if (!font.isValid())
return;
QGlyphRunPrivate *glyphRun_d = QGlyphRunPrivate::get(glyphRun);
const quint32 *glyphIndexes = glyphRun_d->glyphIndexData;
const QPointF *glyphPositions = glyphRun_d->glyphPositionData;
int count = qMin(glyphRun_d->glyphIndexDataSize, glyphRun_d->glyphPositionDataSize);
QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
QRawFontPrivate *fontD = QRawFontPrivate::get(font);
bool supportsTransformations;
if (d->extended != 0) {
supportsTransformations = d->extended->supportsTransformations(fontD->fontEngine->fontDef.pixelSize,
d->state->matrix);
} else {
supportsTransformations = d->state->matrix.isAffine();
}
for (int i=0; i<count; ++i) {
QPointF processedPosition = position + glyphPositions[i];
if (!supportsTransformations)
processedPosition = d->state->transform().map(processedPosition);
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, font, glyphRun.overline(),
glyphRun.underline(), glyphRun.strikeOut());
}
void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
int glyphCount,
const QRawFont &font, bool overline, bool underline,
bool strikeOut)
{
Q_Q(QPainter);
updateState(state);
QRawFontPrivate *fontD = QRawFontPrivate::get(font);
QFontEngine *fontEngine = fontD->fontEngine;
QFixed leftMost;
QFixed rightMost;
QFixed baseLine;
for (int i=0; i<glyphCount; ++i) {
glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
if (i == 0 || leftMost > positions[i].x)
leftMost = positions[i].x;
// We don't support glyphs that do not share a common baseline. If this turns out to
// be a relevant use case, then we need to find clusters of glyphs that share a baseline
// and do a drawTextItemDecorations call per cluster.
if (i == 0 || baseLine < positions[i].y)
baseLine = positions[i].y;
// We use the advance rather than the actual bounds to match the algorithm in drawText()
if (i == 0 || rightMost < positions[i].x + gm.xoff)
rightMost = positions[i].x + gm.xoff;
}
QFixed width = rightMost - leftMost;
if (extended != 0 && state->matrix.isAffine()) {
QStaticTextItem staticTextItem;
staticTextItem.color = state->pen.color();
staticTextItem.font = state->font;
staticTextItem.setFontEngine(fontEngine);
staticTextItem.numGlyphs = glyphCount;
staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
staticTextItem.glyphPositions = positions;
extended->drawStaticTextItem(&staticTextItem);
} else {
QTextItemInt textItem;
textItem.fontEngine = fontEngine;
QVarLengthArray<QFixed, 128> advances(glyphCount);
QVarLengthArray<QGlyphJustification, 128> glyphJustifications(glyphCount);
QVarLengthArray<HB_GlyphAttributes, 128> glyphAttributes(glyphCount);
memset(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes));
memset(advances.data(), 0, advances.size() * sizeof(QFixed));
memset(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification));
textItem.glyphs.numGlyphs = glyphCount;
textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray));
textItem.glyphs.offsets = positions;
textItem.glyphs.advances_x = advances.data();
textItem.glyphs.advances_y = advances.data();
textItem.glyphs.justifications = glyphJustifications.data();
textItem.glyphs.attributes = glyphAttributes.data();
engine->drawTextItem(QPointF(0, 0), textItem);
}
QTextItemInt::RenderFlags flags;
if (underline)
flags |= QTextItemInt::Underline;
if (overline)
flags |= QTextItemInt::Overline;
if (strikeOut)
flags |= QTextItemInt::StrikeOut;
drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
fontEngine,
(underline
? QTextCharFormat::SingleUnderline
: QTextCharFormat::NoUnderline),
flags, width.toReal(), QTextCharFormat());
}
#endif // QT_NO_RAWFONT
/*!
\fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText)

View file

@ -78,7 +78,6 @@ class QTextItem;
class QMatrix;
class QTransform;
class QStaticText;
class QGlyphRun;
class Q_GUI_EXPORT QPainter
{
@ -390,10 +389,6 @@ public:
void setLayoutDirection(Qt::LayoutDirection direction);
Qt::LayoutDirection layoutDirection() const;
#if !defined(QT_NO_RAWFONT)
void drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun);
#endif
void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText);
inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText);
inline void drawStaticText(int left, int top, const QStaticText &staticText);
@ -464,7 +459,6 @@ private:
friend class QFontEngine;
friend class QFontEngineBox;
friend class QFontEngineFT;
friend class QFontEngineXLFD;
friend class QPaintEngine;
friend class QPaintEngineExPrivate;
friend class QX11PaintEngine;

View file

@ -155,7 +155,6 @@ struct QPainterDummyState
QTransform transform;
};
class QRawFont;
class QPainterPrivate
{
Q_DECLARE_PUBLIC(QPainter)
@ -200,12 +199,6 @@ public:
void drawStretchedGradient(const QPainterPath &path, DrawOperation operation);
void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation);
#if !defined(QT_NO_RAWFONT)
void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
const QRawFont &font, bool overline = false, bool underline = false,
bool strikeOut = false);
#endif
void updateMatrix();
void updateInvMatrix();

View file

@ -167,7 +167,7 @@ Q_GUI_EXPORT int qt_defaultDpi()
QFontPrivate::QFontPrivate()
: engineData(0), dpi(qt_defaultDpi()), screen(0),
rawMode(false), underline(false), overline(false), strikeOut(false), kerning(true),
underline(false), overline(false), strikeOut(false), kerning(true),
capital(0), letterSpacingIsAbsolute(false), scFont(0)
{
#ifdef Q_WS_X11
@ -180,7 +180,7 @@ QFontPrivate::QFontPrivate()
QFontPrivate::QFontPrivate(const QFontPrivate &other)
: request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
rawMode(other.rawMode), underline(other.underline), overline(other.overline),
underline(other.underline), overline(other.overline),
strikeOut(other.strikeOut), kerning(other.kerning),
capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing),
@ -407,9 +407,6 @@ QFontEngineData::~QFontEngineData()
setPointSize() has a similar effect and provides device
independence.
In X11 you can set a font using its system
specific name with setRawName().
Loading fonts can be expensive, especially on X11. QFont contains
extensive optimizations to make the copying of QFont objects fast,
and to cache the results of the slow window system functions it
@ -550,44 +547,6 @@ QFontEngineData::~QFontEngineData()
i.e., X11 and some Embedded Linux platforms.
*/
/*!
\fn QString QFont::rawName() const
Returns the name of the font within the underlying window system.
On X11, this function will return an empty string if Qt is built with
FontConfig support; otherwise the XLFD (X Logical Font Description) is
returned.
Using the return value of this function is usually \e not \e
portable.
\sa setRawName()
*/
/*!
\fn void QFont::setRawName(const QString &name)
Sets a font by its system specific name. The function is
particularly useful under X, where system font settings (for
example X resources) are usually available in XLFD (X Logical Font
Description) form only. You can pass an XLFD as \a name to this
function.
A font set with setRawName() is still a full-featured QFont. It can
be queried (for example with italic()) or modified (for example with
setItalic()) and is therefore also suitable for rendering rich text.
If Qt's internal font database cannot resolve the raw name, the
font becomes a raw font with \a name as its family.
Note that the present implementation does not handle wildcards in
XLFDs well, and that font aliases (file \c fonts.alias in the font
directory on X11) are not supported.
\sa rawName(), setRawMode(), setFamily()
*/
/*!
\fn QString QFont::lastResortFamily() const
@ -628,7 +587,7 @@ QFontEngineData::~QFontEngineData()
happens. Please \link bughowto.html report it as a bug\endlink if
it does, preferably with a list of the fonts you have installed.
\sa lastResortFamily() rawName()
\sa lastResortFamily()
*/
/*!
@ -1418,10 +1377,6 @@ int QFont::stretch() const
The stretch factor is only applied to outline fonts. The stretch
factor is ignored for bitmap fonts.
NOTE: QFont cannot stretch XLFD fonts. When loading XLFD fonts on
X11, the stretch factor is matched against a predefined set of
values for the SETWIDTH_NAME field of the XLFD.
\sa stretch() QFont::Stretch
*/
void QFont::setStretch(int factor)
@ -1583,33 +1538,6 @@ QFont::Capitalization QFont::capitalization() const
return static_cast<QFont::Capitalization> (d->capital);
}
/*!
If \a enable is true, turns raw mode on; otherwise turns raw mode
off. This function only has an effect under X11.
If raw mode is enabled, Qt will search for an X font with a
complete font name matching the family name, ignoring all other
values set for the QFont. If the font name matches several fonts,
Qt will use the first font returned by X. QFontInfo \e cannot be
used to fetch information about a QFont using raw mode (it will
return the values set in the QFont for all parameters, including
the family name).
\warning Do not use raw mode unless you really, really need it! In
most (if not all) cases, setRawName() is a much better choice.
\sa rawMode(), setRawName()
*/
void QFont::setRawMode(bool enable)
{
detach();
if ((bool) d->rawMode == enable) return;
d->rawMode = enable;
}
/*!
Returns true if a window system font exactly matching the settings
of this font is available.
@ -1620,9 +1548,7 @@ bool QFont::exactMatch() const
{
QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
Q_ASSERT(engine != 0);
return (d->rawMode
? engine->type() != QFontEngine::Box
: d->request.exactMatch(engine->fontDef));
return d->request.exactMatch(engine->fontDef);
}
/*!
@ -1630,8 +1556,7 @@ bool QFont::exactMatch() const
false.
Two QFonts are considered equal if their font attributes are
equal. If rawMode() is enabled for both fonts, only the family
fields are compared.
equal.
\sa operator!=() isCopyOf()
*/
@ -1697,8 +1622,7 @@ bool QFont::operator<(const QFont &f) const
returns false.
Two QFonts are considered to be different if their font attributes
are different. If rawMode() is enabled for both fonts, only the
family fields are compared.
are different.
\sa operator==()
*/
@ -1727,17 +1651,6 @@ bool QFont::isCopyOf(const QFont & f) const
return d == f.d;
}
/*!
Returns true if raw mode is used for font name matching; otherwise
returns false.
\sa setRawMode() rawName()
*/
bool QFont::rawMode() const
{
return d->rawMode;
}
/*!
Returns a new QFont that has attributes copied from \a other that
have not been previously set on this font.
@ -1973,8 +1886,6 @@ static quint8 get_font_bits(int version, const QFontPrivate *f)
bits |= 0x08;
// if (f.hintSetByUser)
// bits |= 0x10;
if (f->rawMode)
bits |= 0x20;
if (f->kerning)
bits |= 0x10;
if (f->request.style == QFont::StyleOblique)
@ -2008,7 +1919,6 @@ static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
f->strikeOut = (bits & 0x04) != 0;
f->request.fixedPitch = (bits & 0x08) != 0;
// f->hintSetByUser = (bits & 0x10) != 0;
f->rawMode = (bits & 0x20) != 0;
f->kerning = (bits & 0x10) != 0;
if ((bits & 0x80) != 0)
f->request.style = QFont::StyleOblique;
@ -2052,8 +1962,7 @@ QString QFont::toString() const
QString::number((int) style()) + comma +
QString::number((int) underline()) + comma +
QString::number((int) strikeOut()) + comma +
QString::number((int)fixedPitch()) + comma +
QString::number((int) rawMode());
QString::number((int)fixedPitch()) + comma;
}
@ -2085,7 +1994,6 @@ bool QFont::fromString(const QString &descrip)
setUnderline(l[5].toInt());
setStrikeOut(l[6].toInt());
setFixedPitch(l[7].toInt());
setRawMode(l[8].toInt());
} else if (count == 10) {
if (l[2].toInt() > 0)
setPixelSize(l[2].toInt());
@ -2095,7 +2003,6 @@ bool QFont::fromString(const QString &descrip)
setUnderline(l[6].toInt());
setStrikeOut(l[7].toInt());
setFixedPitch(l[8].toInt());
setRawMode(l[9].toInt());
}
if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
d->request.ignorePitch = true;
@ -2475,21 +2382,6 @@ QFont::StyleHint QFontInfo::styleHint() const
return (QFont::StyleHint) engine->fontDef.styleHint;
}
/*!
Returns true if the font is a raw mode font; otherwise returns
false.
If it is a raw mode font, all other functions in QFontInfo will
return the same values set in the QFont, regardless of the font
actually used.
\sa QFont::rawMode()
*/
bool QFontInfo::rawMode() const
{
return d->rawMode;
}
/*!
Returns true if the matched window system font is exactly the same
as the one specified by the font; otherwise returns false.
@ -2500,9 +2392,7 @@ bool QFontInfo::exactMatch() const
{
QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
Q_ASSERT(engine != 0);
return (d->rawMode
? engine->type() != QFontEngine::Box
: d->request.exactMatch(engine->fontDef));
return d->request.exactMatch(engine->fontDef);
}

View file

@ -225,10 +225,6 @@ public:
void setHintingPreference(HintingPreference hintingPreference);
HintingPreference hintingPreference() const;
// is raw mode still needed?
bool rawMode() const;
void setRawMode(bool);
// dupicated from QFontInfo
bool exactMatch() const;
@ -248,10 +244,6 @@ public:
FT_Face freetypeFace() const;
#endif
// needed for X11
void setRawName(const QString &);
QString rawName() const;
QString key() const;
QString toString() const;

View file

@ -171,7 +171,6 @@ public:
int dpi;
int screen;
uint rawMode : 1;
uint underline : 1;
uint overline : 1;
uint strikeOut : 1;

View file

@ -212,8 +212,6 @@ Qt::HANDLE QFont::handle() const
Q_ASSERT(engine != 0);
if (engine->type() == QFontEngine::Multi)
engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
if (engine->type() == QFontEngine::XLFD)
return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
return 0;
}
@ -228,45 +226,12 @@ FT_Face QFont::freetypeFace() const
if (engine->type() == QFontEngine::Freetype) {
const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
return ft->non_locked_face();
} else
#endif
if (engine->type() == QFontEngine::XLFD) {
const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
return xlfd->non_locked_face();
}
#endif
#endif
return 0;
}
QString QFont::rawName() const
{
QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
Q_ASSERT(engine != 0);
if (engine->type() == QFontEngine::Multi)
engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
if (engine->type() == QFontEngine::XLFD)
return QString::fromLatin1(engine->name());
return QString();
}
struct QtFontDesc;
void QFont::setRawName(const QString &name)
{
detach();
// from qfontdatabase_x11.cpp
extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
setFamily(name);
setRawMode(true);
} else {
resolve_mask = QFont::AllPropertiesResolved;
}
}
QString QFont::lastResortFamily() const
{
return QString::fromLatin1("Helvetica");

View file

@ -349,15 +349,14 @@ struct QtFontFamily
Unknown = 0,
Supported = 1,
UnsupportedFT = 2,
UnsupportedXLFD = 4,
Unsupported = UnsupportedFT | UnsupportedXLFD
Unsupported = UnsupportedFT
};
QtFontFamily(const QString &n)
:
#ifdef Q_WS_X11
fixedPitch(true), ftWritingSystemCheck(false),
xlfdLoaded(false), synthetic(false), symbol_checked(false),
synthetic(false), symbol_checked(false),
#else
fixedPitch(false),
#endif
@ -374,7 +373,6 @@ struct QtFontFamily
bool fixedPitch : 1;
#ifdef Q_WS_X11
bool ftWritingSystemCheck : 1;
bool xlfdLoaded : 1;
bool synthetic : 1;
bool symbol_checked : 1;
#endif
@ -741,35 +739,7 @@ struct QtFontDesc
static void match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>(), bool forceXLFD=false);
#if defined(Q_WS_X11)
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef)
{
fontDef->family = desc.family->name;
if (! desc.foundry->name.isEmpty() && desc.family->count > 1) {
fontDef->family += QString::fromLatin1(" [");
fontDef->family += desc.foundry->name;
fontDef->family += QLatin1Char(']');
}
if (desc.style->smoothScalable)
fontDef->pixelSize = request.pixelSize;
else if ((desc.style->bitmapScalable && (request.styleStrategy & QFont::PreferMatch)))
fontDef->pixelSize = request.pixelSize;
else
fontDef->pixelSize = desc.size->pixelSize;
fontDef->styleHint = request.styleHint;
fontDef->styleStrategy = request.styleStrategy;
fontDef->weight = desc.style->key.weight;
fontDef->style = desc.style->key.style;
fontDef->fixedPitch = desc.family->fixedPitch;
fontDef->stretch = desc.style->key.stretch;
fontDef->ignorePitch = false;
}
#endif
QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>());
#if defined(Q_WS_X11)
static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
@ -879,44 +849,14 @@ static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &st
static QtFontEncoding *findEncoding(int script, int styleStrategy,
QtFontSize *size, int force_encoding_id)
{
QtFontEncoding *encoding = Q_NULLPTR;
if (force_encoding_id >= 0) {
encoding = size->encodingID(force_encoding_id);
QtFontEncoding *encoding = size->encodingID(force_encoding_id);
if (!encoding)
FM_DEBUG(" required encoding_id not available");
return encoding;
}
encoding = size->encodingID(-1); // -1 == prefer Freetype
if (encoding)
return encoding;
// FT not available, find an XLFD font, trying the default encoding first
encoding = size->encodingID(QFontPrivate::defaultEncodingID);
if (encoding) {
// does it support the requested script?
bool supportsScript = false;
for (int ws = 1; !supportsScript && ws < QFontDatabase::WritingSystemsCount; ++ws) {
if (scriptForWritingSystem[ws] != script)
continue;
supportsScript = writingSystems_for_xlfd_encoding[encoding->encoding][ws];
}
if (!supportsScript)
encoding = 0;
}
// find the first encoding that supports the requested script
for (int ws = 1; !encoding && ws < QFontDatabase::WritingSystemsCount; ++ws) {
if (scriptForWritingSystem[ws] != script)
continue;
for (int x = 0; !encoding && x < size->count; ++x) {
const int enc = size->encodings[x].encoding;
if (writingSystems_for_xlfd_encoding[enc][ws])
encoding = size->encodings + x;
}
}
return encoding;
return size->encodingID(-1); // -1 == prefer Freetype;
}
#endif // Q_WS_X11
@ -1103,7 +1043,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
*/
static void match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool forceXLFD)
QtFontDesc *desc, const QList<int> &blacklistedFamilies)
{
Q_UNUSED(force_encoding_id);
@ -1139,12 +1079,9 @@ static void match(int script, const QFontDef &request,
unsigned int score = ~0u;
#ifdef Q_WS_X11
load(family_name, script, forceXLFD);
#else
Q_UNUSED(forceXLFD);
load(family_name, script);
#endif
if (qt_x11Data->has_fontconfig) {
initializeFontDb();
}
QFontDatabasePrivate *db = privateDb();
for (int x = 0; x < db->count; ++x) {
@ -1158,9 +1095,6 @@ static void match(int script, const QFontDef &request,
&& test.family->name.compare(family_name, Qt::CaseInsensitive) != 0)
continue;
if (family_name.isEmpty())
load(test.family->name, script);
uint score_adjust = 0;
bool supported = (script == QUnicodeTables::Common);
@ -1359,7 +1293,7 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
{
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)();
createDatabase();
#ifdef Q_WS_X11
checkSymbolFonts();
#endif
@ -1395,7 +1329,7 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(const QString
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)();
createDatabase();
#ifdef Q_WS_X11
checkSymbolFonts(familyName);
#endif
@ -1428,7 +1362,7 @@ QStringList QFontDatabase::families(WritingSystem writingSystem) const
{
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)();
createDatabase();
#ifdef Q_WS_X11
if (writingSystem != Any)
checkSymbolFonts();
@ -1473,7 +1407,7 @@ QStringList QFontDatabase::styles(const QString &family) const
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QStringList l;
QtFontFamily *f = d->family(familyName);
@ -1516,7 +1450,7 @@ bool QFontDatabase::isFixedPitch(const QString &family,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontFamily *f = d->family(familyName);
return (f && f->fixedPitch);
@ -1540,7 +1474,7 @@ bool QFontDatabase::isBitmapScalable(const QString &family,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontStyle::Key styleKey(style);
@ -1578,7 +1512,7 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontStyle::Key styleKey(style);
@ -1630,7 +1564,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontStyle::Key styleKey(styleName);
@ -1685,7 +1619,7 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontFoundry allStyles(foundryName);
QtFontFamily *f = d->family(familyName);
@ -1736,7 +1670,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontStyle::Key styleKey(styleName);
@ -1812,7 +1746,7 @@ bool QFontDatabase::italic(const QString &family, const QString &style) const
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontFoundry allStyles(foundryName);
QtFontFamily *f = d->family(familyName);
@ -1846,7 +1780,7 @@ bool QFontDatabase::bold(const QString &family,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontFoundry allStyles(foundryName);
QtFontFamily *f = d->family(familyName);
@ -1882,7 +1816,7 @@ int QFontDatabase::weight(const QString &family,
QMutexLocker locker(fontDatabaseMutex());
QT_PREPEND_NAMESPACE(load)(familyName);
createDatabase();
QtFontFoundry allStyles(foundryName);
QtFontFamily *f = d->family(familyName);
@ -2257,7 +2191,7 @@ void QFontDatabase::parseFontName(const QString &name, QString &foundry, QString
}
void QFontDatabase::createDatabase()
{ initializeDb(); }
{ initializeFontDb(); }
// used from qfontengine_ft.cpp
Q_GUI_EXPORT QByteArray qt_fontdata_from_index(int index)

View file

@ -157,7 +157,6 @@ private:
friend class QFontPrivate;
friend class QFontDialog;
friend class QFontDialogPrivate;
friend class QFontEngineMultiXLFD;
QFontDatabasePrivate *d;
};

View file

@ -97,246 +97,51 @@ static inline void capitalize (char *s)
*/
// ----- begin of generated code -----
#define make_tag( c1, c2, c3, c4 ) \
((((unsigned int)c1)<<24) | (((unsigned int)c2)<<16) | \
(((unsigned int)c3)<<8) | ((unsigned int)c4))
struct XlfdEncoding {
const char *name;
int id;
int mib;
unsigned int hash1;
unsigned int hash2;
};
static const XlfdEncoding xlfd_encoding[] = {
{ "iso8859-1", 0, 4, make_tag('i','s','o','8'), make_tag('5','9','-','1') },
{ "iso8859-2", 1, 5, make_tag('i','s','o','8'), make_tag('5','9','-','2') },
{ "iso8859-3", 2, 6, make_tag('i','s','o','8'), make_tag('5','9','-','3') },
{ "iso8859-4", 3, 7, make_tag('i','s','o','8'), make_tag('5','9','-','4') },
{ "iso8859-9", 4, 12, make_tag('i','s','o','8'), make_tag('5','9','-','9') },
{ "iso8859-10", 5, 13, make_tag('i','s','o','8'), make_tag('9','-','1','0') },
{ "iso8859-13", 6, 109, make_tag('i','s','o','8'), make_tag('9','-','1','3') },
{ "iso8859-14", 7, 110, make_tag('i','s','o','8'), make_tag('9','-','1','4') },
{ "iso8859-15", 8, 111, make_tag('i','s','o','8'), make_tag('9','-','1','5') },
{ "hp-roman8", 9, 2004, make_tag('h','p','-','r'), make_tag('m','a','n','8') },
{ "iso8859-5", 10, 8, make_tag('i','s','o','8'), make_tag('5','9','-','5') },
{ "*-cp1251", 11, 2251, 0, make_tag('1','2','5','1') },
{ "koi8-ru", 12, 2084, make_tag('k','o','i','8'), make_tag('8','-','r','u') },
{ "koi8-u", 13, 2088, make_tag('k','o','i','8'), make_tag('i','8','-','u') },
{ "koi8-r", 14, 2084, make_tag('k','o','i','8'), make_tag('i','8','-','r') },
{ "iso8859-7", 15, 10, make_tag('i','s','o','8'), make_tag('5','9','-','7') },
{ "iso8859-8", 16, 85, make_tag('i','s','o','8'), make_tag('5','9','-','8') },
{ "gb18030-0", 17, -114, make_tag('g','b','1','8'), make_tag('3','0','-','0') },
{ "gb18030.2000-0", 18, -113, make_tag('g','b','1','8'), make_tag('0','0','-','0') },
{ "gbk-0", 19, -113, make_tag('g','b','k','-'), make_tag('b','k','-','0') },
{ "gb2312.*-0", 20, 57, make_tag('g','b','2','3'), 0 },
{ "jisx0201*-0", 21, 15, make_tag('j','i','s','x'), 0 },
{ "jisx0208*-0", 22, 63, make_tag('j','i','s','x'), 0 },
{ "ksc5601*-*", 23, 36, make_tag('k','s','c','5'), 0 },
{ "big5hkscs-0", 24, -2101, make_tag('b','i','g','5'), make_tag('c','s','-','0') },
{ "hkscs-1", 25, -2101, make_tag('h','k','s','c'), make_tag('c','s','-','1') },
{ "big5*-*", 26, -2026, make_tag('b','i','g','5'), 0 },
{ "tscii-*", 27, 2028, make_tag('t','s','c','i'), 0 },
{ "tis620*-*", 28, 2259, make_tag('t','i','s','6'), 0 },
{ "iso8859-11", 29, 2259, make_tag('i','s','o','8'), make_tag('9','-','1','1') },
{ "mulelao-1", 30, -4242, make_tag('m','u','l','e'), make_tag('a','o','-','1') },
{ "ethiopic-unicode", 31, 0, make_tag('e','t','h','i'), make_tag('c','o','d','e') },
{ "iso10646-1", 32, 0, make_tag('i','s','o','1'), make_tag('4','6','-','1') },
{ "unicode-*", 33, 0, make_tag('u','n','i','c'), 0 },
{ "*-symbol", 34, 0, 0, make_tag('m','b','o','l') },
{ "*-fontspecific", 35, 0, 0, make_tag('i','f','i','c') },
{ "fontspecific-*", 36, 0, make_tag('f','o','n','t'), 0 },
{ 0, 0, 0, 0, 0 }
};
static const char writingSystems_for_xlfd_encoding[sizeof(xlfd_encoding)][QFontDatabase::WritingSystemsCount] = {
// iso8859-1
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-2
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-3
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-4
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-9
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-10
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-13
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-14
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-15
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// hp-roman8
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-5
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// *-cp1251
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// koi8-ru
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// koi8-u
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// koi8-r
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-7
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-8
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// gb18030-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0 },
// gb18030.2000-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0 },
// gbk-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0 },
// gb2312.*-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0 },
// jisx0201*-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0 },
// jisx0208*-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0 },
// ksc5601*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0 },
// big5hkscs-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0 },
// hkscs-1
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0 },
// big5*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0 },
// tscii-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// tis620*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso8859-11
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// mulelao-1
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// ethiopic-unicode
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
// iso10646-1
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
0, 0 },
// unicode-*
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
0, 0 },
// *-symbol
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0 },
// *-fontspecific
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0 },
// fontspecific-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0 }
{ "iso8859-1", 0, 4 },
{ "iso8859-2", 1, 5 },
{ "iso8859-3", 2, 6 },
{ "iso8859-4", 3, 7 },
{ "iso8859-9", 4, 12 },
{ "iso8859-10", 5, 13 },
{ "iso8859-13", 6, 109 },
{ "iso8859-14", 7, 110 },
{ "iso8859-15", 8, 111 },
{ "hp-roman8", 9, 2004 },
{ "iso8859-5", 10, 8 },
{ "*-cp1251", 11, 2251 },
{ "koi8-ru", 12, 2084 },
{ "koi8-u", 13, 2088 },
{ "koi8-r", 14, 2084 },
{ "iso8859-7", 15, 10 },
{ "iso8859-8", 16, 85 },
{ "gb18030-0", 17, -114 },
{ "gb18030.2000-0", 18, -113 },
{ "gbk-0", 19, -113 },
{ "gb2312.*-0", 20, 57 },
{ "jisx0201*-0", 21, 15 },
{ "jisx0208*-0", 22, 63 },
{ "ksc5601*-*", 23, 36 },
{ "big5hkscs-0", 24, -2101 },
{ "hkscs-1", 25, -2101 },
{ "big5*-*", 26, -2026 },
{ "tscii-*", 27, 2028 },
{ "tis620*-*", 28, 2259 },
{ "iso8859-11", 29, 2259 },
{ "mulelao-1", 30, -4242 },
{ "ethiopic-unicode", 31, 0 },
{ "iso10646-1", 32, 0 },
{ "unicode-*", 33, 0 },
{ "*-symbol", 34, 0 },
{ "*-fontspecific", 35, 0 },
{ "fontspecific-*", 36, 0 },
{ 0, 0, 0 }
};
// ----- end of generated code -----
@ -344,57 +149,6 @@ static const char writingSystems_for_xlfd_encoding[sizeof(xlfd_encoding)][QFontD
const int numEncodings = sizeof(xlfd_encoding) / sizeof(XlfdEncoding) - 1;
int qt_xlfd_encoding_id(const char *encoding)
{
// qDebug("looking for encoding id for '%s'", encoding);
int len = strlen(encoding);
if (len < 4)
return -1;
unsigned int hash1 = make_tag(encoding[0], encoding[1], encoding[2], encoding[3]);
const char *ch = encoding + len - 4;
unsigned int hash2 = make_tag(ch[0], ch[1], ch[2], ch[3]);
const XlfdEncoding *enc = xlfd_encoding;
for (; enc->name; ++enc) {
if ((enc->hash1 && enc->hash1 != hash1) ||
(enc->hash2 && enc->hash2 != hash2))
continue;
// hashes match, do a compare if strings match
// the enc->name can contain '*'s we have to interpret correctly
const char *n = enc->name;
const char *e = encoding;
while (1) {
// qDebug("bol: *e='%c', *n='%c'", *e, *n);
if (*e == '\0') {
if (*n)
break;
// qDebug("found encoding id %d", enc->id);
return enc->id;
}
if (*e == *n) {
++e;
++n;
continue;
}
if (*n != '*')
break;
++n;
// qDebug("skip: *e='%c', *n='%c'", *e, *n);
while (*e && *e != *n)
++e;
}
}
// qDebug("couldn't find encoding %s", encoding);
return -1;
}
int qt_mib_for_xlfd_encoding(const char *encoding)
{
int id = qt_xlfd_encoding_id(encoding);
if (id != -1) return xlfd_encoding[id].mib;
return 0;
}
int qt_encoding_id_for_mib(int mib)
{
const XlfdEncoding *enc = xlfd_encoding;
@ -405,6 +159,8 @@ int qt_encoding_id_for_mib(int mib)
return -1;
}
#ifdef QFONTDATABASE_DEBUG
static const char * xlfd_for_id(int id)
{
// special case: -1 returns the "*-*" encoding, allowing us to do full
@ -413,313 +169,7 @@ static const char * xlfd_for_id(int id)
return "*-*";
return xlfd_encoding[id].name;
}
namespace XLFDFieldNames {
enum Fields {
Foundry,
Family,
Weight,
Slant,
Width,
AddStyle,
PixelSize,
PointSize,
ResolutionX,
ResolutionY,
Spacing,
AverageWidth,
CharsetRegistry,
CharsetEncoding,
NFontFields
};
}
// Splits an X font name into fields separated by '-'
static bool parseXFontName(char *fontName, char **tokens)
{
if (! fontName || fontName[0] == '0' || fontName[0] != '-') {
tokens[0] = 0;
return false;
}
int i;
++fontName;
for (i = 0; i < XLFDFieldNames::NFontFields && fontName && fontName[0]; ++i) {
tokens[i] = fontName;
for (;; ++fontName) {
if (*fontName == '-')
break;
if (! *fontName) {
fontName = 0;
break;
}
}
if (fontName) *fontName++ = '\0';
}
if (i < XLFDFieldNames::NFontFields) {
for (int j = i ; j < XLFDFieldNames::NFontFields; ++j)
tokens[j] = 0;
return false;
}
return true;
}
static inline bool isZero(char *x)
{
return (x[0] == '0' && x[1] == 0);
}
static inline bool isScalable(char **tokens)
{
return (isZero(tokens[XLFDFieldNames::PixelSize]) &&
isZero(tokens[XLFDFieldNames::PointSize]) &&
isZero(tokens[XLFDFieldNames::AverageWidth]));
}
static inline bool isSmoothlyScalable(char **tokens)
{
return (isZero(tokens[XLFDFieldNames::ResolutionX]) &&
isZero(tokens[XLFDFieldNames::ResolutionY]));
}
static inline bool isFixedPitch(char **tokens)
{
return (tokens[XLFDFieldNames::Spacing][0] == 'm' ||
tokens[XLFDFieldNames::Spacing][0] == 'c' ||
tokens[XLFDFieldNames::Spacing][0] == 'M' ||
tokens[XLFDFieldNames::Spacing][0] == 'C');
}
/*
Fills in a font definition (QFontDef) from an XLFD (X Logical Font
Description).
Returns true if the given xlfd is valid.
*/
bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc)
{
char *tokens[XLFDFieldNames::NFontFields];
QByteArray buffer = xlfd;
if (! parseXFontName(buffer.data(), tokens))
return false;
capitalize(tokens[XLFDFieldNames::Family]);
capitalize(tokens[XLFDFieldNames::Foundry]);
fd->styleStrategy |= QFont::NoAntialias;
fd->family = QString::fromLatin1(tokens[XLFDFieldNames::Family]);
QString foundry = QString::fromLatin1(tokens[XLFDFieldNames::Foundry]);
if (! foundry.isEmpty() && foundry != QLatin1String("*") && (!desc || desc->family->count > 1))
fd->family +=
QLatin1String(" [") + foundry + QLatin1Char(']');
if (qstrlen(tokens[XLFDFieldNames::AddStyle]) > 0)
fd->addStyle = QString::fromLatin1(tokens[XLFDFieldNames::AddStyle]);
else
fd->addStyle.clear();
fd->pointSize = atoi(tokens[XLFDFieldNames::PointSize])/10.;
fd->styleHint = QFont::AnyStyle; // ### any until we match families
char slant = tolower((uchar) tokens[XLFDFieldNames::Slant][0]);
fd->style = (slant == 'o' ? QFont::StyleOblique : (slant == 'i' ? QFont::StyleItalic : QFont::StyleNormal));
char fixed = tolower((uchar) tokens[XLFDFieldNames::Spacing][0]);
fd->fixedPitch = (fixed == 'm' || fixed == 'c');
fd->weight = getFontWeight(QLatin1String(tokens[XLFDFieldNames::Weight]));
int r = atoi(tokens[XLFDFieldNames::ResolutionY]);
fd->pixelSize = atoi(tokens[XLFDFieldNames::PixelSize]);
// not "0" or "*", or required DPI
if (r && fd->pixelSize && r != dpi) {
// calculate actual pointsize for display DPI
fd->pointSize = qt_pointSize(fd->pixelSize, dpi);
} else if (fd->pixelSize == 0 && fd->pointSize) {
// calculate pixel size from pointsize/dpi
fd->pixelSize = qRound(qt_pixelSize(fd->pointSize, dpi));
}
return true;
}
/*
Fills in a font definition (QFontDef) from the font properties in an
XFontStruct.
Returns true if the QFontDef could be filled with properties from
the XFontStruct.
*/
static bool qt_fillFontDef(XFontStruct *fs, QFontDef *fd, int dpi, QtFontDesc *desc)
{
unsigned long value;
if (!fs || !XGetFontProperty(fs, XA_FONT, &value))
return false;
char *n = XGetAtomName(QX11Info::display(), value);
QByteArray xlfd(n);
if (n)
XFree(n);
return qt_fillFontDef(xlfd.toLower(), fd, dpi, desc);
}
static QtFontStyle::Key getStyle(char ** tokens)
{
QtFontStyle::Key key;
char slant0 = tolower((uchar) tokens[XLFDFieldNames::Slant][0]);
if (slant0 == 'r') {
if (tokens[XLFDFieldNames::Slant][1]) {
char slant1 = tolower((uchar) tokens[XLFDFieldNames::Slant][1]);
if (slant1 == 'o')
key.style = QFont::StyleOblique;
else if (slant1 == 'i')
key.style = QFont::StyleItalic;
}
} else if (slant0 == 'o')
key.style = QFont::StyleOblique;
else if (slant0 == 'i')
key.style = QFont::StyleItalic;
key.weight = getFontWeight(QLatin1String(tokens[XLFDFieldNames::Weight]));
if (qstrcmp(tokens[XLFDFieldNames::Width], "normal") == 0) {
key.stretch = 100;
} else if (qstrcmp(tokens[XLFDFieldNames::Width], "semi condensed") == 0 ||
qstrcmp(tokens[XLFDFieldNames::Width], "semicondensed") == 0) {
key.stretch = 90;
} else if (qstrcmp(tokens[XLFDFieldNames::Width], "condensed") == 0) {
key.stretch = 80;
} else if (qstrcmp(tokens[XLFDFieldNames::Width], "narrow") == 0) {
key.stretch = 60;
}
return key;
}
static bool xlfdsFullyLoaded = false;
static unsigned char encodingLoaded[numEncodings];
static void loadXlfds(const char *reqFamily, int encoding_id)
{
QFontDatabasePrivate *db = privateDb();
QtFontFamily *fontFamily = reqFamily ? db->family(QLatin1String(reqFamily)) : 0;
// make sure we don't load twice
if ((encoding_id == -1 && xlfdsFullyLoaded)
|| (encoding_id != -1 && encodingLoaded[encoding_id]))
return;
if (fontFamily && fontFamily->xlfdLoaded)
return;
int fontCount;
// force the X server to give us XLFDs
QByteArray xlfd_pattern("-*-");
xlfd_pattern += (reqFamily && reqFamily[0] != '\0') ? reqFamily : "*";
xlfd_pattern += "-*-*-*-*-*-*-*-*-*-*-";
xlfd_pattern += xlfd_for_id(encoding_id);
char **fontList = XListFonts(QX11Info::display(),
xlfd_pattern,
0xffff, &fontCount);
// qDebug("requesting xlfd='%s', got %d fonts", xlfd_pattern.data(), fontCount);
char *tokens[XLFDFieldNames::NFontFields];
for(int i = 0 ; i < fontCount ; i++) {
if (! parseXFontName(fontList[i], tokens))
continue;
// get the encoding_id for this xlfd. we need to do this
// here, since we can pass -1 to this function to do full
// database population
*(tokens[XLFDFieldNames::CharsetEncoding] - 1) = '-';
int encoding_id = qt_xlfd_encoding_id(tokens[XLFDFieldNames::CharsetRegistry]);
if (encoding_id == -1)
continue;
char *familyName = tokens[XLFDFieldNames::Family];
capitalize(familyName);
char *foundryName = tokens[XLFDFieldNames::Foundry];
capitalize(foundryName);
QtFontStyle::Key styleKey = getStyle(tokens);
bool smooth_scalable = false;
bool bitmap_scalable = false;
if (isScalable(tokens)) {
if (isSmoothlyScalable(tokens))
smooth_scalable = true;
else
bitmap_scalable = true;
}
uint pixelSize = atoi(tokens[XLFDFieldNames::PixelSize]);
uint xpointSize = atoi(tokens[XLFDFieldNames::PointSize]);
uint xres = atoi(tokens[XLFDFieldNames::ResolutionX]);
uint yres = atoi(tokens[XLFDFieldNames::ResolutionY]);
uint avgwidth = atoi(tokens[XLFDFieldNames::AverageWidth]);
bool fixedPitch = isFixedPitch(tokens);
if (avgwidth == 0 && pixelSize != 0) {
/*
Ignore bitmap scalable fonts that are automatically
generated by some X servers. We know they are bitmap
scalable because even though they have a specified pixel
size, the average width is zero.
*/
continue;
}
QtFontFamily *family = fontFamily ? fontFamily : db->family(QLatin1String(familyName), true);
#ifndef QT_NO_FONTCONFIG
family->fontFileIndex = -1;
#endif
family->symbol_checked = true;
QtFontFoundry *foundry = family->foundry(QLatin1String(foundryName), true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
delete [] style->weightName;
style->weightName = qstrdup(tokens[XLFDFieldNames::Weight]);
delete [] style->setwidthName;
style->setwidthName = qstrdup(tokens[XLFDFieldNames::Width]);
if (smooth_scalable) {
style->smoothScalable = true;
style->bitmapScalable = false;
pixelSize = SMOOTH_SCALABLE;
}
if (!style->smoothScalable && bitmap_scalable)
style->bitmapScalable = true;
if (!fixedPitch)
family->fixedPitch = false;
QtFontSize *size = style->pixelSize(pixelSize, true);
QtFontEncoding *enc =
size->encodingID(encoding_id, xpointSize, xres, yres, avgwidth, true);
enc->pitch = *tokens[XLFDFieldNames::Spacing];
if (!enc->pitch) enc->pitch = '*';
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
if (writingSystems_for_xlfd_encoding[encoding_id][i])
family->writingSystems[i] = QtFontFamily::Supported;
}
}
if (!reqFamily) {
// mark encoding as loaded
if (encoding_id == -1)
xlfdsFullyLoaded = true;
else
encodingLoaded[encoding_id] = true;
}
XFreeFontNames(fontList);
}
#ifndef QT_NO_FONTCONFIG
@ -1184,14 +634,13 @@ static void loadFontConfig()
struct FcDefaultFont {
const char *qtname;
const char *rawname;
bool fixed;
};
const FcDefaultFont defaults[] = {
{ "Serif", "serif", false },
{ "Sans Serif", "sans-serif", false },
{ "Monospace", "monospace", true },
{ 0, 0, false }
{ "Serif", false },
{ "Sans Serif", false },
{ "Monospace", true },
{ 0, false }
};
const FcDefaultFont *f = defaults;
while (f->qtname) {
@ -1224,54 +673,11 @@ static void loadFontConfig()
}
#endif // QT_NO_FONTCONFIG
static void initializeDb();
static void load(const QString &family = QString(), int script = -1, bool forceXLFD = false)
{
if (qt_x11Data->has_fontconfig && !forceXLFD) {
initializeDb();
return;
}
#ifdef QFONTDATABASE_DEBUG
QElapsedTimer t;
t.start();
#endif
if (family.isNull() && script == -1) {
loadXlfds(0, -1);
} else {
if (family.isNull()) {
// load all families in all writing systems that match \a script
for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
if (scriptForWritingSystem[ws] != script)
continue;
for (int i = 0; i < numEncodings; ++i) {
if (writingSystems_for_xlfd_encoding[i][ws])
loadXlfds(0, i);
}
}
} else {
QtFontFamily *f = privateDb()->family(family);
// could reduce this further with some more magic:
// would need to remember the encodings loaded for the family.
if (!f || !f->xlfdLoaded)
loadXlfds(family.toLatin1(), -1);
}
}
#ifdef QFONTDATABASE_DEBUG
FD_DEBUG("QFontDatabase: load(%s, %d) took %d ms",
family.toLatin1().constData(), script, t.elapsed());
#endif
}
static void checkSymbolFont(QtFontFamily *family)
{
#ifndef QT_NO_FONTCONFIG
if (!family || family->symbol_checked || family->fontFilename.isEmpty())
return;
// qDebug() << "checking " << family->rawName;
family->symbol_checked = true;
QFontEngine::FaceId id;
@ -1317,7 +723,7 @@ static void checkSymbolFonts(const QString &family = QString())
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
static void initializeDb()
static void initializeFontDb()
{
QFontDatabasePrivate *db = privateDb();
if (!db || db->count)
@ -1383,12 +789,6 @@ static void initializeDb()
#ifdef QFONTDATABASE_DEBUG
#ifndef QT_NO_FONTCONFIG
if (!qt_x11Data->has_fontconfig)
#endif
// load everything at startup in debug mode.
loadXlfds(0, -1);
// print the database
for (int f = 0; f < db->count; f++) {
QtFontFamily *family = db->families[f];
@ -1781,139 +1181,6 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
}
#endif // QT_NO_FONTCONFIG
static QFontEngine *loadRaw(const QFontPrivate *fp, const QFontDef &request)
{
Q_ASSERT(fp && fp->rawMode);
QByteArray xlfd = request.family.toLatin1();
FM_DEBUG("Loading XLFD (rawmode) '%s'", xlfd.data());
QFontEngine *fe;
XFontStruct *xfs;
if (!(xfs = XLoadQueryFont(QX11Info::display(), xlfd.data())))
if (!(xfs = XLoadQueryFont(QX11Info::display(), "fixed")))
return 0;
fe = new QFontEngineXLFD(xfs, xlfd, 0);
if (! qt_fillFontDef(xfs, &fe->fontDef, fp->dpi, 0) &&
! qt_fillFontDef(xlfd, &fe->fontDef, fp->dpi, 0))
fe->fontDef = QFontDef();
return fe;
}
QFontEngine *QFontDatabase::loadXlfd(int script, const QFontDef &request, int force_encoding_id)
{
QMutexLocker locker(fontDatabaseMutex());
QtFontDesc desc;
FM_DEBUG() << "---> loadXlfd: request is" << request.family;
QStringList families_and_foundries = familyList(request);
const char *stylehint = styleHint(request);
if (stylehint)
families_and_foundries << QString::fromLatin1(stylehint);
families_and_foundries << QString();
FM_DEBUG() << "loadXlfd: list is" << families_and_foundries;
for (int i = 0; i < families_and_foundries.size(); ++i) {
QString family, foundry;
QT_PREPEND_NAMESPACE(parseFontName)(families_and_foundries.at(i), foundry, family);
FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id);
QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc, QList<int>(), true);
if (desc.family)
break;
}
QFontEngine *fe = 0;
if (force_encoding_id != -1
|| (request.styleStrategy & QFont::NoFontMerging)
|| (desc.family && desc.family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) {
if (desc.family) {
int px = desc.size->pixelSize;
if (desc.style->smoothScalable && px == SMOOTH_SCALABLE)
px = request.pixelSize;
else if (desc.style->bitmapScalable && px == 0)
px = request.pixelSize;
QByteArray xlfd("-");
xlfd += desc.foundry->name.isEmpty() ? QByteArray("*") : desc.foundry->name.toLatin1();
xlfd += '-';
xlfd += desc.family->name.isEmpty() ? QByteArray("*") : desc.family->name.toLatin1();
xlfd += '-';
xlfd += desc.style->weightName ? desc.style->weightName : "*";
xlfd += '-';
xlfd += (desc.style->key.style == QFont::StyleItalic
? 'i'
: (desc.style->key.style == QFont::StyleOblique ? 'o' : 'r'));
xlfd += '-';
xlfd += desc.style->setwidthName ? desc.style->setwidthName : "*";
// ### handle add-style
xlfd += "-*-";
xlfd += QByteArray::number(px);
xlfd += '-';
xlfd += QByteArray::number(desc.encoding->xpoint);
xlfd += '-';
xlfd += QByteArray::number(desc.encoding->xres);
xlfd += '-';
xlfd += QByteArray::number(desc.encoding->yres);
xlfd += '-';
xlfd += desc.encoding->pitch;
xlfd += '-';
xlfd += QByteArray::number(desc.encoding->avgwidth);
xlfd += '-';
xlfd += xlfd_for_id(desc.encoding->encoding);
FM_DEBUG(" using XLFD: %s\n", xlfd.data());
const int mib = xlfd_encoding[desc.encoding->encoding].mib;
XFontStruct *xfs;
if ((xfs = XLoadQueryFont(QX11Info::display(), xlfd))) {
fe = new QFontEngineXLFD(xfs, xlfd, mib);
const int dpi = QX11Info::appDpiY();
if (!qt_fillFontDef(xfs, &fe->fontDef, dpi, &desc)
&& !qt_fillFontDef(xlfd, &fe->fontDef, dpi, &desc)) {
initFontDef(desc, request, &fe->fontDef);
}
}
}
if (!fe) {
fe = new QFontEngineBox(request.pixelSize);
fe->fontDef = QFontDef();
}
} else {
QList<int> encodings;
if (desc.encoding) {
if (desc.encoding->encoding >= 0)
encodings.append(int(desc.encoding->encoding));
}
if (desc.size) {
// append all other encodings for the matched font
for (int i = 0; i < desc.size->count; ++i) {
QtFontEncoding *e = desc.size->encodings + i;
if (e == desc.encoding || e->encoding < 0)
continue;
encodings.append(int(e->encoding));
}
}
// fill in the missing encodings
const XlfdEncoding *enc = xlfd_encoding;
for (; enc->name; ++enc) {
if (!encodings.contains(enc->id) && enc->id >= 0) {
encodings.append(enc->id);
}
}
#if defined(FONT_MATCH_DEBUG)
FM_DEBUG(" using MultiXLFD, encodings:");
for (int i = 0; i < encodings.size(); ++i) {
const int id = encodings.at(i);
FM_DEBUG(" %2d: %s", xlfd_encoding[id].id, xlfd_encoding[id].name);
}
#endif
fe = new QFontEngineMultiXLFD(request, encodings);
}
return fe;
}
/*! \internal
Loads a QFontEngine for the specified \a script that matches the
@ -1935,7 +1202,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
if (req.stretch == 0)
req.stretch = 100;
QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen);
QFontCache::Key key(req, script, d->screen);
if (!d->engineData)
getEngineData(d, key);
@ -1953,24 +1220,18 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
if (!fe) {
QMutexLocker locker(fontDatabaseMutex());
if (!privateDb()->count)
initializeDb();
initializeFontDb();
const bool mainThread = (qApp->thread() == QThread::currentThread());
#ifdef QT_BUILD_INTERNAL
if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
fe = new QTestFontEngine(req.pixelSize);
fe->fontDef = req;
} else
#endif
if (d->rawMode) {
if (mainThread)
fe = loadRaw(d, req);
#ifndef QT_NO_FONTCONFIG
} else if (qt_x11Data->has_fontconfig) {
if (qt_x11Data->has_fontconfig) {
fe = loadFc(d, script, req);
#endif
} else if (mainThread && qt_is_gui_used) {
fe = loadXlfd(script, req);
}
if (!fe) {
fe = new QFontEngineBox(req.pixelSize);

View file

@ -87,9 +87,6 @@ public:
Box,
Multi,
// X11 types
XLFD,
// QWS types
Freetype,
Proxy,
@ -362,7 +359,6 @@ public:
protected:
friend class QPSPrintEnginePrivate;
friend class QPSPrintEngineFontMulti;
friend class QRawFont;
virtual void loadEngine(int at) = 0;
QVector<QFontEngine *> engines;
};

View file

@ -100,761 +100,6 @@
QT_BEGIN_NAMESPACE
// ------------------------------------------------------------------
// Multi XLFD engine
// ------------------------------------------------------------------
QFontEngineMultiXLFD::QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l)
: QFontEngineMulti(l.size()), encodings(l), request(r)
{
loadEngine(0);
fontDef = engines[0]->fontDef;
}
QFontEngineMultiXLFD::~QFontEngineMultiXLFD()
{ }
void QFontEngineMultiXLFD::loadEngine(int at)
{
Q_ASSERT(at < engines.size());
Q_ASSERT(engines.at(at) == 0);
const int encoding = encodings.at(at);
QFontEngine *fontEngine = QFontDatabase::loadXlfd(QUnicodeTables::Common, request, encoding);
Q_ASSERT(fontEngine != 0);
fontEngine->ref.ref();
engines[at] = fontEngine;
}
// ------------------------------------------------------------------
// Xlfd font engine
// ------------------------------------------------------------------
#ifndef QT_NO_FREETYPE
static QStringList *qt_fontpath = 0;
static QStringList fontPath()
{
if (qt_fontpath)
return *qt_fontpath;
// append qsettings fontpath
QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
settings.beginGroup(QLatin1String("Qt"));
QStringList fontpath;
int npaths;
char** font_path;
font_path = XGetFontPath(qt_x11Data->display, &npaths);
bool xfsconfig_read = false;
for (int i=0; i<npaths; i++) {
// If we're using xfs, append font paths from /etc/X11/fs/config
// can't hurt, and chances are we'll get all fonts that way.
if (((font_path[i])[0] != '/') && !xfsconfig_read) {
// We're using xfs -> read its config
bool finished = false;
QFile f(QLatin1String("/etc/X11/fs/config"));
if (!f.exists())
f.setFileName(QLatin1String("/usr/X11R6/lib/X11/fs/config"));
if (!f.exists())
f.setFileName(QLatin1String("/usr/X11/lib/X11/fs/config"));
if (f.exists()) {
f.open(QIODevice::ReadOnly);
while (f.error()==QFile::NoError && !finished) {
QString fs = QString::fromLocal8Bit(f.readLine(1024));
fs=fs.trimmed();
if (fs.left(9)==QLatin1String("catalogue") && fs.contains(QLatin1Char('='))) {
fs = fs.mid(fs.indexOf(QLatin1Char('=')) + 1).trimmed();
bool end = false;
while (f.error()==QFile::NoError && !end) {
if (fs[int(fs.length())-1] == QLatin1Char(','))
fs = fs.left(fs.length()-1);
else
end = true;
fs = fs.left(fs.indexOf(QLatin1String(":unscaled")));
if (fs[0] != QLatin1Char('#'))
fontpath += fs;
fs = QLatin1String(f.readLine(1024));
fs = fs.trimmed();
if (fs.isEmpty())
end = true;
}
finished = true;
}
}
f.close();
}
xfsconfig_read = true;
} else {
QString fs = QString::fromLocal8Bit(font_path[i]);
fontpath += fs.left(fs.indexOf(QLatin1String(":unscaled")));
}
}
XFreeFontPath(font_path);
// append qsettings fontpath
QStringList fp = settings.value(QLatin1String("fontPath")).toStringList();
if (!fp.isEmpty())
fontpath += fp;
qt_fontpath = new QStringList(fontpath);
return fontpath;
}
static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
{
*freetype = 0;
*synth = 0;
QByteArray xname = _xname.toLower();
int pos = 0;
int minus = 0;
while (minus < 5 && (pos = xname.indexOf('-', pos + 1)))
++minus;
QByteArray searchname = xname.left(pos);
while (minus < 12 && (pos = xname.indexOf('-', pos + 1)))
++minus;
QByteArray encoding = xname.mid(pos + 1);
//qDebug("xname='%s', searchname='%s', encoding='%s'", xname.data(), searchname.data(), encoding.data());
QStringList fontpath = fontPath();
QFontEngine::FaceId face_id;
face_id.index = 0;
QByteArray best_mapping;
for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {
if (!(*it).startsWith(QLatin1Char('/')))
continue; // not a path name, a font server
QString fontmapname;
int num = 0;
// search font.dir and font.scale for the right file
while (num < 2) {
if (num == 0)
fontmapname = (*it) + QLatin1String("/fonts.scale");
else
fontmapname = (*it) + QLatin1String("/fonts.dir");
++num;
//qWarning(fontmapname);
QFile fontmap(fontmapname);
if (!fontmap.open(QIODevice::ReadOnly))
continue;
while (!fontmap.atEnd()) {
QByteArray mapping = fontmap.readLine();
QByteArray lmapping = mapping.toLower();
//qWarning(xfontname);
//qWarning(mapping);
if (!lmapping.contains(searchname))
continue;
int index = mapping.indexOf(' ');
QByteArray ffn = mapping.mid(0,index);
// remove bitmap formats freetype can't handle
if (ffn.contains(".spd") || ffn.contains(".phont"))
continue;
bool best_match = false;
if (!best_mapping.isEmpty()) {
if (lmapping.contains("-0-0-0-0-")) { // scalable font
best_match = true;
goto found;
}
if (lmapping.contains(encoding) && !best_mapping.toLower().contains(encoding))
goto found;
continue;
}
found:
int colon = ffn.lastIndexOf(':');
if (colon != -1) {
QByteArray s = ffn.left(colon);
ffn = ffn.mid(colon + 1);
if (s.contains("ds="))
*synth |= QFontEngine::SynthesizedBold;
if (s.contains("ai="))
*synth |= QFontEngine::SynthesizedItalic;
}
face_id.filename = (*it).toLocal8Bit() + '/' + ffn;
best_mapping = mapping;
if (best_match)
goto end;
}
}
}
end:
// qDebug("fontfile for %s is from '%s'\n got %s synth=%d", xname.data(),
// best_mapping.data(), face_id.filename.data(), *synth);
*freetype = QFreetypeFace::getFace(face_id);
if (!*freetype) {
face_id.index = 0;
face_id.filename = QByteArray();
}
return face_id;
}
#endif // QT_NO_FREETYPE
// defined in qfontdatabase_x11.cpp
extern int qt_mib_for_xlfd_encoding(const char *encoding);
extern int qt_xlfd_encoding_id(const char *encoding);
static inline XCharStruct *charStruct(XFontStruct *xfs, uint ch)
{
XCharStruct *xcs = 0;
unsigned char r = ch>>8;
unsigned char c = ch&0xff;
if (xfs->per_char &&
r >= xfs->min_byte1 &&
r <= xfs->max_byte1 &&
c >= xfs->min_char_or_byte2 &&
c <= xfs->max_char_or_byte2) {
xcs = xfs->per_char + ((r - xfs->min_byte1) *
(xfs->max_char_or_byte2 -
xfs->min_char_or_byte2 + 1)) +
(c - xfs->min_char_or_byte2);
if (xcs->width == 0 && xcs->ascent == 0 && xcs->descent == 0)
xcs = 0;
}
return xcs;
}
QFontEngineXLFD::QFontEngineXLFD(XFontStruct *fs, const QByteArray &name, int mib)
: _fs(fs), _name(name), _codec(0), _cmap(mib)
{
if (_cmap) _codec = QTextCodec::codecForMib(_cmap);
cache_cost = (((fs->max_byte1 - fs->min_byte1) *
(fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +
fs->max_char_or_byte2 - fs->min_char_or_byte2);
cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *
(fs->max_bounds.width * cache_cost / 8));
lbearing = SHRT_MIN;
rbearing = SHRT_MIN;
face_id.index = -1;
freetype = 0;
synth = 0;
}
QFontEngineXLFD::~QFontEngineXLFD()
{
XFreeFont(QX11Info::display(), _fs);
_fs = 0;
#ifndef QT_NO_FREETYPE
if (freetype)
freetype->release(face_id);
#endif
}
bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
{
if (*nglyphs < len) {
*nglyphs = len;
return false;
}
// filter out surrogates, we can't handle them anyway with XLFD fonts
QVarLengthArray<ushort> _s(len);
QChar *str = (QChar *)_s.data();
for (int i = 0; i < len; ++i) {
if (s[i].isHighSurrogate() && i < len-1 && s[i+1].isLowSurrogate()) {
*str = QChar();
++i;
} else {
*str = s[i];
}
++str;
}
len = str - (QChar *)_s.data();
str = (QChar *)_s.data();
bool mirrored = flags & QTextEngine::RightToLeft;
if (_codec) {
bool haveNbsp = false;
for (int i = 0; i < len; i++)
if (str[i].unicode() == 0xa0) {
haveNbsp = true;
break;
}
QVarLengthArray<unsigned short> ch(len);
QChar *chars = (QChar *)ch.data();
if (haveNbsp || mirrored) {
for (int i = 0; i < len; i++)
chars[i] = (str[i].unicode() == 0xa0 ? 0x20 :
(mirrored ? QChar::mirroredChar(str[i].unicode()) : str[i].unicode()));
} else {
for (int i = 0; i < len; i++)
chars[i] = str[i].unicode();
}
QTextCodec::ConverterState state;
state.flags = QTextCodec::ConvertInvalidToNull;
QByteArray ba = _codec->fromUnicode(chars, len, &state);
if (ba.length() == 2*len) {
// double byte encoding
const uchar *data = (const uchar *)ba.constData();
for (int i = 0; i < len; i++) {
glyphs->glyphs[i] = ((ushort)data[0] << 8) + data[1];
data += 2;
}
} else {
const uchar *data = (const uchar *)ba.constData();
for (int i = 0; i < len; i++)
glyphs->glyphs[i] = (ushort)data[i];
}
} else {
int i = len;
const QChar *c = str + len;
if (mirrored) {
while (c != str)
glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode());
} else {
while (c != str)
glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode();
}
}
*nglyphs = len;
glyphs->numGlyphs = len;
if (!(flags & QTextEngine::GlyphIndicesOnly))
recalcAdvances(glyphs, flags);
return true;
}
void QFontEngineXLFD::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags /*flags*/) const
{
int i = glyphs->numGlyphs;
XCharStruct *xcs;
// inlined for better performance
if (!_fs->per_char) {
xcs = &_fs->min_bounds;
while (i != 0) {
--i;
const unsigned char r = glyphs->glyphs[i] >> 8;
const unsigned char c = glyphs->glyphs[i] & 0xff;
if (r >= _fs->min_byte1 &&
r <= _fs->max_byte1 &&
c >= _fs->min_char_or_byte2 &&
c <= _fs->max_char_or_byte2) {
glyphs->advances_x[i] = xcs->width;
} else {
glyphs->glyphs[i] = 0;
}
}
}
else if (!_fs->max_byte1) {
XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;
while (i != 0) {
unsigned int gl = glyphs->glyphs[--i];
xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?
base + gl : 0;
if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) {
glyphs->glyphs[i] = 0;
} else {
glyphs->advances_x[i] = xcs->width;
}
}
}
else {
while (i != 0) {
xcs = charStruct(_fs, glyphs->glyphs[--i]);
if (!xcs) {
glyphs->glyphs[i] = 0;
} else {
glyphs->advances_x[i] = xcs->width;
}
}
}
}
glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs)
{
int i;
glyph_metrics_t overall;
// initialize with line height, we get the same behaviour on all platforms
overall.y = -ascent();
overall.height = ascent() + descent() + 1;
QFixed ymax;
QFixed xmax;
for (i = 0; i < glyphs.numGlyphs; i++) {
XCharStruct *xcs = charStruct(_fs, glyphs.glyphs[i]);
if (xcs) {
QFixed x = overall.xoff + glyphs.offsets[i].x + xcs->lbearing;
QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent;
overall.x = qMin(overall.x, x);
overall.y = qMin(overall.y, y);
// XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
} else {
QFixed size = _fs->ascent;
overall.x = qMin(overall.x, overall.xoff);
overall.y = qMin(overall.y, overall.yoff - size);
ymax = qMax(ymax, overall.yoff);
overall.xoff += size;
xmax = qMax(xmax, overall.xoff);
}
}
overall.height = qMax(overall.height, ymax - overall.y);
overall.width = xmax - overall.x;
return overall;
}
glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph)
{
glyph_metrics_t gm;
XCharStruct *xcs = charStruct(_fs, glyph);
if (xcs) {
// XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
// XCharStruct::width is defined as the advance
gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
xcs->width, 0);
} else {
QFixed size = ascent();
gm = glyph_metrics_t(0, size, size, size, size, 0);
}
return gm;
}
QFixed QFontEngineXLFD::ascent() const
{
return _fs->ascent;
}
QFixed QFontEngineXLFD::descent() const
{
return (_fs->descent-1);
}
QFixed QFontEngineXLFD::leading() const
{
QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent)
+ qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15);
return l.ceil();
}
qreal QFontEngineXLFD::maxCharWidth() const
{
return _fs->max_bounds.width;
}
// Loads the font for the specified script
static inline int maxIndex(XFontStruct *f) {
return (((f->max_byte1 - f->min_byte1) *
(f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +
f->max_char_or_byte2 - f->min_char_or_byte2);
}
qreal QFontEngineXLFD::minLeftBearing() const
{
if (lbearing == SHRT_MIN) {
if (_fs->per_char) {
XCharStruct *cs = _fs->per_char;
int nc = maxIndex(_fs) + 1;
int mx = cs->lbearing;
for (int c = 1; c < nc; c++) {
// ignore the bearings for characters whose ink is
// completely outside the normal bounding box
if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
(cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
continue;
int nmx = cs[c].lbearing;
if (nmx < mx)
mx = nmx;
}
((QFontEngineXLFD *)this)->lbearing = mx;
} else
((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;
}
return lbearing;
}
qreal QFontEngineXLFD::minRightBearing() const
{
if (rbearing == SHRT_MIN) {
if (_fs->per_char) {
XCharStruct *cs = _fs->per_char;
int nc = maxIndex(_fs) + 1;
int mx = cs->rbearing;
for (int c = 1; c < nc; c++) {
// ignore the bearings for characters whose ink is
// completely outside the normal bounding box
if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
(cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
continue;
int nmx = cs[c].rbearing;
if (nmx < mx)
mx = nmx;
}
((QFontEngineXLFD *)this)->rbearing = mx;
} else
((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;
}
return rbearing;
}
const char *QFontEngineXLFD::name() const
{
return _name;
}
bool QFontEngineXLFD::canRender(const QChar *string, int len)
{
QVarLengthGlyphLayoutArray glyphs(len);
int nglyphs = len;
if (stringToCMap(string, len, &glyphs, &nglyphs, 0) == false) {
glyphs.resize(nglyphs);
stringToCMap(string, len, &glyphs, &nglyphs, 0);
}
bool allExist = true;
for (int i = 0; i < nglyphs; i++) {
if (!glyphs.glyphs[i] || !charStruct(_fs, glyphs.glyphs[i])) {
allExist = false;
break;
}
}
return allExist;
}
QBitmap QFontEngineXLFD::bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags)
{
int w = metrics.width.toInt();
int h = metrics.height.toInt();
if (w <= 0 || h <= 0)
return QBitmap();
QPixmapData *data = new QX11PixmapData(QPixmapData::BitmapType);
data->resize(w, h);
QPixmap bm(data);
QPainter p(&bm);
p.fillRect(0, 0, w, h, Qt::color0);
p.setPen(Qt::color1);
QTextItemInt item;
item.flags = flags;
item.ascent = -metrics.y;
item.descent = metrics.height - item.ascent;
item.width = metrics.width;
item.chars = 0;
item.num_chars = 0;
item.logClusters = 0;
item.glyphs = glyphs;
item.fontEngine = this;
item.f = 0;
p.drawTextItem(QPointF(-metrics.x.toReal(), item.ascent.toReal()), item);
p.end();
return QBitmap(bm);
}
void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
{
// cannot use QFontEngine::addBitmapFontToPath(), since we don't
// have direct access to the glyph bitmaps, so we have to draw
// onto a QBitmap, then convert to QImage, then to path
glyph_metrics_t metrics = boundingBox(glyphs);
QImage image = bitmapForGlyphs(glyphs, metrics, flags).toImage();
if (image.isNull())
return;
image = image.convertToFormat(QImage::Format_Mono);
const uchar *image_data = image.bits();
uint bpl = image.bytesPerLine();
// from qfontengine.cpp
extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data,
int bpl, int w, int h, QPainterPath *path);
qt_addBitmapToPath(x, y + metrics.y.toReal(), image_data, bpl, image.width(), image.height(), path);
}
QFontEngine::FaceId QFontEngineXLFD::faceId() const
{
#ifndef QT_NO_FREETYPE
if (face_id.index == -1) {
face_id = fontFile(_name, &freetype, &synth);
if (_codec)
face_id.encoding = _codec->mibEnum();
if (freetype) {
const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();
} else {
face_id.index = 0;
face_id.filename = '-' + QFontEngine::properties().postscriptName;
}
}
#endif
return face_id;
}
QFontEngine::Properties QFontEngineXLFD::properties() const
{
if (face_id.index == -1)
(void)faceId();
#ifndef QT_NO_FREETYPE
if (freetype)
return freetype->properties();
#endif
return QFontEngine::properties();
}
void QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
{
if (face_id.index == -1)
(void)faceId();
#ifndef QT_NO_FREETYPE
if (!freetype)
#endif
{
QFontEngine::getUnscaledGlyph(glyph, path, metrics);
return;
}
#ifndef QT_NO_FREETYPE
freetype->lock();
FT_Face face = freetype->face;
FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0);
freetype->xsize = face->units_per_EM << 6;
freetype->ysize = face->units_per_EM << 6;
FT_Set_Transform(face, 0, 0);
glyph = glyphIndexToFreetypeGlyphIndex(glyph);
FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
int left = face->glyph->metrics.horiBearingX;
int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
int top = face->glyph->metrics.horiBearingY;
int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
QFixedPoint p;
p.x = 0;
p.y = 0;
metrics->width = QFixed::fromFixed(right-left);
metrics->height = QFixed::fromFixed(top-bottom);
metrics->x = QFixed::fromFixed(left);
metrics->y = QFixed::fromFixed(-top);
metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);
if (!FT_IS_SCALABLE(freetype->face))
QFreetypeFace::addBitmapToPath(face->glyph, p, path);
else
QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
FT_Set_Transform(face, &freetype->matrix, 0);
freetype->unlock();
#endif // QT_NO_FREETYPE
}
bool QFontEngineXLFD::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
#ifndef QT_NO_FREETYPE
if (face_id.index == -1)
(void)faceId();
if (!freetype)
return false;
return freetype->getSfntTable(tag, buffer, length);
#else
Q_UNUSED(tag);
Q_UNUSED(buffer);
Q_UNUSED(length);
return false;
#endif
}
int QFontEngineXLFD::synthesized() const
{
return synth;
}
QImage QFontEngineXLFD::alphaMapForGlyph(glyph_t glyph)
{
glyph_metrics_t metrics = boundingBox(glyph);
/*
printf("a) w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
metrics.width.toReal(),
metrics.height.toReal(),
metrics.xoff.toReal(),
metrics.yoff.toReal(),
metrics.x.toReal(),
metrics.y.toReal());
*/
QGlyphLayoutArray<1> glyphs;
glyphs.glyphs[0] = glyph;
QImage image = bitmapForGlyphs(glyphs, metrics).toImage();
//image.save(QString::fromLatin1("x11cache-%1.png").arg((int)glyph));
image = image.convertToFormat(QImage::Format_Indexed8);
QVector<QRgb> colors(256);
for (int i = 0; i < 256; ++i)
colors[i] = qRgba(0, 0, 0, i);
image.setColorTable(colors);
int width = image.width();
int height = image.height();
for (int y = 0; y < height; ++y) {
uchar *bits = image.scanLine(y);
for (int x = 0; x < width; ++x)
bits[x] = ~(bits[x]-1);
}
return image;
}
#ifndef QT_NO_FREETYPE
FT_Face QFontEngineXLFD::non_locked_face() const
{
return freetype ? freetype->face : 0;
}
uint QFontEngineXLFD::toUnicode(glyph_t g) const
{
if (_codec) {
QTextCodec::ConverterState state;
state.flags = QTextCodec::ConvertInvalidToNull;
uchar data[2];
int l = 1;
if (g > 255) {
data[0] = (g >> 8);
data[1] = (g & 255);
l = 2;
} else {
data[0] = g;
}
QString s = _codec->toUnicode((char *)data, l, &state);
Q_ASSERT(s.length() == 1);
g = s.at(0).unicode();
}
return g;
}
glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const
{
return FT_Get_Char_Index(freetype->face, toUnicode(g));
}
#endif
#ifndef QT_NO_FONTCONFIG
// ------------------------------------------------------------------

View file

@ -60,80 +60,6 @@ QT_BEGIN_NAMESPACE
class QFreetypeFace;
// --------------------------------------------------------------------------
class QFontEngineMultiXLFD : public QFontEngineMulti
{
public:
QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l);
~QFontEngineMultiXLFD();
void loadEngine(int at);
private:
QList<int> encodings;
QFontDef request;
};
/**
* \internal The font engine for X Logical Font Description (XLFD) fonts, which is for X11 systems without freetype.
*/
class QFontEngineXLFD : public QFontEngine
{
public:
QFontEngineXLFD(XFontStruct *f, const QByteArray &name, int mib);
~QFontEngineXLFD();
virtual QFontEngine::FaceId faceId() const;
QFontEngine::Properties properties() const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
virtual int synthesized() const;
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
QTextEngine::ShaperFlags flags) const;
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
virtual glyph_metrics_t boundingBox(glyph_t glyph);
virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags);
virtual QFixed ascent() const;
virtual QFixed descent() const;
virtual QFixed leading() const;
virtual qreal maxCharWidth() const;
virtual qreal minLeftBearing() const;
virtual qreal minRightBearing() const;
virtual QImage alphaMapForGlyph(glyph_t);
virtual inline Type type() const
{ return QFontEngine::XLFD; }
virtual bool canRender(const QChar *string, int len);
virtual const char *name() const;
inline XFontStruct *fontStruct() const
{ return _fs; }
#ifndef QT_NO_FREETYPE
FT_Face non_locked_face() const;
glyph_t glyphIndexToFreetypeGlyphIndex(glyph_t g) const;
#endif
uint toUnicode(glyph_t g) const;
private:
QBitmap bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags = 0);
XFontStruct *_fs;
QByteArray _name;
QTextCodec *_codec;
int _cmap;
int lbearing, rbearing;
mutable QFontEngine::FaceId face_id;
mutable QFreetypeFace *freetype;
mutable int synth;
};
#ifndef QT_NO_FONTCONFIG
class Q_GUI_EXPORT QFontEngineMultiFT : public QFontEngineMulti

View file

@ -73,7 +73,6 @@ public:
bool strikeOut() const;
bool fixedPitch() const;
QFont::StyleHint styleHint() const;
bool rawMode() const;
bool exactMatch() const;

View file

@ -287,16 +287,10 @@ QByteArray QFontSubset::glyphName(unsigned short unicode, bool symbol)
#ifndef QT_NO_FREETYPE
static FT_Face ft_face(const QFontEngine *engine)
{
#ifdef Q_WS_X11
#ifndef QT_NO_FONTCONFIG
#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
if (engine->type() == QFontEngine::Freetype) {
const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
return ft->non_locked_face();
} else
#endif
if (engine->type() == QFontEngine::XLFD) {
const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
return xlfd->non_locked_face();
}
#endif
return 0;
@ -318,10 +312,6 @@ QByteArray QFontSubset::glyphName(unsigned int glyph, const QVector<int> reverse
char name[32];
name[0] = 0;
if (face && FT_HAS_GLYPH_NAMES(face)) {
#if defined(Q_WS_X11)
if (fontEngine->type() == QFontEngine::XLFD)
glyphIndex = static_cast<QFontEngineXLFD *>(fontEngine)->glyphIndexToFreetypeGlyphIndex(glyphIndex);
#endif
FT_Get_Glyph_Name(face, glyphIndex, &name, 32);
if (name[0] == '.') // fix broken PS fonts returning .notdef for many glyphs
name[0] = 0;
@ -329,12 +319,6 @@ QByteArray QFontSubset::glyphName(unsigned int glyph, const QVector<int> reverse
if (name[0]) {
s << '/' << name;
} else
#endif
#if defined(Q_WS_X11)
if (fontEngine->type() == QFontEngine::XLFD) {
uint uc = static_cast<QFontEngineXLFD *>(fontEngine)->toUnicode(glyphIndex);
s << '/' << glyphName(uc, false /* ### */);
} else
#endif
if (reverseMap[glyphIndex] && reverseMap[glyphIndex] < 0x10000) {
s << '/' << glyphName(reverseMap[glyphIndex], false);

View file

@ -1,364 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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 "qglobal.h"
#if !defined(QT_NO_RAWFONT)
#include "qglyphrun.h"
#include "qglyphrun_p.h"
QT_BEGIN_NAMESPACE
/*!
\class QGlyphRun
\brief The QGlyphRun class provides direct access to the internal glyphs in a font.
\since 4.8
\ingroup text
\mainclass
When Qt displays a string of text encoded in Unicode, it will first convert the Unicode points
into a list of glyph indexes and a list of positions based on one or more fonts. The Unicode
representation of the text and the QFont object will in this case serve as a convenient
abstraction that hides the details of what actually takes place when displaying the text
on-screen. For instance, by the time the text actually reaches the screen, it may be represented
by a set of fonts in addition to the one specified by the user, e.g. in case the originally
selected font did not support all the writing systems contained in the text.
Under certain circumstances, it can be useful as an application developer to have more low-level
control over which glyphs in a specific font are drawn to the screen. This could for instance
be the case in applications that use an external font engine and text shaper together with Qt.
QGlyphRun provides an interface to the raw data needed to get text on the screen. It
contains a list of glyph indexes, a position for each glyph and a font.
It is the user's responsibility to ensure that the selected font actually contains the
provided glyph indexes.
QTextLayout::glyphRuns() or QTextFragment::glyphRuns() can be used to convert unicode encoded
text into a list of QGlyphRun objects, and QPainter::drawGlyphRun() can be used to draw the
glyphs.
\note Please note that QRawFont is considered local to the thread in which it is constructed.
This in turn means that a new QRawFont will have to be created and set on the QGlyphRun if it is
moved to a different thread. If the QGlyphRun contains a reference to a QRawFont from a different
thread than the current, it will not be possible to draw the glyphs using a QPainter, as the
QRawFont is considered invalid and inaccessible in this case.
*/
/*!
Constructs an empty QGlyphRun object.
*/
QGlyphRun::QGlyphRun() : d(new QGlyphRunPrivate)
{
}
/*!
Constructs a QGlyphRun object which is a copy of \a other.
*/
QGlyphRun::QGlyphRun(const QGlyphRun &other)
{
d = other.d;
}
/*!
Destroys the QGlyphRun.
*/
QGlyphRun::~QGlyphRun()
{
// Required for QExplicitlySharedDataPointer
}
/*!
\internal
*/
void QGlyphRun::detach()
{
if (d->ref != 1)
d.detach();
}
/*!
Assigns \a other to this QGlyphRun object.
*/
QGlyphRun &QGlyphRun::operator=(const QGlyphRun &other)
{
d = other.d;
return *this;
}
/*!
Compares \a other to this QGlyphRun object. Returns true if the list of glyph indexes,
the list of positions and the font are all equal, otherwise returns false.
*/
bool QGlyphRun::operator==(const QGlyphRun &other) const
{
if (d == other.d)
return true;
if ((d->glyphIndexDataSize != other.d->glyphIndexDataSize)
|| (d->glyphPositionDataSize != other.d->glyphPositionDataSize)) {
return false;
}
if (d->glyphIndexData != other.d->glyphIndexData) {
for (int i = 0; i < d->glyphIndexDataSize; ++i) {
if (d->glyphIndexData[i] != other.d->glyphIndexData[i])
return false;
}
}
if (d->glyphPositionData != other.d->glyphPositionData) {
for (int i = 0; i < d->glyphPositionDataSize; ++i) {
if (d->glyphPositionData[i] != other.d->glyphPositionData[i])
return false;
}
}
return (d->overline == other.d->overline
&& d->underline == other.d->underline
&& d->strikeOut == other.d->strikeOut
&& d->rawFont == other.d->rawFont);
}
/*!
\fn bool QGlyphRun::operator!=(const QGlyphRun &other) const
Compares \a other to this QGlyphRun object. Returns true if any of the list of glyph
indexes, the list of positions or the font are different, otherwise returns false.
*/
/*!
Returns the font selected for this QGlyphRun object.
\sa setRawFont()
*/
QRawFont QGlyphRun::rawFont() const
{
return d->rawFont;
}
/*!
Sets the font specified by \a rawFont to be the font used to look up the
glyph indexes.
\sa rawFont(), setGlyphIndexes()
*/
void QGlyphRun::setRawFont(const QRawFont &rawFont)
{
detach();
d->rawFont = rawFont;
}
/*!
Returns the glyph indexes for this QGlyphRun object.
\sa setGlyphIndexes(), setPositions()
*/
QVector<quint32> QGlyphRun::glyphIndexes() const
{
if (d->glyphIndexes.constData() == d->glyphIndexData) {
return d->glyphIndexes;
} else {
QVector<quint32> indexes(d->glyphIndexDataSize);
memcpy(indexes.data(), d->glyphIndexData, d->glyphIndexDataSize * sizeof(quint32));
return indexes;
}
}
/*!
Set the glyph indexes for this QGlyphRun object to \a glyphIndexes. The glyph indexes must
be valid for the selected font.
*/
void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes)
{
detach();
d->glyphIndexes = glyphIndexes; // Keep a reference to the QVector to avoid copying
d->glyphIndexData = glyphIndexes.constData();
d->glyphIndexDataSize = glyphIndexes.size();
}
/*!
Returns the position of the edge of the baseline for each glyph in this set of glyph indexes.
*/
QVector<QPointF> QGlyphRun::positions() const
{
if (d->glyphPositions.constData() == d->glyphPositionData) {
return d->glyphPositions;
} else {
QVector<QPointF> glyphPositions(d->glyphPositionDataSize);
memcpy(glyphPositions.data(), d->glyphPositionData,
d->glyphPositionDataSize * sizeof(QPointF));
return glyphPositions;
}
}
/*!
Sets the positions of the edge of the baseline for each glyph in this set of glyph indexes to
\a positions.
*/
void QGlyphRun::setPositions(const QVector<QPointF> &positions)
{
detach();
d->glyphPositions = positions; // Keep a reference to the vector to avoid copying
d->glyphPositionData = positions.constData();
d->glyphPositionDataSize = positions.size();
}
/*!
Clears all data in the QGlyphRun object.
*/
void QGlyphRun::clear()
{
detach();
d->rawFont = QRawFont();
d->strikeOut = false;
d->overline = false;
d->underline = false;
setPositions(QVector<QPointF>());
setGlyphIndexes(QVector<quint32>());
}
/*!
Sets the glyph indexes and positions of this QGlyphRun to use the first \a size
elements in the arrays \a glyphIndexArray and \a glyphPositionArray. The data is
\e not copied. The caller must guarantee that the arrays are not deleted as long
as this QGlyphRun and any copies of it exists.
\sa setGlyphIndexes(), setPositions()
*/
void QGlyphRun::setRawData(const quint32 *glyphIndexArray, const QPointF *glyphPositionArray,
int size)
{
detach();
d->glyphIndexes.clear();
d->glyphPositions.clear();
d->glyphIndexData = glyphIndexArray;
d->glyphPositionData = glyphPositionArray;
d->glyphIndexDataSize = d->glyphPositionDataSize = size;
}
/*!
Returns true if this QGlyphRun should be painted with an overline decoration.
\sa setOverline()
*/
bool QGlyphRun::overline() const
{
return d->overline;
}
/*!
Indicates that this QGlyphRun should be painted with an overline decoration if \a overline is true.
Otherwise the QGlyphRun should be painted with no overline decoration.
\sa overline()
*/
void QGlyphRun::setOverline(bool overline)
{
if (d->overline == overline)
return;
detach();
d->overline = overline;
}
/*!
Returns true if this QGlyphRun should be painted with an underline decoration.
\sa setUnderline()
*/
bool QGlyphRun::underline() const
{
return d->underline;
}
/*!
Indicates that this QGlyphRun should be painted with an underline decoration if \a underline is
true. Otherwise the QGlyphRun should be painted with no underline decoration.
\sa underline()
*/
void QGlyphRun::setUnderline(bool underline)
{
if (d->underline == underline)
return;
detach();
d->underline = underline;
}
/*!
Returns true if this QGlyphRun should be painted with a strike out decoration.
\sa setStrikeOut()
*/
bool QGlyphRun::strikeOut() const
{
return d->strikeOut;
}
/*!
Indicates that this QGlyphRun should be painted with an strike out decoration if \a strikeOut is
true. Otherwise the QGlyphRun should be painted with no strike out decoration.
\sa strikeOut()
*/
void QGlyphRun::setStrikeOut(bool strikeOut)
{
if (d->strikeOut == strikeOut)
return;
detach();
d->strikeOut = strikeOut;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View file

@ -1,112 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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$
**
****************************************************************************/
#ifndef QGLYPHRUN_H
#define QGLYPHRUN_H
#include <QtCore/qsharedpointer.h>
#include <QtCore/qvector.h>
#include <QtCore/qpoint.h>
#include <QtGui/qrawfont.h>
#if !defined(QT_NO_RAWFONT)
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QGlyphRunPrivate;
class Q_GUI_EXPORT QGlyphRun
{
public:
QGlyphRun();
QGlyphRun(const QGlyphRun &other);
~QGlyphRun();
QRawFont rawFont() const;
void setRawFont(const QRawFont &rawFont);
void setRawData(const quint32 *glyphIndexArray,
const QPointF *glyphPositionArray,
int size);
QVector<quint32> glyphIndexes() const;
void setGlyphIndexes(const QVector<quint32> &glyphIndexes);
QVector<QPointF> positions() const;
void setPositions(const QVector<QPointF> &positions);
void clear();
QGlyphRun &operator=(const QGlyphRun &other);
bool operator==(const QGlyphRun &other) const;
inline bool operator!=(const QGlyphRun &other) const
{ return !operator==(other); }
void setOverline(bool overline);
bool overline() const;
void setUnderline(bool underline);
bool underline() const;
void setStrikeOut(bool strikeOut);
bool strikeOut() const;
private:
friend class QGlyphRunPrivate;
friend class QTextLine;
QGlyphRun operator+(const QGlyphRun &other) const;
QGlyphRun &operator+=(const QGlyphRun &other);
void detach();
QExplicitlySharedDataPointer<QGlyphRunPrivate> d;
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QT_NO_RAWFONT
#endif // QGLYPHS_H

View file

@ -1,122 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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$
**
****************************************************************************/
#ifndef QGLYPHRUN_P_H
#define QGLYPHRUN_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of internal files. This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//
#include "qglyphrun.h"
#include "qrawfont.h"
#include <qfont.h>
#if !defined(QT_NO_RAWFONT)
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QGlyphRunPrivate: public QSharedData
{
public:
QGlyphRunPrivate()
: overline(false)
, underline(false)
, strikeOut(false)
, glyphIndexData(glyphIndexes.constData())
, glyphIndexDataSize(0)
, glyphPositionData(glyphPositions.constData())
, glyphPositionDataSize(0)
{
}
QGlyphRunPrivate(const QGlyphRunPrivate &other)
: QSharedData(other)
, glyphIndexes(other.glyphIndexes)
, glyphPositions(other.glyphPositions)
, rawFont(other.rawFont)
, overline(other.overline)
, underline(other.underline)
, strikeOut(other.strikeOut)
, glyphIndexData(other.glyphIndexData)
, glyphIndexDataSize(other.glyphIndexDataSize)
, glyphPositionData(other.glyphPositionData)
, glyphPositionDataSize(other.glyphPositionDataSize)
{
}
QVector<quint32> glyphIndexes;
QVector<QPointF> glyphPositions;
QRawFont rawFont;
uint overline : 1;
uint underline : 1;
uint strikeOut : 1;
const quint32 *glyphIndexData;
int glyphIndexDataSize;
const QPointF *glyphPositionData;
int glyphPositionDataSize;
static QGlyphRunPrivate *get(const QGlyphRun &glyphRun)
{
return glyphRun.d.data();
}
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QGLYPHS_P_H
#endif // QT_NO_RAWFONT

View file

@ -1,688 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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 "qglobal.h"
#if !defined(QT_NO_RAWFONT)
#include "qrawfont.h"
#include "qrawfont_p.h"
#include <QtCore/qendian.h>
QT_BEGIN_NAMESPACE
/*!
\class QRawFont
\brief The QRawFont class provides access to a single physical instance of a font.
\since 4.8
\ingroup text
\mainclass
\note QRawFont is a low level class. For most purposes QFont is a more appropriate class.
Most commonly, when presenting text in a user interface, the exact fonts used
to render the characters is to some extent unknown. This can be the case for several
reasons: For instance, the actual, physical fonts present on the target system could be
unexpected to the developers, or the text could contain user selected styles, sizes or
writing systems that are not supported by font chosen in the code.
Therefore, Qt's QFont class really represents a query for fonts. When text is interpreted,
Qt will do its best to match the text to the query, but depending on the support, different
fonts can be used behind the scenes.
For most use cases, this is both expected and necessary, as it minimizes the possibility of
text in the user interface being undisplayable. In some cases, however, more direct control
over the process might be useful. It is for these use cases the QRawFont class exists.
A QRawFont object represents a single, physical instance of a given font in a given pixel size.
I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
user specified pixel size to convert metrics into logical pixel units. It can be used in
combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and
also have accessors to some relevant data in the physical font.
QRawFont only provides support for the main font technologies: FreeType on UNIX platforms. For
other font back-ends, the APIs will be disabled.
QRawFont can be constructed in a number of ways:
\list
\o It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
used to render each portion of the text.
\o It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
will return a QRawFont object representing the font that will be selected as response to
the QFont query and the selected writing system.
\o It can be constructed by passing a file name or QByteArray directly to the QRawFont
constructor, or by calling loadFromFile() or loadFromData(). In this case, the
font will not be registered in QFontDatabase, and it will not be available as part of
regular font selection.
\endlist
QRawFont is considered local to the thread in which it is constructed (either using a
constructor, or by calling loadFromData() or loadFromFile()). The QRawFont cannot be moved to a
different thread, but will have to be recreated in the thread in question.
\note For the requirement of caching glyph indexes and font selections for static text to avoid
reshaping and relayouting in the inner loop of an application, a better choice is the QStaticText
class, since it optimizes the memory cost of the cache and also provides the possibility of paint
engine specific caches for an additional speed-up.
*/
/*!
\enum QRawFont::AntialiasingType
This enum represents the different ways a glyph can be rasterized in the function
alphaMapForGlyph().
\value PixelAntialiasing Will rasterize by measuring the coverage of the shape on whole pixels.
The returned image contains the alpha values of each pixel based on the coverage of
the glyph shape.
\value SubPixelAntialiasing Will rasterize by measuring the coverage of each subpixel,
returning a separate alpha value for each of the red, green and blue components of
each pixel.
*/
/*!
Constructs an invalid QRawFont.
*/
QRawFont::QRawFont()
: d(new QRawFontPrivate)
{
}
/*!
Constructs a QRawFont representing the font contained in the file referenced
by \a fileName for the size (in pixels) given by \a pixelSize, and using the
hinting preference specified by \a hintingPreference.
\note The referenced file must contain a TrueType or OpenType font.
*/
QRawFont::QRawFont(const QString &fileName,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
: d(new QRawFontPrivate)
{
loadFromFile(fileName, pixelSize, hintingPreference);
}
/*!
Constructs a QRawFont representing the font contained in the supplied
\a fontData for the size (in pixels) given by \a pixelSize, and using the
hinting preference specified by \a hintingPreference.
\note The data must contain a TrueType or OpenType font.
*/
QRawFont::QRawFont(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
: d(new QRawFontPrivate)
{
loadFromData(fontData, pixelSize, hintingPreference);
}
/*!
Creates a QRawFont which is a copy of \a other.
*/
QRawFont::QRawFont(const QRawFont &other)
{
d = other.d;
}
/*!
Destroys the QRawFont
*/
QRawFont::~QRawFont()
{
}
/*!
Assigns \a other to this QRawFont.
*/
QRawFont &QRawFont::operator=(const QRawFont &other)
{
d = other.d;
return *this;
}
/*!
Returns true if the QRawFont is valid and false otherwise.
*/
bool QRawFont::isValid() const
{
return d->isValid();
}
/*!
Replaces the current QRawFont with the contents of the file referenced
by \a fileName for the size (in pixels) given by \a pixelSize, and using the
hinting preference specified by \a hintingPreference.
The file must reference a TrueType or OpenType font.
\sa loadFromData()
*/
void QRawFont::loadFromFile(const QString &fileName,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
QFile file(fileName);
if (file.open(QIODevice::ReadOnly))
loadFromData(file.readAll(), pixelSize, hintingPreference);
}
/*!
Replaces the current QRawFont with the font contained in the supplied
\a fontData for the size (in pixels) given by \a pixelSize, and using the
hinting preference specified by \a hintingPreference.
The \a fontData must contain a TrueType or OpenType font.
\sa loadFromFile()
*/
void QRawFont::loadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
d.detach();
d->cleanUp();
d->hintingPreference = hintingPreference;
d->thread = QThread::currentThread();
d->platformLoadFromData(fontData, pixelSize, hintingPreference);
}
/*!
This function returns a rasterized image of the glyph at the given
\a glyphIndex in the underlying font, using the \a transform specified.
If the QRawFont is not valid, this function will return an invalid QImage.
If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be
in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of
the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of
QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the
rasterization.
\sa pathForGlyph(), QPainter::drawGlyphRun()
*/
QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
const QTransform &transform) const
{
if (!d->isValid())
return QImage();
if (antialiasingType == SubPixelAntialiasing)
return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform);
return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
}
/*!
This function returns the shape of the glyph at a given \a glyphIndex in the underlying font
if the QRawFont is valid. Otherwise, it returns an empty QPainterPath.
The returned glyph will always be unhinted.
\sa alphaMapForGlyph(), QPainterPath::addText()
*/
QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
{
if (!d->isValid())
return QPainterPath();
QFixedPoint position;
QPainterPath path;
d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, 0);
return path;
}
/*!
Returns true if this QRawFont is equal to \a other. Otherwise, returns false.
*/
bool QRawFont::operator==(const QRawFont &other) const
{
return d->fontEngine == other.d->fontEngine;
}
/*!
\fn bool QRawFont::operator!=(const QRawFont &other) const
Returns true if this QRawFont is not equal to \a other. Otherwise, returns false.
*/
/*!
Returns the ascent of this QRawFont in pixel units.
\sa QFontMetricsF::ascent()
*/
qreal QRawFont::ascent() const
{
return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
}
/*!
Returns the descent of this QRawFont in pixel units.
\sa QFontMetricsF::descent()
*/
qreal QRawFont::descent() const
{
return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
}
/*!
Returns the xHeight of this QRawFont in pixel units.
\sa QFontMetricsF::xHeight()
*/
qreal QRawFont::xHeight() const
{
return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
}
/*!
Returns the leading of this QRawFont in pixel units.
\sa QFontMetricsF::leading()
*/
qreal QRawFont::leading() const
{
return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
}
/*!
Returns the average character width of this QRawFont in pixel units.
\sa QFontMetricsF::averageCharWidth()
*/
qreal QRawFont::averageCharWidth() const
{
return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
}
/*!
Returns the width of the widest character in the font.
\sa QFontMetricsF::maxWidth()
*/
qreal QRawFont::maxCharWidth() const
{
return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
}
/*!
Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are
rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert
internal metrics from design units to logical pixel units.
\sa setPixelSize()
*/
qreal QRawFont::pixelSize() const
{
return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
}
/*!
Returns the number of design units define the width and height of the em square
for this QRawFont. This value is used together with the pixel size when converting design metrics
to pixel units, as the internal metrics are specified in design units and the pixel size gives
the size of 1 em in pixels.
\sa pixelSize(), setPixelSize()
*/
qreal QRawFont::unitsPerEm() const
{
return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
}
/*!
Returns the family name of this QRawFont.
*/
QString QRawFont::familyName() const
{
return d->isValid() ? d->fontEngine->fontDef.family : QString();
}
/*!
Returns the style name of this QRawFont.
\sa QFont::styleName()
*/
QString QRawFont::styleName() const
{
return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
}
/*!
Returns the style of this QRawFont.
\sa QFont::style()
*/
QFont::Style QRawFont::style() const
{
return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
}
/*!
Returns the weight of this QRawFont.
\sa QFont::weight()
*/
int QRawFont::weight() const
{
return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
}
/*!
Converts the string of unicode points given by \a text to glyph indexes
using the CMAP table in the underlying font, and returns a vector containing
the result.
Note that, in cases where there are other tables in the font that affect the
shaping of the text, the returned glyph indexes will not correctly represent
the rendering of the text. To get the correctly shaped text, you can use
QTextLayout to lay out and shape the text, then call QTextLayout::glyphs()
to get the set of glyph index list and QRawFont pairs.
\sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
*/
QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
{
if (!d->isValid())
return QVector<quint32>();
int nglyphs = text.size();
QVarLengthGlyphLayoutArray glyphs(nglyphs);
if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) {
glyphs.resize(nglyphs);
if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) {
Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
return QVector<quint32>();
}
}
QVector<quint32> glyphIndexes;
for (int i=0; i<nglyphs; ++i)
glyphIndexes.append(glyphs.glyphs[i]);
return glyphIndexes;
}
/*!
Converts a string of unicode points to glyph indexes using the CMAP table in the
underlying font. The function works like glyphIndexesForString() except it take
an array (\a chars), the results will be returned though \a glyphIndexes array
and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array
must be at least \a numChars, if that's still not enough, this function will return
false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs.
\sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphRun,
QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
*/
bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
{
if (!d->isValid())
return false;
QGlyphLayout glyphs;
glyphs.glyphs = glyphIndexes;
return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QTextEngine::GlyphIndicesOnly);
}
/*!
Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
give the distance from the position of a given glyph to where the next glyph should be drawn
to make it appear as if the two glyphs are unspaced.
\sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
*/
QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
{
if (!d->isValid())
return QVector<QPointF>();
int numGlyphs = glyphIndexes.size();
QVarLengthGlyphLayoutArray glyphs(numGlyphs);
memcpy(glyphs.glyphs, glyphIndexes.data(), numGlyphs * sizeof(quint32));
d->fontEngine->recalcAdvances(&glyphs, 0);
QVector<QPointF> advances;
for (int i=0; i<numGlyphs; ++i)
advances.append(QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal()));
return advances;
}
/*!
Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
give the distance from the position of a given glyph to where the next glyph should be drawn
to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
array \a glyphIndexes while the results are returned through \a advances, both of them must
have \a numGlyphs elements.
\sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
*/
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
{
if (!d->isValid())
return false;
QGlyphLayout glyphs;
glyphs.glyphs = const_cast<HB_Glyph *>(glyphIndexes);
glyphs.numGlyphs = numGlyphs;
QVarLengthArray<QFixed> advances_x(numGlyphs);
QVarLengthArray<QFixed> advances_y(numGlyphs);
glyphs.advances_x = advances_x.data();
glyphs.advances_y = advances_y.data();
d->fontEngine->recalcAdvances(&glyphs, 0);
for (int i=0; i<numGlyphs; ++i)
advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal());
return true;
}
/*!
Returns the hinting preference used to construct this QRawFont.
\sa QFont::hintingPreference()
*/
QFont::HintingPreference QRawFont::hintingPreference() const
{
return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
}
/*!
Retrieves the sfnt table named \a tagName from the underlying physical font, or an empty
byte array if no such table was found. The returned font table's byte order is Big Endian, like
the sfnt format specifies. The \a tagName must be four characters long and should be formatted
in the default endianness of the current platform.
*/
QByteArray QRawFont::fontTable(const char *tagName) const
{
if (!d->isValid())
return QByteArray();
const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
return d->fontEngine->getSfntTable(qToBigEndian(*tagId));
}
// From qfontdatabase.cpp
extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2]);
/*!
Returns a list of writing systems supported by the font according to designer supplied
information in the font file. Please note that this does not guarantee support for a
specific unicode point in the font. You can use the supportsCharacter() to check support
for a single, specific character.
\note The list is determined based on the unicode ranges and codepage ranges set in the font's
OS/2 table and requires such a table to be present in the underlying font file.
\sa supportsCharacter()
*/
QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
{
if (d->isValid()) {
QByteArray os2Table = fontTable("OS/2");
if (os2Table.size() > 86) {
char *data = os2Table.data();
quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
quint32 unicodeRanges[4];
quint32 codepageRanges[2];
for (int i=0; i<4; ++i) {
if (i < 2)
codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges[i]);
unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges[i]);
}
return qt_determine_writing_systems_from_truetype_bits(unicodeRanges, codepageRanges);
}
}
return QList<QFontDatabase::WritingSystem>();
}
/*!
Returns true if the font has a glyph that corresponds to the given \a character.
\sa supportedWritingSystems()
*/
bool QRawFont::supportsCharacter(QChar character) const
{
return d->isValid() && d->fontEngine->canRender(&character, 1);
}
/*!
\overload
Returns true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4.
\sa supportedWritingSystems()
*/
bool QRawFont::supportsCharacter(quint32 ucs4) const
{
QChar str[2];
int len;
if (!QChar::requiresSurrogates(ucs4)) {
str[0] = QChar(ucs4);
len = 1;
} else {
str[0] = QChar(QChar::highSurrogate(ucs4));
str[1] = QChar(QChar::lowSurrogate(ucs4));
len = 2;
}
return d->isValid() && d->fontEngine->canRender(str, len);
}
// qfontdatabase.cpp
extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
/*!
Fetches the physical representation based on a \a font query. The physical font returned is
the font that will be preferred by Qt in order to display text in the selected \a writingSystem.
*/
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
{
QRawFont rawFont;
QFontPrivate *font_d = QFontPrivate::get(font);
int script = qt_script_for_writing_system(writingSystem);
QFontEngine *fe = font_d->engineForScript(script);
if (fe != 0 && fe->type() == QFontEngine::Multi) {
QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
fe = multiEngine->engine(0);
if (fe == 0) {
multiEngine->loadEngine(0);
fe = multiEngine->engine(0);
}
}
if (fe != 0) {
rawFont.d.data()->fontEngine = fe;
rawFont.d.data()->fontEngine->ref.ref();
rawFont.d.data()->hintingPreference = font.hintingPreference();
}
return rawFont;
}
/*!
Sets the pixel size with which this font should be rendered to \a pixelSize.
*/
void QRawFont::setPixelSize(qreal pixelSize)
{
if (d->fontEngine == 0)
return;
d.detach();
QFontEngine *oldFontEngine = d->fontEngine;
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
if (d->fontEngine != 0)
d->fontEngine->ref.ref();
if (!oldFontEngine->ref.deref())
delete oldFontEngine;
}
/*!
\internal
*/
void QRawFontPrivate::cleanUp()
{
if (fontEngine != 0 && !fontEngine->ref.deref())
delete fontEngine;
fontEngine = 0;
hintingPreference = QFont::PreferDefaultHinting;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View file

@ -1,146 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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$
**
****************************************************************************/
#ifndef QRAWFONT_H
#define QRAWFONT_H
#include <QtCore/qstring.h>
#include <QtCore/qiodevice.h>
#include <QtCore/qglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qpoint.h>
#include <QtGui/qfont.h>
#include <QtGui/qtransform.h>
#include <QtGui/qfontdatabase.h>
#if !defined(QT_NO_RAWFONT)
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QRawFontPrivate;
class Q_GUI_EXPORT QRawFont
{
public:
enum AntialiasingType {
PixelAntialiasing,
SubPixelAntialiasing
};
QRawFont();
QRawFont(const QString &fileName,
qreal pixelSize,
QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
QRawFont(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
QRawFont(const QRawFont &other);
~QRawFont();
bool isValid() const;
QRawFont &operator=(const QRawFont &other);
bool operator==(const QRawFont &other) const;
inline bool operator!=(const QRawFont &other) const
{ return !operator==(other); }
QString familyName() const;
QString styleName() const;
QFont::Style style() const;
int weight() const;
QVector<quint32> glyphIndexesForString(const QString &text) const;
QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const;
bool glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const;
bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const;
QImage alphaMapForGlyph(quint32 glyphIndex,
AntialiasingType antialiasingType = SubPixelAntialiasing,
const QTransform &transform = QTransform()) const;
QPainterPath pathForGlyph(quint32 glyphIndex) const;
void setPixelSize(qreal pixelSize);
qreal pixelSize() const;
QFont::HintingPreference hintingPreference() const;
qreal ascent() const;
qreal descent() const;
qreal leading() const;
qreal xHeight() const;
qreal averageCharWidth() const;
qreal maxCharWidth() const;
qreal unitsPerEm() const;
void loadFromFile(const QString &fileName,
qreal pixelSize,
QFont::HintingPreference hintingPreference);
void loadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference);
bool supportsCharacter(quint32 ucs4) const;
bool supportsCharacter(QChar character) const;
QList<QFontDatabase::WritingSystem> supportedWritingSystems() const;
QByteArray fontTable(const char *tagName) const;
static QRawFont fromFont(const QFont &font,
QFontDatabase::WritingSystem writingSystem = QFontDatabase::Any);
private:
friend class QRawFontPrivate;
QExplicitlySharedDataPointer<QRawFontPrivate> d;
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QT_NO_RAWFONT
#endif // QRAWFONT_H

View file

@ -1,136 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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 <QtCore/qglobal.h>
#if !defined(QT_NO_RAWFONT)
#include "qrawfont_p.h"
#include "qfontengine_ft_p.h"
#include "quuid.h"
#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
# include "qfontengine_x11_p.h"
#endif
QT_BEGIN_NAMESPACE
class QFontEngineFTRawFont
#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
: public QFontEngineX11FT
#else
: public QFontEngineFT
#endif
{
public:
QFontEngineFTRawFont(const QFontDef &fontDef)
#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
: QFontEngineX11FT(fontDef)
#else
: QFontEngineFT(fontDef)
#endif
{
}
void updateFamilyNameAndStyle()
{
fontDef.family = QString::fromAscii(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);
}
};
void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_ASSERT(fontEngine == 0);
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
if (!fe->initFromData(fontData)) {
delete fe;
return;
}
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;
}
fontEngine = fe;
fontEngine->ref.ref();
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View file

@ -1,114 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company 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$
**
****************************************************************************/
#ifndef QRAWFONTPRIVATE_P_H
#define QRAWFONTPRIVATE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qrawfont.h"
#include "qfontengine_p.h"
#include <QtCore/qthread.h>
#include <QtCore/qthreadstorage.h>
#if !defined(QT_NO_RAWFONT)
QT_BEGIN_NAMESPACE
namespace { class CustomFontFileLoader; }
class Q_AUTOTEST_EXPORT QRawFontPrivate
{
public:
QRawFontPrivate()
: fontEngine(0)
, hintingPreference(QFont::PreferDefaultHinting)
, thread(0)
{}
QRawFontPrivate(const QRawFontPrivate &other)
: fontEngine(other.fontEngine)
, hintingPreference(other.hintingPreference)
, thread(other.thread)
{
if (fontEngine != 0)
fontEngine->ref.ref();
}
~QRawFontPrivate()
{
Q_ASSERT(ref == 0);
cleanUp();
}
inline bool isValid() const
{
Q_ASSERT(thread == 0 || thread == QThread::currentThread());
return fontEngine != 0;
}
void cleanUp();
void platformLoadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference);
static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
QFontEngine *fontEngine;
QFont::HintingPreference hintingPreference;
QThread *thread;
QAtomicInt ref;
};
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT
#endif // QRAWFONTPRIVATE_P_H

View file

@ -2303,12 +2303,10 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
? static_cast<QFontEngineMulti *>(fe)->engine(0)
: fe;
// the lookup can be really slow when we use XLFD fonts
if (feForEllipsis->type() != QFontEngine::XLFD
&& feForEllipsis->canRender(&ellipsisChar, 1)) {
int nGlyphs = 1;
feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0);
}
if (feForEllipsis->canRender(&ellipsisChar, 1)) {
int nGlyphs = 1;
feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0);
}
}
if (ellipsisGlyph.glyphs[0]) {

View file

@ -53,16 +53,11 @@
#include "qtextformat_p.h"
#include "qstyleoption.h"
#include "qpainterpath.h"
#include "qglyphrun.h"
#include "qglyphrun_p.h"
#include "qrawfont.h"
#include "qrawfont_p.h"
#include <limits.h>
#include <qdebug.h>
#include "qdebug.h"
#include "qfontengine_p.h"
#include <limits.h>
#if !defined(QT_NO_FREETYPE)
# include "qfontengine_ft_p.h"
#endif
@ -1004,26 +999,6 @@ static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
return clip.isValid() ? (rect & clip) : rect;
}
/*!
Returns the glyph indexes and positions for all glyphs in this QTextLayout. This is an
expensive function, and should not be called in a time sensitive context.
\since 4.8
\sa draw(), QPainter::drawGlyphRun()
*/
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> QTextLayout::glyphRuns() const
{
QList<QGlyphRun> glyphs;
for (int i=0; i<d->lines.size(); ++i)
glyphs += QTextLine(i, d).glyphs(-1, -1);
return glyphs;
}
#endif // QT_NO_RAWFONT
/*!
Draws the whole layout on the painter \a p at the position specified by \a pos.
The rendered layout includes the given \a selections and is clipped within
@ -2106,170 +2081,6 @@ namespace {
};
}
/*!
\internal
Returns the glyph indexes and positions for all glyphs in this QTextLine which reside in
QScriptItems that overlap with the range defined by \a from and \a length. The arguments
specify characters, relative to the text in the layout. Note that it is not possible to
use this function to retrieve a subset of the glyphs in a QScriptItem.
\since 4.8
\sa QTextLayout::glyphRuns()
*/
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> QTextLine::glyphs(int from, int length) const
{
const QScriptLine &line = eng->lines[i];
if (line.length == 0)
return QList<QGlyphRun>();
QHash<QFontEngine *, GlyphInfo> glyphLayoutHash;
QTextLineItemIterator iterator(eng, i);
qreal y = line.y.toReal() + line.base().toReal();
while (!iterator.atEnd()) {
QScriptItem &si = iterator.next();
if (si.analysis.flags >= QScriptAnalysis::TabOrObject)
continue;
QPointF pos(iterator.x.toReal(), y);
if (from >= 0 && length >= 0 &&
(from >= si.position + eng->length(&si) || from + length <= si.position))
continue;
QFont font = eng->font(si);
QTextItem::RenderFlags flags;
if (font.overline())
flags |= QTextItem::Overline;
if (font.underline())
flags |= QTextItem::Underline;
if (font.strikeOut())
flags |= QTextItem::StrikeOut;
if (si.analysis.bidiLevel % 2)
flags |= QTextItem::RightToLeft;
QGlyphLayout glyphLayout = eng->shapedGlyphs(&si).mid(iterator.glyphsStart,
iterator.glyphsEnd - iterator.glyphsStart);
if (glyphLayout.numGlyphs > 0) {
QFontEngine *mainFontEngine = font.d->engineForScript(si.analysis.script);
if (mainFontEngine->type() == QFontEngine::Multi) {
QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine);
int start = 0;
int end;
int which = glyphLayout.glyphs[0] >> 24;
for (end = 0; end < glyphLayout.numGlyphs; ++end) {
const int e = glyphLayout.glyphs[end] >> 24;
if (e == which)
continue;
QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
GlyphInfo(subLayout, pos, flags));
for (int i = 0; i < subLayout.numGlyphs; i++)
pos += QPointF(subLayout.advances_x[i].toReal(),
subLayout.advances_y[i].toReal());
start = end;
which = e;
}
QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
GlyphInfo(subLayout, pos, flags));
} else {
glyphLayoutHash.insertMulti(mainFontEngine,
GlyphInfo(glyphLayout, pos, flags));
}
}
}
QHash<QPair<QFontEngine *, int>, QGlyphRun> glyphsHash;
QList<QFontEngine *> keys = glyphLayoutHash.uniqueKeys();
for (int i=0; i<keys.size(); ++i) {
QFontEngine *fontEngine = keys.at(i);
// Make a font for this particular engine
QRawFont font;
QRawFontPrivate *fontD = QRawFontPrivate::get(font);
fontD->fontEngine = fontEngine;
fontD->fontEngine->ref.ref();
#if !defined(QT_NO_FREETYPE)
if (fontEngine->type() == QFontEngine::Freetype) {
QFontEngineFT *freeTypeEngine = static_cast<QFontEngineFT *>(fontEngine);
switch (freeTypeEngine->defaultHintStyle()) {
case QFontEngineFT::HintNone:
fontD->hintingPreference = QFont::PreferNoHinting;
break;
case QFontEngineFT::HintLight:
fontD->hintingPreference = QFont::PreferVerticalHinting;
break;
case QFontEngineFT::HintMedium:
case QFontEngineFT::HintFull:
fontD->hintingPreference = QFont::PreferFullHinting;
break;
};
}
#endif
QList<GlyphInfo> glyphLayouts = glyphLayoutHash.values(fontEngine);
for (int j=0; j<glyphLayouts.size(); ++j) {
const QPointF &pos = glyphLayouts.at(j).itemPosition;
const QGlyphLayout &glyphLayout = glyphLayouts.at(j).glyphLayout;
const QTextItem::RenderFlags &flags = glyphLayouts.at(j).flags;
QVarLengthArray<glyph_t> glyphsArray;
QVarLengthArray<QFixedPoint> positionsArray;
fontEngine->getGlyphPositions(glyphLayout, QTransform(), flags, glyphsArray,
positionsArray);
Q_ASSERT(glyphsArray.size() == positionsArray.size());
QVector<quint32> glyphs;
QVector<QPointF> positions;
for (int i=0; i<glyphsArray.size(); ++i) {
glyphs.append(glyphsArray.at(i) & 0xffffff);
positions.append(positionsArray.at(i).toPointF() + pos);
}
QGlyphRun glyphIndexes;
glyphIndexes.setGlyphIndexes(glyphs);
glyphIndexes.setPositions(positions);
glyphIndexes.setOverline(flags.testFlag(QTextItem::Overline));
glyphIndexes.setUnderline(flags.testFlag(QTextItem::Underline));
glyphIndexes.setStrikeOut(flags.testFlag(QTextItem::StrikeOut));
glyphIndexes.setRawFont(font);
QPair<QFontEngine *, int> key(fontEngine, int(flags));
if (!glyphsHash.contains(key)) {
glyphsHash.insert(key, glyphIndexes);
} else {
QGlyphRun &glyphRun = glyphsHash[key];
QVector<quint32> indexes = glyphRun.glyphIndexes();
QVector<QPointF> positions = glyphRun.positions();
indexes += glyphIndexes.glyphIndexes();
positions += glyphIndexes.positions();
glyphRun.setGlyphIndexes(indexes);
glyphRun.setPositions(positions);
}
}
}
return glyphsHash.values();
}
#endif // QT_NO_RAWFONT
/*!
\fn void QTextLine::draw(QPainter *painter, const QPointF &position, const QTextLayout::FormatRange *selection) const

View file

@ -43,7 +43,6 @@
#include <QtCore/qobject.h>
#include <QtGui/qevent.h>
#include <QtGui/qglyphrun.h>
#include <QtGui/qtextcursor.h>
QT_BEGIN_HEADER
@ -166,10 +165,6 @@ public:
qreal minimumWidth() const;
qreal maximumWidth() const;
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> glyphRuns() const;
#endif
QTextEngine *engine() const { return d; }
void setFlags(int flags);
private:
@ -241,10 +236,6 @@ private:
QTextLine(int line, QTextEngine *e) : i(line), eng(e) {}
void layout_helper(int numGlyphs);
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> glyphs(int from, int length) const;
#endif
friend class QTextLayout;
friend class QTextFragment;
int i;

View file

@ -1659,33 +1659,8 @@ QTextBlock::iterator &QTextBlock::iterator::operator--()
Returns the glyphs of this text fragment. The positions of the glyphs are
relative to the position of the QTextBlock's layout.
\sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun()
\sa QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun()
*/
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> QTextFragment::glyphRuns() const
{
if (!p || !n)
return QList<QGlyphRun>();
int pos = position();
int len = length();
if (len == 0)
return QList<QGlyphRun>();
int blockNode = p->blockMap().findNode(pos);
const QTextBlockData *blockData = p->blockMap().fragment(blockNode);
QTextLayout *layout = blockData->layout;
QList<QGlyphRun> ret;
for (int i=0; i<layout->lineCount(); ++i) {
QTextLine textLine = layout->lineAt(i);
ret += textLine.glyphs(pos, len);
}
return ret;
}
#endif // QT_NO_RAWFONT
/*!
Returns the position of this text fragment in the document.

View file

@ -44,7 +44,6 @@
#include <QtCore/qobject.h>
#include <QtGui/qtextformat.h>
#include <QtGui/qglyphrun.h>
QT_BEGIN_HEADER
@ -315,10 +314,6 @@ public:
int charFormatIndex() const;
QString text() const;
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> glyphRuns() const;
#endif
private:
const QTextDocumentPrivate *p;
int n;

View file

@ -39,10 +39,6 @@ set(GUI_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/text/qtextodfwriter_p.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qstatictext_p.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qstatictext.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qrawfont.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qrawfont_p.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qglyphrun.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qglyphrun_p.h
${CMAKE_CURRENT_SOURCE_DIR}/text/qharfbuzz_p.h
)
@ -76,8 +72,6 @@ set(GUI_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/text/qzip.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text/qtextodfwriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text/qstatictext.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text/qrawfont.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text/qglyphrun.cpp
)
if(WITH_FREETYPE AND FREETYPE_FOUND)
@ -96,7 +90,6 @@ if(WITH_FONTCONFIG AND FONTCONFIG_FOUND)
set(GUI_SOURCES
${GUI_SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/text/qfontengine_ft.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text/qrawfont_ft.cpp
)
set(EXTRA_GUI_LIBS

View file

@ -162,8 +162,6 @@ static const ClassInfoEntry qclass_lib_map[] = {
{ "QFontInfo", "QtGui/qfontinfo.h"},
{ "QFontMetrics", "QtGui/qfontmetrics.h"},
{ "QFontMetricsF", "QtGui/qfontmetrics.h"},
{ "QGlyphRun", "QtGui/qglyphrun.h"},
{ "QRawFont", "QtGui/qrawfont.h"},
{ "QStaticText", "QtGui/qstatictext.h"},
{ "QSyntaxHighlighter", "QtGui/qsyntaxhighlighter.h"},
{ "QTextCursor", "QtGui/qtextcursor.h"},
@ -702,6 +700,6 @@ static const ClassInfoEntry qclass_lib_map[] = {
{ "QFormBuilder", "QtUiTools/formbuilder.h"},
{ "QUiLoader", "QtUiTools/quiloader.h"},
};
static const int qclass_lib_count = 696;
static const int qclass_lib_count = 694;
#endif

View file

@ -73,63 +73,14 @@ while (<IN>) {
}
print out "#define make_tag( c1, c2, c3, c4 ) \\\n";
print out " ((((unsigned int)c1)<<24) | (((unsigned int)c2)<<16) | \\\n";
print out " (((unsigned int)c3)<<8) | ((unsigned int)c4))\n\n";
print out "struct XlfdEncoding {\n const char *name;\n int id;\n";
print out " int mib;\n unsigned int hash1;\n unsigned int hash2;\n};\n\n";
print out "struct XlfdEncoding {\n const char *name;\n int id;\n int mib;\n};\n\n";
print out "static const XlfdEncoding xlfd_encoding[] = {\n";
$i = 0;
while( $i < $num ) {
my $x = $xlfd[$i];
my $hash1 = "make_tag('".substr($x,0,1)."','".substr($x,1,1)."','".substr($x,2,1)."','".substr($x,3,1)."')";
if( index( $x, "*" ) > -1 && index( $x, "*" ) < 4 ) {
$hash1 = "0";
}
my $idx = length( $x ) - 4;
my $hash2 = "make_tag('".substr($x,$idx,1)."','".substr($x,$idx+1,1)."','".substr($x,$idx+2,1)."','".substr($x,$idx+3,1)."')";
if( index( $x, "*", $idx ) > -1 ) {
$hash2 = "0";
}
print out " { \"".$xlfd[$i]."\", ".$i.", ".$mib[$i].
", ".$hash1.", ".$hash2." },\n";
print out " { \"".$xlfd[$i]."\", ".$i.", ".$mib[$i]." },\n";
$i = $i + 1;
}
print out " { 0, 0, 0, 0, 0 }\n};\n\n";
print out "static const char writingSystems_for_xlfd_encoding[".$num."][".$writingSystemsCount.
"] = { \n";
$i = 0;
while( $i < $num ) {
my $j = 0;
my @s = split( /,/, $writingSystems[$i] );
print out " // ".$xlfd[$i]."\n";
print out " { ";
while( $j < $writingSystemsCount ) {
if( grep( /^$qwritingSystems[$j]$/, @s ) ) {
print out "1";
} else {
print out "0";
}
$j = $j + 1;
if ( $j < $writingSystemsCount ) {
print out ", ";
if ( !(($j) % 10) ) {
print out "\n ";
}
}
}
$i = $i + 1;
if ( $i < $num ) {
print out " },\n";
} else {
print out " }\n";
}
}
print out "\n};\n\n";
print out " { 0, 0, 0 }\n};\n\n";
close out;