diff -r b72c6db6890b -r 5dc02b23752f src/opengl/qpaintengine_opengl.cpp --- a/src/opengl/qpaintengine_opengl.cpp Wed Jun 23 19:07:03 2010 +0300 +++ b/src/opengl/qpaintengine_opengl.cpp Tue Jul 06 15:10:48 2010 +0300 @@ -60,6 +60,7 @@ #include #include #include +#include #include "private/qtessellator_p.h" @@ -71,10 +72,6 @@ #include "private/qwsmanager_p.h" #endif -#ifdef QT_OPENGL_ES_1_CL -#include "qgl_cl_p.h" -#endif - #define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast(device->context()); #include @@ -671,6 +668,7 @@ , last_created_state(0) , shader_ctx(0) , grad_palette(0) + , tess_points(0) , drawable_texture(0) , ref_cleaner(this) {} @@ -780,7 +778,7 @@ void drawOffscreenPath(const QPainterPath &path); void composite(const QRectF &rect, const QPoint &maskOffset = QPoint()); - void composite(GLuint primitive, const q_vertexType *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint()); + void composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint()); bool createFragmentPrograms(); void deleteFragmentPrograms(); @@ -1792,7 +1790,7 @@ public: QOpenGLTrapezoidToArrayTessellator() : vertices(0), allocated(0), size(0) {} ~QOpenGLTrapezoidToArrayTessellator() { free(vertices); } - q_vertexType *vertices; + GLfloat *vertices; int allocated; int size; QRectF bounds; @@ -1813,36 +1811,36 @@ if (size > allocated - 12) { #endif allocated = qMax(2*allocated, 512); - vertices = (q_vertexType *)realloc(vertices, allocated * sizeof(q_vertexType)); + vertices = (GLfloat *)realloc(vertices, allocated * sizeof(GLfloat)); } QGLTrapezoid t = toGLTrapezoid(trap); #ifndef QT_OPENGL_ES - vertices[size++] = f2vt(t.topLeftX); - vertices[size++] = f2vt(t.top); - vertices[size++] = f2vt(t.topRightX); - vertices[size++] = f2vt(t.top); - vertices[size++] = f2vt(t.bottomRightX); - vertices[size++] = f2vt(t.bottom); - vertices[size++] = f2vt(t.bottomLeftX); - vertices[size++] = f2vt(t.bottom); + vertices[size++] = t.topLeftX; + vertices[size++] = t.top; + vertices[size++] = t.topRightX; + vertices[size++] = t.top; + vertices[size++] = t.bottomRightX; + vertices[size++] = t.bottom; + vertices[size++] = t.bottomLeftX; + vertices[size++] = t.bottom; #else // First triangle - vertices[size++] = f2vt(t.topLeftX); - vertices[size++] = f2vt(t.top); - vertices[size++] = f2vt(t.topRightX); - vertices[size++] = f2vt(t.top); - vertices[size++] = f2vt(t.bottomRightX); - vertices[size++] = f2vt(t.bottom); + vertices[size++] = t.topLeftX; + vertices[size++] = t.top; + vertices[size++] = t.topRightX; + vertices[size++] = t.top; + vertices[size++] = t.bottomRightX; + vertices[size++] = t.bottom; // Second triangle - vertices[size++] = f2vt(t.bottomLeftX); - vertices[size++] = f2vt(t.bottom); - vertices[size++] = f2vt(t.topLeftX); - vertices[size++] = f2vt(t.top); - vertices[size++] = f2vt(t.bottomRightX); - vertices[size++] = f2vt(t.bottom); + vertices[size++] = t.bottomLeftX; + vertices[size++] = t.bottom; + vertices[size++] = t.topLeftX; + vertices[size++] = t.top; + vertices[size++] = t.bottomRightX; + vertices[size++] = t.bottom; #endif } @@ -1869,7 +1867,7 @@ if (use_fragment_programs && !(fast_style && has_fast_composition_mode)) { composite(geometry_mode, tessellator.vertices, tessellator.size / 2); } else { - glVertexPointer(2, q_vertexTypeEnum, 0, tessellator.vertices); + glVertexPointer(2, GL_FLOAT, 0, tessellator.vertices); glEnableClientState(GL_VERTEX_ARRAY); glDrawArrays(geometry_mode, 0, tessellator.size/2); glDisableClientState(GL_VERTEX_ARRAY); @@ -1958,6 +1956,8 @@ void QOpenGLPaintEnginePrivate::drawVertexArrays() { + if (tess_points_stops.count() == 0) + return; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_DOUBLE, 0, tess_points.data()); int previous_stop = 0; @@ -2270,7 +2270,7 @@ return; } -#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_1_CL) +#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2) glClearDepthf(0.0f); #else glClearDepth(0.0f); @@ -2286,12 +2286,12 @@ const QVector rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects(); // rectangle count * 2 (triangles) * vertex count * component count (Z omitted) - QDataBuffer clipVertex(rects.size()*2*3*2); + QDataBuffer clipVertex(rects.size()*2*3*2); for (int i = 0; i < rects.size(); ++i) { - q_vertexType x = i2vt(rects.at(i).left()); - q_vertexType w = i2vt(rects.at(i).width()); - q_vertexType h = i2vt(rects.at(i).height()); - q_vertexType y = i2vt(rects.at(i).top()); + GLfloat x = GLfloat(rects.at(i).left()); + GLfloat w = GLfloat(rects.at(i).width()); + GLfloat h = GLfloat(rects.at(i).height()); + GLfloat y = GLfloat(rects.at(i).top()); // First triangle clipVertex.add(x); @@ -2319,7 +2319,7 @@ glLoadIdentity(); glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, clipVertex.data()); + glVertexPointer(2, GL_FLOAT, 0, clipVertex.data()); glDrawArrays(GL_TRIANGLES, 0, rects.size()*2*3); glDisableClientState(GL_VERTEX_ARRAY); @@ -3111,8 +3111,8 @@ { } -extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); -extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array); +extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); +extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array); void QGLTrapezoidMaskGenerator::drawMask(const QRect &rect) { @@ -3143,7 +3143,7 @@ // clear mask glBlendFunc(GL_ZERO, GL_ZERO); // clear - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); glEnableClientState(GL_VERTEX_ARRAY); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); @@ -3350,15 +3350,15 @@ QTransform gl_to_qt(1, 0, 0, -1, 0, offscreen->drawableSize().height()); QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate; - float m[3][4] = { { inv_matrix.m11(), inv_matrix.m12(), inv_matrix.m13() }, - { inv_matrix.m21(), inv_matrix.m22(), inv_matrix.m23() }, - { inv_matrix.m31(), inv_matrix.m32(), inv_matrix.m33() } }; + float m[3][4] = { { float(inv_matrix.m11()), float(inv_matrix.m12()), float(inv_matrix.m13()) }, + { float(inv_matrix.m21()), float(inv_matrix.m22()), float(inv_matrix.m23()) }, + { float(inv_matrix.m31()), float(inv_matrix.m32()), float(inv_matrix.m33()) } }; QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top()) - (offscreen->offscreenSize().height() - rect.top())); // last component needs to be 1.0f to avoid Nvidia bug on linux - float ellipse_offset[4] = { offs.x(), offs.y(), 0.0f, 1.0f }; + float ellipse_offset[4] = { float(offs.x()), float(offs.y()), 0.0f, 1.0f }; GLfloat vertexArray[4 * 2]; qt_add_rect_to_array(rect, vertexArray); @@ -3374,7 +3374,7 @@ glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_ELLIPSE_OFFSET], ellipse_offset); glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_FRAGMENT_PROGRAM_ARB); @@ -3404,7 +3404,7 @@ Q_Q(QOpenGLPaintEngine); DEBUG_ONCE_STR("QOpenGLPaintEngine::drawRects(): drawing fast rect"); - q_vertexType vertexArray[10]; + GLfloat vertexArray[10]; qt_add_rect_to_array(r, vertexArray); if (has_pen) @@ -3425,7 +3425,7 @@ if (fast_style && has_fast_composition_mode) { glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); } else { @@ -3444,7 +3444,7 @@ vertexArray[8] = vertexArray[0]; vertexArray[9] = vertexArray[1]; - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); glEnableClientState(GL_VERTEX_ARRAY); glDrawArrays(GL_LINE_STRIP, 0, 5); glDisableClientState(GL_VERTEX_ARRAY); @@ -3551,7 +3551,7 @@ } } -static void addQuadAsTriangle(q_vertexType *quad, q_vertexType *triangle) +static void addQuadAsTriangle(GLfloat *quad, GLfloat *triangle) { triangle[0] = quad[0]; triangle[1] = quad[1]; @@ -3612,7 +3612,7 @@ d->flushDrawQueue(); if (d->has_fast_pen) { - QVarLengthArray vertexArray(6 * pointCount); + QVarLengthArray vertexArray(6 * pointCount); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -3622,25 +3622,22 @@ for (int i = 0; i < pointCount; ++i) { QPointF mapped = d->matrix.map(points[i]); - qreal xf = qRound(mapped.x()); - qreal yf = qRound(mapped.y()); - - q_vertexType x = f2vt(xf); - q_vertexType y = f2vt(yf); + GLfloat x = GLfloat(qRound(mapped.x())); + GLfloat y = GLfloat(qRound(mapped.y())); vertexArray[j++] = x; - vertexArray[j++] = y - f2vt(0.5); - - vertexArray[j++] = x + f2vt(1.5); - vertexArray[j++] = y + f2vt(1.0); + vertexArray[j++] = y - 0.5f; + + vertexArray[j++] = x + 1.5f; + vertexArray[j++] = y + 1.0f; vertexArray[j++] = x; - vertexArray[j++] = y + f2vt(1.0); + vertexArray[j++] = y + 1.0f; } glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); + glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); glDrawArrays(GL_TRIANGLES, 0, pointCount*3); glDisableClientState(GL_VERTEX_ARRAY); @@ -3657,7 +3654,7 @@ } else { Q_ASSERT(sizeof(QPointF) == 8); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); } glEnableClientState(GL_VERTEX_ARRAY); @@ -3725,47 +3722,47 @@ } } - q_vertexType endCap = f2vt(d->cpen.capStyle() == Qt::FlatCap ? 0 : 0.5); + GLfloat endCap = d->cpen.capStyle() == Qt::FlatCap ? 0.0f : 0.5f; if (useRects) { - QVarLengthArray vertexArray(12 * lineCount); - - q_vertexType quad[8]; + QVarLengthArray vertexArray(12 * lineCount); + + GLfloat quad[8]; for (int i = 0; i < lineCount; ++i) { - q_vertexType x1 = f2vt(lines[i].x1()); - q_vertexType x2 = f2vt(lines[i].x2()); - q_vertexType y1 = f2vt(lines[i].y1()); - q_vertexType y2 = f2vt(lines[i].y2()); + GLfloat x1 = lines[i].x1(); + GLfloat x2 = lines[i].x2(); + GLfloat y1 = lines[i].y1(); + GLfloat y2 = lines[i].y2(); if (x1 == x2) { if (y1 > y2) qSwap(y1, y2); - quad[0] = x1 - f2vt(0.5); + quad[0] = x1 - 0.5f; quad[1] = y1 - endCap; - quad[2] = x1 + f2vt(0.5); + quad[2] = x1 + 0.5f; quad[3] = y1 - endCap; - quad[4] = x1 + f2vt(0.5); + quad[4] = x1 + 0.5f; quad[5] = y2 + endCap; - quad[6] = x1 - f2vt(0.5); + quad[6] = x1 - 0.5f; quad[7] = y2 + endCap; } else { if (x1 > x2) qSwap(x1, x2); quad[0] = x1 - endCap; - quad[1] = y1 + f2vt(0.5); + quad[1] = y1 + 0.5f; quad[2] = x1 - endCap; - quad[3] = y1 - f2vt(0.5); + quad[3] = y1 - 0.5f; quad[4] = x2 + endCap; - quad[5] = y1 - f2vt(0.5); + quad[5] = y1 - 0.5f; quad[6] = x2 + endCap; - quad[7] = y1 + f2vt(0.5); + quad[7] = y1 + 0.5f; } addQuadAsTriangle(quad, &vertexArray[12*i]); @@ -3773,26 +3770,26 @@ glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); + glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); glDrawArrays(GL_TRIANGLES, 0, lineCount*6); glDisableClientState(GL_VERTEX_ARRAY); } else { - QVarLengthArray vertexArray(4 * lineCount); + QVarLengthArray vertexArray(4 * lineCount); for (int i = 0; i < lineCount; ++i) { const QPointF a = lines[i].p1(); - vertexArray[4*i] = f2vt(lines[i].x1()); - vertexArray[4*i+1] = f2vt(lines[i].y1()); - vertexArray[4*i+2] = f2vt(lines[i].x2()); - vertexArray[4*i+3] = f2vt(lines[i].y2()); + vertexArray[4*i] = lines[i].x1(); + vertexArray[4*i+1] = lines[i].y1(); + vertexArray[4*i+2] = lines[i].x2(); + vertexArray[4*i+3] = lines[i].y2(); } glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); + glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); glDrawArrays(GL_LINES, 0, lineCount*2); - glVertexPointer(2, q_vertexTypeEnum, 4*sizeof(q_vertexType), vertexArray.constData() + 2); + glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), vertexArray.constData() + 2); glDrawArrays(GL_POINTS, 0, lineCount); glDisableClientState(GL_VERTEX_ARRAY); @@ -3879,7 +3876,7 @@ } else { Q_ASSERT(sizeof(QPointF) == 8); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); } glEnableClientState(GL_VERTEX_ARRAY); @@ -3898,12 +3895,12 @@ if (d->has_pen) { if (d->has_fast_pen && !d->high_quality_antialiasing) { d->setGradientOps(d->cpen.brush(), bounds); - QVarLengthArray vertexArray(pointCount*2 + 2); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); + QVarLengthArray vertexArray(pointCount*2 + 2); + glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); int i; for (i=0; i &); + void cacheGlyphs(QGLContext *, QFontEngine *, glyph_t *glyphs, int numGlyphs); void cleanCache(); void allocTexture(int width, int height, GLuint texture); @@ -4712,8 +4709,8 @@ } #endif -void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti, - const QVarLengthArray &glyphs) +void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine, + glyph_t *glyphs, int numGlyphs) { QGLContextHash::const_iterator dev_it = qt_context_cache.constFind(context); QGLFontGlyphHash *font_cache = 0; @@ -4749,25 +4746,25 @@ } Q_ASSERT(font_cache != 0); - QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(ti.fontEngine); + QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(fontEngine); QGLGlyphHash *cache = 0; if (cache_it == font_cache->constEnd()) { cache = new QGLGlyphHash; - font_cache->insert(ti.fontEngine, cache); - connect(ti.fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*))); + font_cache->insert(fontEngine, cache); + connect(fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*))); } else { cache = cache_it.value(); } current_cache = cache; quint64 font_key = (reinterpret_cast(context_key ? context_key : context) << 32) - | reinterpret_cast(ti.fontEngine); + | reinterpret_cast(fontEngine); QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key); QGLFontTexture *font_tex; if (it == qt_font_textures.constEnd()) { GLuint font_texture; glGenTextures(1, &font_texture); - GLint tex_height = qt_next_power_of_two(qRound(ti.ascent.toReal() + ti.descent.toReal())+2); + GLint tex_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2); GLint tex_width = qt_next_power_of_two(tex_height*30); // ### GLint max_tex_size; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); @@ -4789,16 +4786,16 @@ glBindTexture(GL_TEXTURE_2D, font_tex->texture); } - for (int i=0; i< glyphs.size(); ++i) { + for (int i=0; i< numGlyphs; ++i) { QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]); if (it == cache->constEnd()) { // render new glyph and put it in the cache - glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]); + glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]); int glyph_width = qRound(metrics.width.toReal())+2; - int glyph_height = qRound(ti.ascent.toReal() + ti.descent.toReal())+2; + int glyph_height = qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2; if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) { - int strip_height = qt_next_power_of_two(qRound(ti.ascent.toReal() + ti.descent.toReal())+2); + int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2); font_tex->x_offset = x_margin; font_tex->y_offset += strip_height; if (font_tex->y_offset >= font_tex->height) { @@ -4831,7 +4828,7 @@ } } - QImage glyph_im(ti.fontEngine->alphaMapForGlyph(glyphs[i])); + QImage glyph_im(fontEngine->alphaMapForGlyph(glyphs[i])); glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8); glyph_width = glyph_im.width(); Q_ASSERT(glyph_width >= 0); @@ -4911,30 +4908,15 @@ qt_glyph_cache()->cleanupContext(ctx); } -void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) +void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) { Q_D(QOpenGLPaintEngine); - const QTextItemInt &ti = static_cast(textItem); - - // fall back to drawing a polygon if the scale factor is large, or - // we use a gradient pen - if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern - && d->pen_brush_style <= Qt::ConicalGradientPattern)) { - QPaintEngine::drawTextItem(p, textItem); - return; - } - d->flushDrawQueue(); - // add the glyphs used to the glyph texture cache - QVarLengthArray positions; - QVarLengthArray glyphs; - QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y())); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - // make sure the glyphs we want to draw are in the cache - qt_glyph_cache()->cacheGlyphs(d->device->context(), ti, glyphs); + qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine, textItem->glyphs, + textItem->numGlyphs); d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops qt_glColor4ubv(d->pen_color); @@ -4948,21 +4930,21 @@ #endif // do the actual drawing - q_vertexType vertexArray[4*2]; - q_vertexType texCoordArray[4*2]; - - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); - glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); + GLfloat vertexArray[4*2]; + GLfloat texCoordArray[4*2]; + + glVertexPointer(2, GL_FLOAT, 0, vertexArray); + glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - bool antialias = !(ti.fontEngine->fontDef.styleStrategy & QFont::NoAntialias) - && (d->matrix.type() > QTransform::TxTranslate); + bool antialias = !(textItem->fontEngine->fontDef.styleStrategy & QFont::NoAntialias) + && (d->matrix.type() > QTransform::TxTranslate); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST); - for (int i=0; i< glyphs.size(); ++i) { - QGLGlyphCoord *g = qt_glyph_cache()->lookup(ti.fontEngine, glyphs[i]); + for (int i=0; i< textItem->numGlyphs; ++i) { + QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine, textItem->glyphs[i]); // we don't cache glyphs with no width/height if (!g) @@ -4974,8 +4956,8 @@ x2 = x1 + g->width; y2 = y1 + g->height; - QPointF logical_pos((positions[i].x - g->x_offset).toReal(), - (positions[i].y + g->y_offset).toReal()); + QPointF logical_pos((textItem->glyphPositions[i].x - g->x_offset).toReal(), + (textItem->glyphPositions[i].y + g->y_offset).toReal()); qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray); qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray); @@ -4992,6 +4974,40 @@ // XXX: This may not be needed as this behavior does seem to be caused by driver bug glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); #endif + +} + +void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) +{ + Q_D(QOpenGLPaintEngine); + + const QTextItemInt &ti = static_cast(textItem); + + // fall back to drawing a polygon if the scale factor is large, or + // we use a gradient pen + if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern + && d->pen_brush_style <= Qt::ConicalGradientPattern)) { + QPaintEngine::drawTextItem(p, textItem); + return; + } + + // add the glyphs used to the glyph texture cache + QVarLengthArray positions; + QVarLengthArray glyphs; + QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y())); + ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + + { + QStaticTextItem staticTextItem; + staticTextItem.chars = ti.chars; + staticTextItem.fontEngine = ti.fontEngine; + staticTextItem.glyphs = glyphs.data(); + staticTextItem.numChars = ti.num_chars; + staticTextItem.numGlyphs = glyphs.size(); + staticTextItem.glyphPositions = positions.data(); + drawStaticTextItem(&staticTextItem); + } + } @@ -5165,7 +5181,7 @@ Q_UNUSED(rect); Q_UNUSED(maskOffset); #else - q_vertexType vertexArray[8]; + GLfloat vertexArray[8]; qt_add_rect_to_array(rect, vertexArray); composite(GL_TRIANGLE_FAN, vertexArray, 4, maskOffset); @@ -5173,7 +5189,7 @@ } -void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType *vertexArray, int vertexCount, const QPoint &maskOffset) +void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset) { #ifdef QT_OPENGL_ES Q_UNUSED(primitive); @@ -5196,8 +5212,8 @@ qreal minX = 1e9, minY = 1e9, maxX = -1e9, maxY = -1e9; for (int i = 0; i < vertexCount; ++i) { - qreal x = vt2f(vertexArray[2 * i]); - qreal y = vt2f(vertexArray[2 * i + 1]); + qreal x = vertexArray[2 * i]; + qreal y = vertexArray[2 * i + 1]; qreal tx, ty; matrix.map(x, y, &tx, &ty); @@ -5256,7 +5272,7 @@ } glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); + glVertexPointer(2, GL_FLOAT, 0, vertexArray); glEnable(GL_FRAGMENT_PROGRAM_ARB); GLuint program = qt_gl_program_cache()->getProgram(device->context(), fragment_brush,