summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-09-10 23:02:48 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-09-10 23:02:48 (GMT)
commit2e5a459cc5e3a302274db69172603ed8fb346420 (patch)
treea5bf635c50b3d14f8ed29fc1f71013e0e307f658
parent31cc0b1820c0c8fdfdbc3d5b804f2dba2051c96f (diff)
parent408ff8b676e22a33c962077467d1f48b58286d43 (diff)
downloadQt-2e5a459cc5e3a302274db69172603ed8fb346420.zip
Qt-2e5a459cc5e3a302274db69172603ed8fb346420.tar.gz
Qt-2e5a459cc5e3a302274db69172603ed8fb346420.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2: Fix typos. Fix typo in declative example. test for gdb version before runnning dwarf indexing Fix Core Text font loading for certain Mac Fonts Support sub pixel positioning of glyphs in raster engine Added basic tests for threaded QPainter drawing onto FBOs and PBOs.
-rw-r--r--doc/src/declarative/advtutorial.qdoc2
-rw-r--r--doc/src/declarative/example-slideswitch.qdoc2
-rw-r--r--doc/src/declarative/extending.qdoc2
-rw-r--r--mkspecs/features/unix/gdb_dwarf_index.prf1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp10
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp97
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h36
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp45
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qfontengine_ft.cpp6
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
-rw-r--r--src/gui/text/qfontengine_mac.mm20
-rw-r--r--src/gui/text/qfontengine_p.h13
-rw-r--r--src/gui/text/qfontengine_win.cpp2
-rw-r--r--src/gui/text/qfontengine_win_p.h2
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp9
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp6
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h2
-rw-r--r--tests/auto/qfontdatabase/tst_qfontdatabase.cpp35
-rw-r--r--tests/auto/qglthreads/tst_qglthreads.cpp160
-rw-r--r--tests/auto/qglthreads/tst_qglthreads.h2
-rw-r--r--tests/auto/qglyphs/tst_qglyphs.cpp8
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp36
23 files changed, 394 insertions, 106 deletions
diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc
index 1341bbb..4c97e1a 100644
--- a/doc/src/declarative/advtutorial.qdoc
+++ b/doc/src/declarative/advtutorial.qdoc
@@ -425,7 +425,7 @@ First we call \c sendHighScore() (explained in the section below) if it is possi
Then, we use the \l{Offline Storage API} to maintain a persistant SQL database unique to this application. We create an offline storage database for the high scores using \c openDatabase() and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrival, and in the \c db.transaction() call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string.
-This is one way of storing and displaying high scores locally, but certainly not the only way. A more complex alternative would be to create a high score dialog component, and pass it the results for processing and display (instead of reusing the \c Dialog). This would allow a more themeable dialog that could beter present the high scores. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database.
+This is one way of storing and displaying high scores locally, but certainly not the only way. A more complex alternative would be to create a high score dialog component, and pass it the results for processing and display (instead of reusing the \c Dialog). This would allow a more themeable dialog that could better present the high scores. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database.
\section3 Storing high scores online
diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc
index 1a40f14..09b6006 100644
--- a/doc/src/declarative/example-slideswitch.qdoc
+++ b/doc/src/declarative/example-slideswitch.qdoc
@@ -35,7 +35,7 @@ The code for this example can be found in the \c $QTDIR/examples/declarative/ui-
\section1 Overview
-The elements that composed the switch are:
+The elements that compose the switch are:
\list
\o a \c on property (the interface to interact with the switch),
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index 0cc989d..a1ffde0 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -124,7 +124,7 @@ The QML snippet shown above assigns a \c Person object to the \c BirthdayParty's
QML can set properties of types that are more complex than basic intrinsics like
integers and strings. Properties can also be object pointers, Qt interface
-pointers, lists of object points, and lists of Qt interface pointers. As QML
+pointers, lists of object pointers, and lists of Qt interface pointers. As QML
is typesafe it ensures that only valid types are assigned to these properties,
just like it does for primitive types.
diff --git a/mkspecs/features/unix/gdb_dwarf_index.prf b/mkspecs/features/unix/gdb_dwarf_index.prf
index 264edc2..e2167a6 100644
--- a/mkspecs/features/unix/gdb_dwarf_index.prf
+++ b/mkspecs/features/unix/gdb_dwarf_index.prf
@@ -1,6 +1,7 @@
!CONFIG(separate_debug_info):CONFIG(debug, debug|release):!staticlib:!static:!contains(TEMPLATE, subdirs):!isEmpty(QMAKE_OBJCOPY) {
QMAKE_GDB_INDEX = { test -z \"$(DESTDIR)\" || cd \"$(DESTDIR)\"; } && \
+ test \$\$(gdb --version | sed -e \'s,[^(]*(GDB).\\([0-9]\\)\\.\\([0-9]\\).*,\\1\\2,;q\') -gt 71 && \
gdb --nx --batch --quiet -ex \'set confirm off\' -ex \'save gdb-index .\' -ex quit \'$(TARGET)\' && \
test -f $(TARGET).gdb-index && \
$$QMAKE_OBJCOPY --add-section \'.gdb_index=$(TARGET).gdb-index\' --set-section-flags \'.gdb_index=readonly\' \'$(TARGET)\' \'$(TARGET)\' && \
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 0b76898..94d7578 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3098,9 +3098,17 @@ void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
int margin = cache->glyphMargin();
+ bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
+
const uchar *bits = image.bits();
for (int i=0; i<numGlyphs; ++i) {
- const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]);
+
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(positions[i].x);
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
+ const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
+
int x = qFloor(positions[i].x) + c.baseLineX - margin;
int y = qFloor(positions[i].y) - c.baseLineY - margin;
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 376219b..e992bb2 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -69,8 +69,60 @@ static inline int qt_next_power_of_two(int v)
return v;
}
+int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
+{
+ // Test 12 different subpixel positions since it factors into 3*4 so it gives
+ // the coverage we need.
+
+ QList<QImage> images;
+ for (int i=0; i<12; ++i) {
+ QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0));
+
+ if (images.isEmpty()) {
+ QPainterPath path;
+ QFixedPoint point;
+ m_current_fontengine->addGlyphsToPath(&glyph, &point, 1, &path, QTextItem::RenderFlags());
+
+ // Glyph is space, return 0 to indicate that we need to keep trying
+ if (path.isEmpty())
+ break;
+
+ images.append(img);
+ } else {
+ bool found = false;
+ for (int j=0; j<images.size(); ++j) {
+ if (images.at(j) == img) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ images.append(img);
+ }
+ }
+
+ return images.size();
+}
+
+QFixed QTextureGlyphCache::subPixelPositionForX(QFixed x) const
+{
+ if (m_subPixelPositionCount == 0)
+ return QFixed();
+
+ QFixed subPixelPosition;
+ if (x != 0) {
+ subPixelPosition = x - x.floor();
+ QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
+
+ // Compensate for precision loss in fixed point to make sure we are always drawing at a subpixel position over
+ // the lower boundary for the selected rasterization by adding 1/64.
+ subPixelPosition = fraction / QFixed(m_subPixelPositionCount) + QFixed::fromReal(0.015625);
+ }
+ return subPixelPosition;
+}
+
void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
- const QFixedPoint *)
+ const QFixedPoint *positions)
{
#ifdef CACHE_DEBUG
printf("Populating with %d glyphs\n", numGlyphs);
@@ -81,15 +133,33 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
const int margin = glyphMargin();
const int paddingDoubled = glyphPadding() * 2;
- QHash<glyph_t, Coord> listItemCoordinates;
+ bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
+ if (m_subPixelPositionCount == 0) {
+ if (!supportsSubPixelPositions) {
+ m_subPixelPositionCount = 1;
+ } else {
+ int i = 0;
+ while (m_subPixelPositionCount == 0 && i < numGlyphs)
+ m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]);
+ }
+ }
+
+ QHash<GlyphAndSubPixelPosition, Coord> listItemCoordinates;
int rowHeight = 0;
// check each glyph for its metrics and get the required rowHeight.
for (int i=0; i < numGlyphs; ++i) {
const glyph_t glyph = glyphs[i];
- if (coords.contains(glyph))
+
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions) {
+ QFixed x = positions != 0 ? positions[i].x : QFixed();
+ subPixelPosition = subPixelPositionForX(x);
+ }
+
+ if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
continue;
- if (listItemCoordinates.contains(glyph))
+ if (listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
continue;
glyph_metrics_t metrics = fontEngine->boundingBox(glyph, m_transform);
@@ -119,7 +189,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
metrics.x.round().truncate(),
-metrics.y.truncate() }; // baseline for horizontal scripts
- listItemCoordinates.insert(glyph, c);
+ listItemCoordinates.insert(GlyphAndSubPixelPosition(glyph, subPixelPosition), c);
rowHeight = qMax(rowHeight, glyph_height);
}
if (listItemCoordinates.isEmpty())
@@ -135,7 +205,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
}
// now actually use the coords and paint the wanted glyps into cache.
- QHash<glyph_t, Coord>::iterator iter = listItemCoordinates.begin();
+ QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = listItemCoordinates.begin();
while (iter != listItemCoordinates.end()) {
Coord c = iter.value();
@@ -166,7 +236,7 @@ void QTextureGlyphCache::fillInPendingGlyphs()
int requiredHeight = 0;
{
- QHash<glyph_t, Coord>::iterator iter = m_pendingGlyphs.begin();
+ QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = m_pendingGlyphs.begin();
while (iter != m_pendingGlyphs.end()) {
Coord c = iter.value();
requiredHeight = qMax(requiredHeight, c.y + c.h);
@@ -182,9 +252,10 @@ void QTextureGlyphCache::fillInPendingGlyphs()
}
{
- QHash<glyph_t, Coord>::iterator iter = m_pendingGlyphs.begin();
+ QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = m_pendingGlyphs.begin();
while (iter != m_pendingGlyphs.end()) {
- fillTexture(iter.value(), iter.key());
+ GlyphAndSubPixelPosition key = iter.key();
+ fillTexture(iter.value(), key.glyph, key.subPixelPosition);
++iter;
}
@@ -193,7 +264,7 @@ void QTextureGlyphCache::fillInPendingGlyphs()
m_pendingGlyphs.clear();
}
-QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const
+QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
{
#if defined(Q_WS_X11)
if (m_transform.type() > QTransform::TxTranslate) {
@@ -226,7 +297,7 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const
} else
#endif
if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
- return m_current_fontengine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);
+ return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, glyphMargin(), m_transform);
else
return m_current_fontengine->alphaMapForGlyph(g, m_transform);
@@ -272,9 +343,9 @@ int QImageTextureGlyphCache::glyphMargin() const
#endif
}
-void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g)
+void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subPixelPosition)
{
- QImage mask = textureMapForGlyph(g);
+ QImage mask = textureMapForGlyph(g, subPixelPosition);
#ifdef CACHE_DEBUG
printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index 0770ed4..4131003 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -77,11 +77,24 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache
public:
QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
: QFontEngineGlyphCache(matrix, type), m_current_fontengine(0),
- m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0)
+ m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0), m_subPixelPositionCount(0)
{ }
virtual ~QTextureGlyphCache() { }
+ struct GlyphAndSubPixelPosition
+ {
+ GlyphAndSubPixelPosition(glyph_t g, QFixed spp) : glyph(g), subPixelPosition(spp) {}
+
+ bool operator==(const GlyphAndSubPixelPosition &other) const
+ {
+ return glyph == other.glyph && subPixelPosition == other.subPixelPosition;
+ }
+
+ glyph_t glyph;
+ QFixed subPixelPosition;
+ };
+
struct Coord {
int x;
int y;
@@ -101,7 +114,7 @@ public:
virtual int glyphMargin() const { return 0; }
virtual int glyphPadding() const { return 0; }
- virtual void fillTexture(const Coord &coord, glyph_t glyph) = 0;
+ virtual void fillTexture(const Coord &coord, glyph_t glyph, QFixed subPixelPosition) = 0;
inline void createCache(int width, int height) {
m_w = width;
@@ -118,22 +131,31 @@ public:
inline bool isNull() const { return m_h == 0; }
- QHash<glyph_t, Coord> coords;
+ QHash<GlyphAndSubPixelPosition, Coord> coords;
- QImage textureMapForGlyph(glyph_t g) const;
+ QImage textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const;
+
+ QFixed subPixelPositionForX(QFixed x) const;
protected:
- QFontEngine *m_current_fontengine;
+ int calculateSubPixelPositionCount(glyph_t) const;
- QHash<glyph_t, Coord> m_pendingGlyphs;
+ QFontEngine *m_current_fontengine;
+ QHash<GlyphAndSubPixelPosition, Coord> m_pendingGlyphs;
int m_w; // image width
int m_h; // image height
int m_cx; // current x
int m_cy; // current y
int m_currentRowHeight; // Height of last row
+ int m_subPixelPositionCount; // Number of positions within a single pixel for this cache
};
+inline uint qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g)
+{
+ return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
+}
+
class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache
{
@@ -143,7 +165,7 @@ public:
virtual int glyphMargin() const;
virtual void createTextureData(int width, int height);
virtual void resizeTextureData(int width, int height);
- virtual void fillTexture(const Coord &c, glyph_t glyph);
+ virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition);
inline const QImage &image() const { return m_image; }
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index 4648304..5c41e0a 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -293,8 +293,12 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// previous versions
family_list << QApplication::font().defaultFamily();
+#if defined(QT_MAC_USE_COCOA)
+ QCFString fontName = NULL, familyName = NULL;
+#else
ATSFontFamilyRef familyRef = 0;
ATSFontRef fontRef = 0;
+#endif
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
@@ -304,26 +308,21 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
for (int k = 0; k < db->count; ++k) {
if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
QByteArray family_name = db->families[k]->name.toUtf8();
+#if defined(QT_MAC_USE_COCOA)
+ CTFontRef ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
+ if (ctFont) {
+ fontName = CTFontCopyFullName(ctFont);
+ familyName = CTFontCopyFamilyName(ctFont);
+ CFRelease(ctFont);
+ goto FamilyFound;
+ }
+#else
familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
if (familyRef) {
fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
goto FamilyFound;
- } else {
-#if defined(QT_MAC_USE_COCOA)
- // ATS and CT disagrees on what the family name should be,
- // use CT to look up the font if ATS fails.
- QCFString familyName = QString::fromAscii(family_name);
- QCFType<CTFontRef> CTfontRef = CTFontCreateWithName(familyName, 12, NULL);
- QCFType<CTFontDescriptorRef> fontDescriptor = CTFontCopyFontDescriptor(CTfontRef);
- QCFString displayName = (CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontDisplayNameAttribute);
-
- familyRef = ATSFontFamilyFindFromName(displayName, kATSOptionFlagsDefault);
- if (familyRef) {
- fontRef = ATSFontFindFromName(displayName, kATSOptionFlagsDefault);
- goto FamilyFound;
- }
-#endif
}
+#endif
}
}
}
@@ -331,18 +330,18 @@ FamilyFound:
//fill in the engine's font definition
QFontDef fontDef = d->request; //copy..
if(fontDef.pointSize < 0)
- fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
+ fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
else
- fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
- {
- QCFString actualName;
- if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
- fontDef.family = actualName;
- }
+ fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
#ifdef QT_MAC_USE_COCOA
- QFontEngine *engine = new QCoreTextFontEngineMulti(familyRef, fontRef, fontDef, d->kerning);
+ fontDef.family = familyName;
+ QFontEngine *engine = new QCoreTextFontEngineMulti(fontName, fontDef, d->kerning);
+ CFRelease(fontName);
#else
+ QCFString actualName;
+ if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
+ fontDef.family = actualName;
QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
#endif
d->engineData->engine = engine;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 4348589..6487e29 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -616,7 +616,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &t)
return i;
}
-QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int /* margin */, const QTransform &t)
+QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, int /* margin */, const QTransform &t)
{
QImage alphaMask = alphaMapForGlyph(glyph, t);
QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32);
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 4bbb977..5e86b37 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -1878,10 +1878,10 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g)
return img;
}
-QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransform &t)
+QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, int margin, const QTransform &t)
{
if (t.type() > QTransform::TxTranslate)
- return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
+ return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, margin, t);
lockFace();
@@ -1890,7 +1890,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransfor
Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
if (!glyph) {
unlockFace();
- return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
+ return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, margin, t);
}
QImage img(glyph->width, glyph->height, QImage::Format_RGB32);
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 2f05a8b..72f7d9f 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -241,7 +241,7 @@ private:
virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const;
virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual void removeGlyphFromCache(glyph_t glyph);
virtual int glyphCount() const;
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 2bbf9f2..894de44 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -143,7 +143,7 @@ void qmacfontengine_gamma_correct(QImage *image)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
@@ -159,9 +159,6 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con
break;
}
- QCFString name;
- ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
-
transform = CGAffineTransformIdentity;
if (fontDef.stretch != 100) {
transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
@@ -663,7 +660,7 @@ QFont QCoreTextFontEngine::createExplicitFont() const
return createExplicitFontWithName(familyName);
}
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
+QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa)
{
const glyph_metrics_t br = boundingBox(glyph);
QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
@@ -700,7 +697,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
QCFType<CGFontRef> cgFont = CGFontCreateWithPlatformFont(&atsfont);
CGContextSetFont(ctx, cgFont);
- qreal pos_x = -br.x.toReal()+1, pos_y = im.height()+br.y.toReal();
+ qreal pos_x = -br.x.toReal() + subPixelPosition.toReal();
+ qreal pos_y = im.height()+br.y.toReal();
CGContextSetTextPosition(ctx, pos_x, pos_y);
CGSize advance;
@@ -721,7 +719,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
{
- QImage im = imageForGlyph(glyph, 0, false);
+ QImage im = imageForGlyph(glyph, QFixed(), 0, false);
QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
QVector<QRgb> colors(256);
@@ -742,12 +740,12 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
return indexed;
}
-QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x)
+QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, const QTransform &x)
{
if (x.type() >= QTransform::TxScale)
- return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x);
+ return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x);
- QImage im = imageForGlyph(glyph, margin, true);
+ QImage im = imageForGlyph(glyph, subPixelPosition, margin, true);
qmacfontengine_gamma_correct(&im);
return im;
}
@@ -1706,7 +1704,7 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
return indexed;
}
-QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t)
+QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
{
QImage im = imageForGlyph(glyph, margin, true);
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 6e9bd0bc..b3a6c59 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -155,6 +155,7 @@ public:
SynthesizedStretch = 0x4
};
virtual int synthesized() const { return 0; }
+ virtual bool supportsSubPixelPositions() const { return false; }
virtual QFixed emSquareSize() const { return ascent(); }
@@ -188,7 +189,7 @@ public:
*/
virtual QImage alphaMapForGlyph(glyph_t);
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual void removeGlyphFromCache(glyph_t);
@@ -448,6 +449,7 @@ public:
virtual bool canRender(const QChar *string, int len);
virtual int synthesized() const { return synthesisFlags; }
+ virtual bool supportsSubPixelPositions() const { return true; }
virtual Type type() const { return QFontEngine::Mac; }
@@ -457,13 +459,13 @@ public:
virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;
virtual QFont createExplicitFont() const;
private:
- QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
+ QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful);
CTFontRef ctfont;
CGFontRef cgFont;
QCoreTextFontEngineMulti *parentEngine;
@@ -475,8 +477,7 @@ private:
class QCoreTextFontEngineMulti : public QFontEngineMulti
{
public:
- QCoreTextFontEngineMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef,
- const QFontDef &fontDef, bool kerning);
+ QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
~QCoreTextFontEngineMulti();
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
@@ -546,7 +547,7 @@ public:
virtual Properties properties() const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
private:
QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index 82de0d5..ac13b59 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -1254,7 +1254,7 @@ QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
-QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t)
+QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
{
HFONT font = hfont;
diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
index 68b53b5..d86f42e 100644
--- a/src/gui/text/qfontengine_win_p.h
+++ b/src/gui/text/qfontengine_win_p.h
@@ -104,7 +104,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
- virtual QImage alphaRGBMapForGlyph(glyph_t t, int margin, const QTransform &xform);
+ virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
#ifndef Q_CC_MINGW
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index b762bcc..8e31e76 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1525,8 +1525,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
vertexCoordinates->clear();
textureCoordinates->clear();
+ bool supportsSubPixelPositions = staticTextItem->fontEngine->supportsSubPixelPositions();
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
- const QTextureGlyphCache::Coord &c = cache->coords.value(staticTextItem->glyphs[i]);
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
+
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
+
+ const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
int x = staticTextItem->glyphPositions[i].x.toInt() + c.baseLineX - margin;
int y = staticTextItem->glyphPositions[i].y.toInt() - c.baseLineY - margin;
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 53a2f3a..3dc7789 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -216,7 +216,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
pex->updateClipScissorTest();
}
-void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
+void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
{
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::fillTexture: Called with no context");
@@ -225,7 +225,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) {
- QImageTextureGlyphCache::fillTexture(c, glyph);
+ QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
const QImage &texture = image();
@@ -238,7 +238,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
return;
}
- QImage mask = textureMapForGlyph(glyph);
+ QImage mask = textureMapForGlyph(glyph, subPixelPosition);
const int maskWidth = mask.width();
const int maskHeight = mask.height();
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 2ae3a64..345684d 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -106,7 +106,7 @@ public:
virtual void createTextureData(int width, int height);
virtual void resizeTextureData(int width, int height);
- virtual void fillTexture(const Coord &c, glyph_t glyph);
+ virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition);
virtual int glyphPadding() const;
inline GLuint texture() const {
diff --git a/tests/auto/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/qfontdatabase/tst_qfontdatabase.cpp
index 357b82e..bddd92a 100644
--- a/tests/auto/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/qfontdatabase/tst_qfontdatabase.cpp
@@ -70,6 +70,11 @@ private slots:
void fixedPitch_data();
void fixedPitch();
+#ifdef Q_WS_MAC
+ void trickyFonts_data();
+ void trickyFonts();
+#endif
+
void widthTwoTimes_data();
void widthTwoTimes();
@@ -131,10 +136,16 @@ void tst_QFontDatabase::fixedPitch_data()
QTest::newRow( "Times New Roman" ) << QString( "Times New Roman" ) << false;
QTest::newRow( "Arial" ) << QString( "Arial" ) << false;
- QTest::newRow( "Script" ) << QString( "Script" ) << false;
+ QTest::newRow( "Andale Mono" ) << QString( "Andale Mono" ) << true;
QTest::newRow( "Courier" ) << QString( "Courier" ) << true;
QTest::newRow( "Courier New" ) << QString( "Courier New" ) << true;
+#ifndef Q_WS_MAC
+ QTest::newRow( "Script" ) << QString( "Script" ) << false;
QTest::newRow( "Lucida Console" ) << QString( "Lucida Console" ) << true;
+#else
+ QTest::newRow( "Menlo" ) << QString( "Menlo" ) << true;
+ QTest::newRow( "Monaco" ) << QString( "Monaco" ) << true;
+#endif
}
void tst_QFontDatabase::fixedPitch()
@@ -156,6 +167,28 @@ void tst_QFontDatabase::fixedPitch()
QCOMPARE(fi.fixedPitch(), fixedPitch);
}
+#ifdef Q_WS_MAC
+void tst_QFontDatabase::trickyFonts_data()
+{
+ QTest::addColumn<QString>("font");
+
+ QTest::newRow( "Geeza Pro" ) << QString( "Geeza Pro" );
+}
+
+void tst_QFontDatabase::trickyFonts()
+{
+ QFETCH(QString, font);
+
+ QFontDatabase fdb;
+ if (!fdb.families().contains(font))
+ QSKIP( "Font not installed", SkipSingle);
+
+ QFont qfont(font);
+ QFontInfo fi(qfont);
+ QCOMPARE(fi.family(), font);
+}
+#endif
+
void tst_QFontDatabase::widthTwoTimes_data()
{
QTest::addColumn<QString>("font");
diff --git a/tests/auto/qglthreads/tst_qglthreads.cpp b/tests/auto/qglthreads/tst_qglthreads.cpp
index 4777fb1..38b0dab 100644
--- a/tests/auto/qglthreads/tst_qglthreads.cpp
+++ b/tests/auto/qglthreads/tst_qglthreads.cpp
@@ -456,11 +456,71 @@ void tst_QGLThreads::renderInThread()
QVERIFY(!thread.failure);
}
+class Device
+{
+public:
+ virtual ~Device() {}
+ virtual QPaintDevice *realPaintDevice() = 0;
+ virtual void prepareDevice() {}
+};
+
+class GLWidgetWrapper : public Device
+{
+public:
+ GLWidgetWrapper() {
+ widget.resize(150, 150);
+ widget.show();
+ QTest::qWaitForWindowShown(&widget);
+ widget.doneCurrent();
+ }
+ QPaintDevice *realPaintDevice() { return &widget; }
+
+ ThreadSafeGLWidget widget;
+};
+
+class PixmapWrapper : public Device
+{
+public:
+ PixmapWrapper() { pixmap = new QPixmap(512, 512); }
+ ~PixmapWrapper() { delete pixmap; }
+ QPaintDevice *realPaintDevice() { return pixmap; }
+
+ QPixmap *pixmap;
+};
+
+class PixelBufferWrapper : public Device
+{
+public:
+ PixelBufferWrapper() { pbuffer = new QGLPixelBuffer(512, 512); }
+ ~PixelBufferWrapper() { delete pbuffer; }
+ QPaintDevice *realPaintDevice() { return pbuffer; }
+
+ QGLPixelBuffer *pbuffer;
+};
+
+
+class FrameBufferObjectWrapper : public Device
+{
+public:
+ FrameBufferObjectWrapper() {
+ widget.makeCurrent();
+ fbo = new QGLFramebufferObject(512, 512);
+ widget.doneCurrent();
+ }
+ ~FrameBufferObjectWrapper() { delete fbo; }
+ QPaintDevice *realPaintDevice() { return fbo; }
+ void prepareDevice() { widget.makeCurrent(); }
+
+ ThreadSafeGLWidget widget;
+ QGLFramebufferObject *fbo;
+};
+
+
class ThreadPainter : public QObject
{
Q_OBJECT
public:
- ThreadPainter(QPaintDevice *pd) : paintDevice(pd), fail(true) {
+ ThreadPainter(Device *pd) : device(pd), fail(true) {
pixmap = QPixmap(40, 40);
pixmap.fill(Qt::green);
QPainter p(&pixmap);
@@ -474,6 +534,8 @@ public slots:
QTime time;
time.start();
int rotAngle = 10;
+ device->prepareDevice();
+ QPaintDevice *paintDevice = device->realPaintDevice();
QSize s(paintDevice->width(), paintDevice->height());
while (time.elapsed() < RUNNING_TIME) {
QPainter p;
@@ -506,7 +568,7 @@ public slots:
private:
QPixmap pixmap;
- QPaintDevice *paintDevice;
+ Device *device;
bool fail;
};
@@ -520,16 +582,6 @@ public:
devices.append(new T);
threads.append(new QThread);
painters.append(new ThreadPainter(devices.at(i)));
- if (devices.at(i)->devType() == QInternal::Widget) {
- QWidget *widget = static_cast<QWidget *>(devices.at(i));
- widget->resize(150, 150);
- widget->show();
- QTest::qWaitForWindowShown(widget);
- if (widget->inherits("QGLWidget")) {
- QGLWidget *glWidget = static_cast<QGLWidget *>(widget);
- glWidget->doneCurrent();
- }
- }
painters.at(i)->moveToThread(threads.at(i));
painters.at(i)->connect(threads.at(i), SIGNAL(started()), painters.at(i), SLOT(draw()));
}
@@ -568,7 +620,7 @@ public:
private:
QList<QThread *> threads;
- QList<QPaintDevice *> devices;
+ QList<Device *> devices;
QList<ThreadPainter *> painters;
int numThreads;
};
@@ -587,7 +639,12 @@ void tst_QGLThreads::painterOnGLWidgetInThread()
#ifdef Q_OS_MAC
QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll);
#endif
- PaintThreadManager<ThreadSafeGLWidget> painterThreads(5);
+ if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) ||
+ (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) {
+ QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0.", SkipAll);
+ }
+
+ PaintThreadManager<GLWidgetWrapper> painterThreads(5);
painterThreads.start();
while (painterThreads.areRunning()) {
@@ -601,12 +658,6 @@ void tst_QGLThreads::painterOnGLWidgetInThread()
QVERIFY(!painterThreads.failed());
}
-class Pixmap : public QPixmap
-{
-public:
- Pixmap() : QPixmap(200, 200) {}
-};
-
/*
This test uses QPainter to draw onto different QPixmaps in
different threads at the same time.
@@ -616,7 +667,74 @@ void tst_QGLThreads::painterOnPixmapInThread()
#ifdef Q_WS_X11
QSKIP("Drawing text in threads onto X11 drawables currently crashes on some X11 servers.", SkipAll);
#endif
- PaintThreadManager<Pixmap> painterThreads(5);
+ PaintThreadManager<PixmapWrapper> painterThreads(5);
+ painterThreads.start();
+
+ while (painterThreads.areRunning()) {
+ qApp->processEvents();
+#ifdef Q_WS_WIN
+ Sleep(100);
+#else
+ usleep(100 * 1000);
+#endif
+ }
+ QVERIFY(!painterThreads.failed());
+}
+
+/* This test uses QPainter to draw onto different QGLPixelBuffer
+ objects in different threads at the same time.
+*/
+void tst_QGLThreads::painterOnPboInThread()
+{
+#ifdef Q_OS_MAC
+ QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll);
+#endif
+ if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) ||
+ (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) {
+ QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0.", SkipAll);
+ return;
+ }
+
+ if (!QGLPixelBuffer::hasOpenGLPbuffers()) {
+ QSKIP("This system doesn't support pbuffers.", SkipAll);
+ return;
+ }
+
+ PaintThreadManager<PixelBufferWrapper> painterThreads(5);
+ painterThreads.start();
+
+ while (painterThreads.areRunning()) {
+ qApp->processEvents();
+#ifdef Q_WS_WIN
+ Sleep(100);
+#else
+ usleep(100 * 1000);
+#endif
+ }
+ QVERIFY(!painterThreads.failed());
+}
+
+/* This test uses QPainter to draw onto different
+ QGLFramebufferObjects (bound in a QGLWidget's context) in different
+ threads at the same time.
+*/
+void tst_QGLThreads::painterOnFboInThread()
+{
+#ifdef Q_OS_MAC
+ QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll);
+#endif
+ if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) ||
+ (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) {
+ QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0.", SkipAll);
+ return;
+ }
+
+ if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) {
+ QSKIP("This system doesn't support framebuffer objects.", SkipAll);
+ return;
+ }
+
+ PaintThreadManager<FrameBufferObjectWrapper> painterThreads(5);
painterThreads.start();
while (painterThreads.areRunning()) {
diff --git a/tests/auto/qglthreads/tst_qglthreads.h b/tests/auto/qglthreads/tst_qglthreads.h
index ae6b953..a8c2963 100644
--- a/tests/auto/qglthreads/tst_qglthreads.h
+++ b/tests/auto/qglthreads/tst_qglthreads.h
@@ -58,6 +58,8 @@ private slots:
void renderInThread();
void painterOnGLWidgetInThread();
void painterOnPixmapInThread();
+ void painterOnPboInThread();
+ void painterOnFboInThread();
};
#endif // TST_QGLTHREADS_H
diff --git a/tests/auto/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphs/tst_qglyphs.cpp
index b75e801..da91063 100644
--- a/tests/auto/qglyphs/tst_qglyphs.cpp
+++ b/tests/auto/qglyphs/tst_qglyphs.cpp
@@ -347,10 +347,6 @@ void tst_QGlyphs::drawMultiScriptText1()
void tst_QGlyphs::drawMultiScriptText2()
{
-#if defined(Q_WS_MAC)
- QSKIP("Unstable because of QTBUG-11145", SkipAll);
-#endif
-
QString text;
text += QChar(0x0621); // Arabic, Hamza
text += QChar(0x03D0); // Greek, beta
@@ -530,10 +526,6 @@ void tst_QGlyphs::drawUnderlinedText()
void tst_QGlyphs::drawRightToLeft()
{
-#if defined(Q_WS_MAC)
- QSKIP("Unstable because of QTBUG-11145", SkipAll);
-#endif
-
QString s;
s.append(QChar(1575));
s.append(QChar(1578));
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index 1ba5859..06de16a 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -221,6 +221,8 @@ private slots:
void drawRect_task215378();
void drawRect_task247505();
+ void drawText_subPixelPositionsInRaster_qtbug5053();
+
void drawImage_data();
void drawImage();
@@ -4562,6 +4564,40 @@ void tst_QPainter::clipBoundingRect()
}
+void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053()
+{
+#if !defined(Q_WS_MAC)
+ QSKIP("Only mac supports sub pixel positions currently", SkipAll);
+#endif
+
+ QFontMetricsF fm(qApp->font());
+
+ QImage baseLine(fm.width(QChar::fromLatin1('e')), fm.height(), QImage::Format_RGB32);
+ baseLine.fill(Qt::white);
+ {
+ QPainter p(&baseLine);
+ p.drawText(0, fm.ascent(), QString::fromLatin1("e"));
+ }
+
+ bool foundDifferentRasterization = false;
+ for (int i=1; i<12; ++i) {
+ QImage comparison(baseLine.size(), QImage::Format_RGB32);
+ comparison.fill(Qt::white);
+
+ {
+ QPainter p(&comparison);
+ p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e"));
+ }
+
+ if (comparison != baseLine) {
+ foundDifferentRasterization = true;
+ break;
+ }
+ }
+
+ QVERIFY(foundDifferentRasterization);
+}
+
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"