summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-09-11 01:34:49 +1000
committerQt Continuous Integration System <qt-info@nokia.com>2011-09-11 01:34:49 +1000
commit704dd92581783d91ccd234d58896d7078eed14a5 (patch)
tree29d20b77fb3760cd47e980acc74432624e841be4 /src
parentc21ec3f5a4cce90218a70a1ef657cd38fb20027f (diff)
parentb318fc0800c3081af16a38614b95dd50a82b6bbb (diff)
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging: Disable autotest broken by the change to QCache in 7ab0bed Generate glyphs in un-transformed coordinate system. Use QT_MAX_CACHED_GLYPH_SIZE in QFontEngineFT Reset trailingSpaces in relayout Prevent QPixmapCache potentially growing indefinitely. Allocate 16-byte aligned memory independent of platform for raster pool. Fix trailing spaces problem by not adding it to QScriptLine.length Fix RTL layout for fonts when non-printable character has an advance Fix regression in tst_qrawfont Make it compile on mac Fixed compiling error in qvfb. micro optimizations fix "comparison between signed and unsigned" warnings on windows, don't resolve the gdi32's symbols for each QRawFont instance fix typo in the docs QRawFont: add missed operator != optimize QGlyphRun's operator == a bit QGlyphRun: make operator != inlined QGlyphRun: don't detach if the decoration wasn't actually changed QPA event loop: Set a timeout != 0 if there are no timers.
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qcache.h3
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa.cpp2
-rw-r--r--src/gui/painting/qpaintengine.cpp7
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp54
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qfontengine_ft.cpp8
-rw-r--r--src/gui/text/qglyphrun.cpp33
-rw-r--r--src/gui/text/qglyphrun.h4
-rw-r--r--src/gui/text/qrawfont.cpp136
-rw-r--r--src/gui/text/qrawfont.h6
-rw-r--r--src/gui/text/qrawfont_p.h25
-rw-r--r--src/gui/text/qrawfont_win.cpp82
-rw-r--r--src/gui/text/qtextengine.cpp6
-rw-r--r--src/gui/text/qtextengine_p.h3
-rw-r--r--src/gui/text/qtextlayout.cpp7
15 files changed, 158 insertions, 220 deletions
diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h
index 16861c9869..2408cd3abe 100644
--- a/src/corelib/tools/qcache.h
+++ b/src/corelib/tools/qcache.h
@@ -205,8 +205,7 @@ void QCache<Key,T>::trim(int m)
while (n && total > m) {
Node *u = n;
n = n->p;
- if (qIsDetached(*u->t))
- unlink(*u);
+ unlink(*u);
}
}
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp
index 200696d104..3f2e8b247a 100644
--- a/src/gui/kernel/qeventdispatcher_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_qpa.cpp
@@ -284,7 +284,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_
Q_D(QEventDispatcherQPA);
int retVal = 0;
if (d->hasIntegration()) {
- qint64 timeoutmsec = 0;
+ qint64 timeoutmsec = 1000; // wait a second if we don't have timers
if (timeout)
timeoutmsec = timeout->tv_sec * 1000 + (timeout->tv_usec/1000);
d->selectReturnMutex->lock();
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index c46513a07c..38ba6f9e6f 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -756,14 +756,15 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
path.setFillRule(Qt::WindingFill);
#endif
if (ti.glyphs.numGlyphs)
- ti.fontEngine->addOutlineToPath(p.x(), p.y(), ti.glyphs, &path, ti.flags);
+ ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags);
if (!path.isEmpty()) {
- bool oldAA = painter()->renderHints() & QPainter::Antialiasing;
+ painter()->save();
painter()->setRenderHint(QPainter::Antialiasing,
bool((painter()->renderHints() & QPainter::TextAntialiasing)
&& !(painter()->font().styleStrategy() & QFont::NoAntialias)));
+ painter()->translate(p.x(), p.y());
painter()->fillPath(path, state->pen().brush());
- painter()->setRenderHint(QPainter::Antialiasing, oldAA);
+ painter()->restore();
}
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 36786c4387..bcc5f9d9b7 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3764,6 +3764,11 @@ extern "C" {
int q_gray_rendered_spans(QT_FT_Raster raster);
}
+static inline uchar *alignAddress(uchar *address, quintptr alignmentMask)
+{
+ return (uchar *)(((quintptr)address + alignmentMask) & ~alignmentMask);
+}
+
void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
ProcessSpans callback,
void *userData, QRasterBuffer *)
@@ -3791,19 +3796,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
// minimize memory reallocations. However if initial size for
// raster pool is changed for lower value, reallocations will
// occur normally.
- const int rasterPoolInitialSize = MINIMUM_POOL_SIZE;
- int rasterPoolSize = rasterPoolInitialSize;
- unsigned char *rasterPoolBase;
-#if defined(Q_WS_WIN64)
- rasterPoolBase =
- // We make use of setjmp and longjmp in qgrayraster.c which requires
- // 16-byte alignment, hence we hardcode this requirement here..
- (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
-#else
- unsigned char rasterPoolOnStack[rasterPoolInitialSize];
- rasterPoolBase = rasterPoolOnStack;
-#endif
- Q_CHECK_PTR(rasterPoolBase);
+ int rasterPoolSize = MINIMUM_POOL_SIZE;
+ uchar rasterPoolOnStack[MINIMUM_POOL_SIZE + 0xf];
+ uchar *rasterPoolBase = alignAddress(rasterPoolOnStack, 0xf);
+ uchar *rasterPoolOnHeap = 0;
qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);
@@ -3839,31 +3835,20 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
// Out of memory, reallocate some more and try again...
if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c
- int new_size = rasterPoolSize * 2;
- if (new_size > 1024 * 1024) {
+ rasterPoolSize *= 2;
+ if (rasterPoolSize > 1024 * 1024) {
qWarning("QPainter: Rasterization of primitive failed");
break;
}
rendered_spans += q_gray_rendered_spans(*grayRaster.data());
-#if defined(Q_WS_WIN64)
- _aligned_free(rasterPoolBase);
-#else
- if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
- free(rasterPoolBase);
-#endif
+ free(rasterPoolOnHeap);
+ rasterPoolOnHeap = (uchar *)malloc(rasterPoolSize + 0xf);
- rasterPoolSize = new_size;
- rasterPoolBase =
-#if defined(Q_WS_WIN64)
- // We make use of setjmp and longjmp in qgrayraster.c which requires
- // 16-byte alignment, hence we hardcode this requirement here..
- (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
-#else
- (unsigned char *) malloc(rasterPoolSize);
-#endif
- Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
+ Q_CHECK_PTR(rasterPoolOnHeap); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
+
+ rasterPoolBase = alignAddress(rasterPoolOnHeap, 0xf);
qt_ft_grays_raster.raster_done(*grayRaster.data());
qt_ft_grays_raster.raster_new(grayRaster.data());
@@ -3873,12 +3858,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
}
}
-#if defined(Q_WS_WIN64)
- _aligned_free(rasterPoolBase);
-#else
- if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
- free(rasterPoolBase);
-#endif
+ free(rasterPoolOnHeap);
}
void QRasterPaintEnginePrivate::recalculateFastImages()
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index b4c58b53a4..c9b672bb89 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -280,6 +280,8 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
int i = glyphs.numGlyphs;
int totalKashidas = 0;
while(i--) {
+ if (glyphs.attributes[i].dontPrint)
+ continue;
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
ypos += glyphs.advances_y[i];
totalKashidas += glyphs.justifications[i].nKashidas;
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index b7d1e5d765..e20aa2556b 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -78,6 +78,10 @@
#include FT_ERRORS_H
#endif
+#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
+# define QT_MAX_CACHED_GLYPH_SIZE 64
+#endif
+
QT_BEGIN_NAMESPACE
/*
@@ -373,7 +377,7 @@ void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize,
*xsize = *ysize = 0;
}
} else {
- *outline_drawing = (*xsize > (64<<6) || *ysize > (64<<6));
+ *outline_drawing = (*xsize > (QT_MAX_CACHED_GLYPH_SIZE<<6) || *ysize > (QT_MAX_CACHED_GLYPH_SIZE<<6));
}
}
@@ -1317,7 +1321,7 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransfor
if (!gs) {
// don't try to load huge fonts
- bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= 64;
+ bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= QT_MAX_CACHED_GLYPH_SIZE;
if (draw_as_outline)
return 0;
diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp
index 442f7cc46b..7f43378250 100644
--- a/src/gui/text/qglyphrun.cpp
+++ b/src/gui/text/qglyphrun.cpp
@@ -140,14 +140,18 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const
return false;
}
- for (int i=0; i<qMax(d->glyphIndexDataSize, d->glyphPositionDataSize); ++i) {
- if (i < d->glyphIndexDataSize && d->glyphIndexData[i] != other.d->glyphIndexData[i])
- return false;
-
- if (i < d->glyphPositionDataSize && d->glyphPositionData[i] != other.d->glyphPositionData[i])
- 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
@@ -156,13 +160,11 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const
}
/*!
+ \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.
*/
-bool QGlyphRun::operator!=(const QGlyphRun &other) const
-{
- return !(*this == other);
-}
/*!
Returns the font selected for this QGlyphRun object.
@@ -294,6 +296,9 @@ bool QGlyphRun::overline() const
*/
void QGlyphRun::setOverline(bool overline)
{
+ if (d->overline == overline)
+ return;
+
detach();
d->overline = overline;
}
@@ -316,6 +321,9 @@ bool QGlyphRun::underline() const
*/
void QGlyphRun::setUnderline(bool underline)
{
+ if (d->underline == underline)
+ return;
+
detach();
d->underline = underline;
}
@@ -338,6 +346,9 @@ bool QGlyphRun::strikeOut() const
*/
void QGlyphRun::setStrikeOut(bool strikeOut)
{
+ if (d->strikeOut == strikeOut)
+ return;
+
detach();
d->strikeOut = strikeOut;
}
diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h
index cf407a82d3..bc7f4ff4a9 100644
--- a/src/gui/text/qglyphrun.h
+++ b/src/gui/text/qglyphrun.h
@@ -79,8 +79,10 @@ public:
void clear();
QGlyphRun &operator=(const QGlyphRun &other);
+
bool operator==(const QGlyphRun &other) const;
- bool operator!=(const QGlyphRun &other) const;
+ inline bool operator!=(const QGlyphRun &other) const
+ { return !operator==(other); }
void setOverline(bool overline);
bool overline() const;
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 60a6cb35ee..61bc63efee 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -46,7 +46,6 @@
#include "qrawfont.h"
#include "qrawfont_p.h"
-#include <QtCore/qthread.h>
#include <QtCore/qendian.h>
QT_BEGIN_NAMESPACE
@@ -77,7 +76,7 @@ QT_BEGIN_NAMESPACE
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. In can be used in
+ 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.
@@ -190,8 +189,7 @@ QRawFont &QRawFont::operator=(const QRawFont &other)
*/
bool QRawFont::isValid() const
{
- Q_ASSERT(d->thread == 0 || d->thread == QThread::currentThread());
- return d->fontEngine != 0;
+ return d->isValid();
}
/*!
@@ -225,7 +223,7 @@ void QRawFont::loadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
- detach();
+ d.detach();
d->cleanUp();
d->hintingPreference = hintingPreference;
d->thread = QThread::currentThread();
@@ -247,13 +245,13 @@ void QRawFont::loadFromData(const QByteArray &fontData,
QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
const QTransform &transform) const
{
- if (!isValid())
+ if (!d->isValid())
return QImage();
if (antialiasingType == SubPixelAntialiasing)
return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform);
- else
- return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
+
+ return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
}
/*!
@@ -266,7 +264,7 @@ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialias
*/
QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
{
- if (!isValid())
+ if (!d->isValid())
return QPainterPath();
QFixedPoint position;
@@ -284,16 +282,19 @@ bool QRawFont::operator==(const QRawFont &other) const
}
/*!
+ \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
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->ascent().toReal();
+ return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
}
/*!
@@ -303,10 +304,7 @@ qreal QRawFont::ascent() const
*/
qreal QRawFont::descent() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->descent().toReal();
+ return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
}
/*!
@@ -316,10 +314,7 @@ qreal QRawFont::descent() const
*/
qreal QRawFont::xHeight() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->xHeight().toReal();
+ return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
}
/*!
@@ -329,10 +324,7 @@ qreal QRawFont::xHeight() const
*/
qreal QRawFont::leading() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->leading().toReal();
+ return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
}
/*!
@@ -342,10 +334,7 @@ qreal QRawFont::leading() const
*/
qreal QRawFont::averageCharWidth() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->averageCharWidth().toReal();
+ return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
}
/*!
@@ -355,10 +344,7 @@ qreal QRawFont::averageCharWidth() const
*/
qreal QRawFont::maxCharWidth() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->maxCharWidth();
+ return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
}
/*!
@@ -370,10 +356,7 @@ qreal QRawFont::maxCharWidth() const
*/
qreal QRawFont::pixelSize() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->fontDef.pixelSize;
+ return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
}
/*!
@@ -386,10 +369,7 @@ qreal QRawFont::pixelSize() const
*/
qreal QRawFont::unitsPerEm() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->emSquareSize().toReal();
+ return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
}
/*!
@@ -397,10 +377,7 @@ qreal QRawFont::unitsPerEm() const
*/
QString QRawFont::familyName() const
{
- if (!isValid())
- return QString();
-
- return d->fontEngine->fontDef.family;
+ return d->isValid() ? d->fontEngine->fontDef.family : QString();
}
/*!
@@ -410,10 +387,7 @@ QString QRawFont::familyName() const
*/
QString QRawFont::styleName() const
{
- if (!isValid())
- return QString();
-
- return d->fontEngine->fontDef.styleName;
+ return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
}
/*!
@@ -423,10 +397,7 @@ QString QRawFont::styleName() const
*/
QFont::Style QRawFont::style() const
{
- if (!isValid())
- return QFont::StyleNormal;
-
- return QFont::Style(d->fontEngine->fontDef.style);
+ return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
}
/*!
@@ -436,10 +407,7 @@ QFont::Style QRawFont::style() const
*/
int QRawFont::weight() const
{
- if (!isValid())
- return -1;
-
- return int(d->fontEngine->fontDef.weight);
+ return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
}
/*!
@@ -457,7 +425,7 @@ int QRawFont::weight() const
*/
QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
{
- if (!isValid())
+ if (!d->isValid())
return QVector<quint32>();
int nglyphs = text.size();
@@ -490,7 +458,7 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
*/
bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QGlyphLayout glyphs;
@@ -507,7 +475,7 @@ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *g
*/
QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
{
- if (!isValid())
+ if (!d->isValid())
return QVector<QPointF>();
int numGlyphs = glyphIndexes.size();
@@ -534,7 +502,7 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph
*/
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QGlyphLayout glyphs;
@@ -560,10 +528,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
*/
QFont::HintingPreference QRawFont::hintingPreference() const
{
- if (!isValid())
- return QFont::PreferDefaultHinting;
-
- return d->hintingPreference;
+ return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
}
/*!
@@ -574,7 +539,7 @@ QFont::HintingPreference QRawFont::hintingPreference() const
*/
QByteArray QRawFont::fontTable(const char *tagName) const
{
- if (!isValid())
+ if (!d->isValid())
return QByteArray();
const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
@@ -597,9 +562,9 @@ extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_tru
*/
QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
{
- if (isValid()) {
+ if (d->isValid()) {
QByteArray os2Table = fontTable("OS/2");
- if (!os2Table.isEmpty() && os2Table.size() > 86) {
+ if (os2Table.size() > 86) {
char *data = os2Table.data();
quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
@@ -627,10 +592,7 @@ QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
*/
bool QRawFont::supportsCharacter(QChar character) const
{
- if (!isValid())
- return false;
-
- return d->fontEngine->canRender(&character, 1);
+ return d->isValid() && d->fontEngine->canRender(&character, 1);
}
/*!
@@ -641,9 +603,6 @@ bool QRawFont::supportsCharacter(QChar character) const
*/
bool QRawFont::supportsCharacter(quint32 ucs4) const
{
- if (!isValid())
- return false;
-
QChar str[2];
int len;
if (!QChar::requiresSurrogates(ucs4)) {
@@ -655,7 +614,7 @@ bool QRawFont::supportsCharacter(quint32 ucs4) const
len = 2;
}
- return d->fontEngine->canRender(str, len);
+ return d->isValid() && d->fontEngine->canRender(str, len);
}
// qfontdatabase.cpp
@@ -667,6 +626,7 @@ extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSyst
*/
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
{
+ QRawFont rawFont;
#if defined(Q_WS_MAC)
QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font);
layout.beginLayout();
@@ -677,14 +637,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
// Pick the one matches the family name we originally requested,
// if none of them match, just pick the first one
for (int i = 0; i < list.size(); i++) {
- QGlyphRun glyphs = list.at(i);
- QRawFont rawfont = glyphs.rawFont();
- if (rawfont.familyName() == font.family())
- return rawfont;
+ rawFont = list.at(i).rawFont();
+ if (rawFont.familyName() == font.family())
+ return rawFont;
}
return list.at(0).rawFont();
}
- return QRawFont();
#else
QFontPrivate *font_d = QFontPrivate::get(font);
int script = qt_script_for_writing_system(writingSystem);
@@ -700,15 +658,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
}
if (fe != 0) {
- QRawFont rawFont;
rawFont.d.data()->fontEngine = fe;
rawFont.d.data()->fontEngine->ref.ref();
rawFont.d.data()->hintingPreference = font.hintingPreference();
- return rawFont;
- } else {
- return QRawFont();
}
#endif
+ return rawFont;
}
/*!
@@ -719,7 +674,7 @@ void QRawFont::setPixelSize(qreal pixelSize)
if (d->fontEngine == 0)
return;
- detach();
+ d.detach();
QFontEngine *oldFontEngine = d->fontEngine;
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
@@ -734,15 +689,6 @@ void QRawFont::setPixelSize(qreal pixelSize)
/*!
\internal
*/
-void QRawFont::detach()
-{
- if (d->ref != 1)
- d.detach();
-}
-
-/*!
- \internal
-*/
void QRawFontPrivate::cleanUp()
{
platformCleanUp();
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index d5b5680521..cf7799661e 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -81,7 +81,10 @@ public:
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;
@@ -132,9 +135,6 @@ public:
private:
friend class QRawFontPrivate;
-
- void detach();
-
QExplicitlySharedDataPointer<QRawFontPrivate> d;
};
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
index fdf7cadbb4..3557751637 100644
--- a/src/gui/text/qrawfont_p.h
+++ b/src/gui/text/qrawfont_p.h
@@ -54,7 +54,9 @@
//
#include "qrawfont.h"
+
#include "qfontengine_p.h"
+#include <QtCore/qthread.h>
#include <QtCore/qthreadstorage.h>
#if !defined(QT_NO_RAWFONT)
@@ -71,21 +73,17 @@ public:
, thread(0)
#if defined(Q_WS_WIN)
, fontHandle(NULL)
- , ptrAddFontMemResourceEx(NULL)
- , ptrRemoveFontMemResourceEx(NULL)
#endif
{}
QRawFontPrivate(const QRawFontPrivate &other)
- : hintingPreference(other.hintingPreference)
+ : fontEngine(other.fontEngine)
+ , hintingPreference(other.hintingPreference)
, thread(other.thread)
#if defined(Q_WS_WIN)
, fontHandle(NULL)
- , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
- , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
#endif
{
- fontEngine = other.fontEngine;
if (fontEngine != 0)
fontEngine->ref.ref();
}
@@ -96,6 +94,12 @@ public:
cleanUp();
}
+ inline bool isValid() const
+ {
+ Q_ASSERT(thread == 0 || thread == QThread::currentThread());
+ return fontEngine != 0;
+ }
+
void cleanUp();
void platformCleanUp();
void platformLoadFromData(const QByteArray &fontData,
@@ -111,14 +115,7 @@ public:
#if defined(Q_WS_WIN)
HANDLE fontHandle;
-
- typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
- typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
-
- PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
- PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
-
-#endif // Q_WS_WIN
+#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp
index 779652f657..a729e310d5 100644
--- a/src/gui/text/qrawfont_win.cpp
+++ b/src/gui/text/qrawfont_win.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include "qrawfont_p.h"
+
+#if !defined(QT_NO_RAWFONT)
+
#include <private/qsystemlibrary_p.h>
#if !defined(QT_NO_DIRECTWRITE)
@@ -47,8 +50,6 @@
# include <dwrite.h>
#endif
-#if !defined(QT_NO_RAWFONT)
-
QT_BEGIN_NAMESPACE
namespace {
@@ -61,18 +62,16 @@ namespace {
operator T() const
{
T littleEndian = 0;
- for (int i=0; i<sizeof(T); ++i) {
+ for (int i = 0; i < int(sizeof(T)); ++i)
littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8);
- }
return littleEndian;
}
BigEndian<T> &operator=(const T &t)
{
- for (int i=0; i<sizeof(T); ++i) {
+ for (int i = 0; i < int(sizeof(T)); ++i)
data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff);
- }
return *this;
}
@@ -157,7 +156,7 @@ namespace {
class EmbeddedFont
{
public:
- EmbeddedFont(const QByteArray &fontData);
+ EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
QString changeFamilyName(const QString &newFamilyName);
QByteArray data() const { return m_fontData; }
@@ -168,10 +167,6 @@ namespace {
QByteArray m_fontData;
};
- EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData)
- {
- }
-
TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
{
Q_ASSERT(tagName.size() == 4);
@@ -214,9 +209,9 @@ namespace {
+ nameRecord->offset;
const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr);
- for (int j=0; j<nameRecord->length / sizeof(quint16); ++j)
- name += QChar(s[j]);
-
+ const BigEndian<quint16> *e = s + nameRecord->length / sizeof(quint16);
+ while (s != e)
+ name += QChar(*s++);
break;
}
}
@@ -525,41 +520,49 @@ extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
// From qfontdatabase.cpp
extern QFont::Weight weightFromInteger(int weight);
-void QRawFontPrivate::platformCleanUp()
+typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
+static PtrAddFontMemResourceEx ptrAddFontMemResourceEx = 0;
+typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
+static PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = 0;
+
+static void resolveGdi32()
{
- if (fontHandle != NULL) {
- if (ptrRemoveFontMemResourceEx == NULL) {
- void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
- ptrRemoveFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
+ static bool triedResolve = false;
+ if (!triedResolve) {
+ QSystemLibrary gdi32(QLatin1String("gdi32"));
+ if (gdi32.load()) {
+ ptrAddFontMemResourceEx = (PtrAddFontMemResourceEx)gdi32.resolve("AddFontMemResourceEx");
+ ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)gdi32.resolve("RemoveFontMemResourceEx");
}
- if (ptrRemoveFontMemResourceEx == NULL) {
- qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32");
- fontHandle = NULL;
- } else {
+ triedResolve = true;
+ }
+}
+
+void QRawFontPrivate::platformCleanUp()
+{
+ if (fontHandle != NULL) {
+ if (ptrRemoveFontMemResourceEx)
ptrRemoveFontMemResourceEx(fontHandle);
- fontHandle = NULL;
- }
+ fontHandle = NULL;
}
}
-void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
- QByteArray fontData(_fontData);
EmbeddedFont font(fontData);
#if !defined(QT_NO_DIRECTWRITE)
if (hintingPreference == QFont::PreferDefaultHinting
- || hintingPreference == QFont::PreferFullHinting)
+ || hintingPreference == QFont::PreferFullHinting)
#endif
{
GUID guid;
CoCreateGuid(&guid);
- QString uniqueFamilyName = QString::fromLatin1("f")
+ QString uniqueFamilyName = QLatin1Char('f')
+ QString::number(guid.Data1, 36) + QLatin1Char('-')
+ QString::number(guid.Data2, 36) + QLatin1Char('-')
+ QString::number(guid.Data3, 36) + QLatin1Char('-')
@@ -571,22 +574,13 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
return;
}
- if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) {
- void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
- ptrRemoveFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
-
- func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx");
- ptrAddFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func);
- }
-
Q_ASSERT(fontHandle == NULL);
- if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) {
+ resolveGdi32();
+ if (ptrAddFontMemResourceEx && ptrRemoveFontMemResourceEx) {
DWORD count = 0;
- fontData = font.data();
- fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count);
-
+ QByteArray newFontData = font.data();
+ fontHandle = ptrAddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(),
+ 0, &count);
if (count == 0 && fontHandle != NULL) {
ptrRemoveFontMemResourceEx(fontHandle);
fontHandle = NULL;
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 732b82127d..48860067be 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -968,7 +968,7 @@ void QTextEngine::shapeText(int item) const
}
for (int i = 0; i < si.num_glyphs; ++i)
- si.width += glyphs.advances_x[i];
+ si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
}
static inline bool hasCaseChange(const QScriptItem &si)
@@ -2657,7 +2657,7 @@ void QTextEngine::splitItem(int item, int pos) const
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
- w += g.advances_x[j];
+ w += g.advances_x[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
@@ -2950,7 +2950,7 @@ int QTextEngine::lineNumberForTextPosition(int pos)
return lines.size() - 1;
for (int i = 0; i < lines.size(); ++i) {
const QScriptLine& line = lines[i];
- if (line.from + line.length > pos)
+ if (line.from + line.length + line.trailingSpaces > pos)
return i;
}
return -1;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index b1bd0c3359..0a86886ecf 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -376,7 +376,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
{
// created and filled in QTextLine::layout_helper
QScriptLine()
- : from(0), length(0),
+ : from(0), trailingSpaces(0), length(0),
justified(0), gridfitted(0),
hasTrailingSpaces(0), leadingIncluded(0) {}
QFixed descent;
@@ -388,6 +388,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
QFixed textWidth;
QFixed textAdvance;
int from;
+ unsigned short trailingSpaces;
signed int length : 28;
mutable uint justified : 1;
mutable uint gridfitted : 1;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 4fd6ddf0c1..4595ef54a2 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -814,7 +814,7 @@ QTextLine QTextLayout::createLine()
if (l && d->lines.at(l-1).length < 0) {
QTextLine(l-1, d).setNumColumns(INT_MAX);
}
- int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length : 0;
+ int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length + d->lines.at(l-1).trailingSpaces : 0;
int strlen = d->layoutData->string.length();
if (l && from >= strlen) {
if (!d->lines.at(l-1).length || d->layoutData->string.at(strlen - 1) != QChar::LineSeparator)
@@ -1708,6 +1708,7 @@ void QTextLine::layout_helper(int maxGlyphs)
{
QScriptLine &line = eng->lines[i];
line.length = 0;
+ line.trailingSpaces = 0;
line.textWidth = 0;
line.hasTrailingSpaces = false;
@@ -1931,7 +1932,7 @@ found:
if (eng->option.flags() & QTextOption::IncludeTrailingSpaces)
line.textWidth += lbh.spaceData.textWidth;
if (lbh.spaceData.length) {
- line.length += lbh.spaceData.length;
+ line.trailingSpaces = lbh.spaceData.length;
line.hasTrailingSpaces = true;
}
@@ -1995,7 +1996,7 @@ int QTextLine::textLength() const
&& eng->block.isValid() && i == eng->lines.count()-1) {
return eng->lines[i].length - 1;
}
- return eng->lines[i].length;
+ return eng->lines[i].length + eng->lines[i].trailingSpaces;
}
static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng,