diff options
Diffstat (limited to 'src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 3ddc15a..735aab1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -872,6 +872,35 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable path.makeCacheable(); + if (!device->format().stencil()) { + // If there is no stencil buffer, triangulate the path instead. + + QRectF bbox = path.controlPointRect(); + // If the path doesn't fit within these limits, it is possible that the triangulation will fail. + bool withinLimits = (bbox.left() > -0x8000 * inverseScale) + && (bbox.right() < 0x8000 * inverseScale) + && (bbox.top() > -0x8000 * inverseScale) + && (bbox.bottom() < 0x8000 * inverseScale); + if (withinLimits) { + QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale)); + + QVarLengthArray<float> vertices(polys.vertices.size()); + for (int i = 0; i < polys.vertices.size(); ++i) + vertices[i] = float(inverseScale * polys.vertices.at(i)); + + prepareForDraw(currentBrush.isOpaque()); + setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData()); + if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) + glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data()); + else + glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data()); + } else { + // We can't handle big, concave painter paths with OpenGL without stencil buffer. + qWarning("Painter path exceeds +/-32767 pixels."); + } + return; + } + // The path is too complicated & needs the stencil technique vertexCoordinateArray.clear(); vertexCoordinateArray.addPath(path, inverseScale, false); @@ -1477,11 +1506,13 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp QOpenGL2PaintEngineState *s = q->state(); + void *cacheKey = const_cast<QGLContext *>(QGLContextPrivate::contextGroup(ctx)->context()); QGLTextureGlyphCache *cache = - (QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(ctx, glyphType, QTransform()); - if (!cache || cache->cacheType() != glyphType) { + (QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(cacheKey, glyphType, QTransform()); + if (!cache || cache->cacheType() != glyphType || cache->context() == 0) { cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform()); - staticTextItem->fontEngine()->setGlyphCache(ctx, cache); + staticTextItem->fontEngine()->setGlyphCache(cacheKey, cache); + cache->insert(ctx, cache); } else if (cache->context() == 0) { // Old context has been destroyed, new context has same ptr value cache->setContext(ctx); } @@ -1499,13 +1530,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp // cache so this text is performed before we test if the cache size has changed. if (recreateVertexArrays) { cache->setPaintEnginePrivate(this); - if (!cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, - staticTextItem->glyphs, staticTextItem->glyphPositions)) { - // No space in cache. We need to clear the cache and try again - cache->clear(); - cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, - staticTextItem->glyphs, staticTextItem->glyphPositions); - } + cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, + staticTextItem->glyphs, staticTextItem->glyphPositions); + cache->fillInPendingGlyphs(); } if (cache->width() == 0 || cache->height() == 0) @@ -1551,8 +1578,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; |