summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/gl2paintengineex')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp35
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp21
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h4
-rw-r--r--src/opengl/gl2paintengineex/qtriangulatingstroker.cpp1
4 files changed, 56 insertions, 5 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index b762bcc0f6..d89ef08d90 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -866,6 +866,32 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
if (do_vectorpath_cache)
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());
+ glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.constData());
+ } 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);
@@ -1525,8 +1551,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 53a2f3ac1a..f8e34d4286 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();
@@ -291,4 +291,19 @@ int QGLTextureGlyphCache::glyphPadding() const
return 1;
}
+int QGLTextureGlyphCache::maxTextureWidth() const
+{
+ if (ctx == 0)
+ return QImageTextureGlyphCache::maxTextureWidth();
+ else
+ return ctx->d_ptr->maxTextureSize();
+}
+
+int QGLTextureGlyphCache::maxTextureHeight() const
+{
+ if (ctx == 0)
+ return QImageTextureGlyphCache::maxTextureHeight();
+ else
+ return ctx->d_ptr->maxTextureSize();
+}
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 2ae3a6420f..ada47e9e5d 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -106,8 +106,10 @@ 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;
+ virtual int maxTextureWidth() const;
+ virtual int maxTextureHeight() const;
inline GLuint texture() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
index 9bc099df38..7b0b8a2180 100644
--- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
+++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
@@ -509,6 +509,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c
m_dash_stroker.setDashPattern(pen.dashPattern());
m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width);
+ m_dash_stroker.setDashOffset(pen.dashOffset());
m_dash_stroker.setMiterLimit(pen.miterLimit());
m_dash_stroker.setClipRect(clip);