58 #include "qvarlengtharray.h" |
58 #include "qvarlengtharray.h" |
59 #include <private/qpainter_p.h> |
59 #include <private/qpainter_p.h> |
60 #include <private/qglpixelbuffer_p.h> |
60 #include <private/qglpixelbuffer_p.h> |
61 #include <private/qbezier_p.h> |
61 #include <private/qbezier_p.h> |
62 #include <qglframebufferobject.h> |
62 #include <qglframebufferobject.h> |
|
63 #include <private/qstatictext_p.h> |
63 |
64 |
64 #include "private/qtessellator_p.h" |
65 #include "private/qtessellator_p.h" |
65 |
66 |
66 #include "util/fragmentprograms_p.h" |
67 #include "util/fragmentprograms_p.h" |
67 |
68 |
68 #ifdef Q_WS_QWS |
69 #ifdef Q_WS_QWS |
69 #include "private/qglwindowsurface_qws_p.h" |
70 #include "private/qglwindowsurface_qws_p.h" |
70 #include "qwsmanager_qws.h" |
71 #include "qwsmanager_qws.h" |
71 #include "private/qwsmanager_p.h" |
72 #include "private/qwsmanager_p.h" |
72 #endif |
|
73 |
|
74 #ifdef QT_OPENGL_ES_1_CL |
|
75 #include "qgl_cl_p.h" |
|
76 #endif |
73 #endif |
77 |
74 |
78 #define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(device->context()); |
75 #define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(device->context()); |
79 |
76 |
80 #include <stdlib.h> |
77 #include <stdlib.h> |
778 void drawTiledImageAsPath(const QRectF &r, const QImage &img, qreal sx, qreal sy, const QPointF &offset); |
776 void drawTiledImageAsPath(const QRectF &r, const QImage &img, qreal sx, qreal sy, const QPointF &offset); |
779 |
777 |
780 void drawOffscreenPath(const QPainterPath &path); |
778 void drawOffscreenPath(const QPainterPath &path); |
781 |
779 |
782 void composite(const QRectF &rect, const QPoint &maskOffset = QPoint()); |
780 void composite(const QRectF &rect, const QPoint &maskOffset = QPoint()); |
783 void composite(GLuint primitive, const q_vertexType *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint()); |
781 void composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint()); |
784 |
782 |
785 bool createFragmentPrograms(); |
783 bool createFragmentPrograms(); |
786 void deleteFragmentPrograms(); |
784 void deleteFragmentPrograms(); |
787 void updateFragmentProgramData(int locations[]); |
785 void updateFragmentProgramData(int locations[]); |
788 |
786 |
1811 if (size > allocated - 8) { |
1809 if (size > allocated - 8) { |
1812 #else |
1810 #else |
1813 if (size > allocated - 12) { |
1811 if (size > allocated - 12) { |
1814 #endif |
1812 #endif |
1815 allocated = qMax(2*allocated, 512); |
1813 allocated = qMax(2*allocated, 512); |
1816 vertices = (q_vertexType *)realloc(vertices, allocated * sizeof(q_vertexType)); |
1814 vertices = (GLfloat *)realloc(vertices, allocated * sizeof(GLfloat)); |
1817 } |
1815 } |
1818 |
1816 |
1819 QGLTrapezoid t = toGLTrapezoid(trap); |
1817 QGLTrapezoid t = toGLTrapezoid(trap); |
1820 |
1818 |
1821 #ifndef QT_OPENGL_ES |
1819 #ifndef QT_OPENGL_ES |
1822 vertices[size++] = f2vt(t.topLeftX); |
1820 vertices[size++] = t.topLeftX; |
1823 vertices[size++] = f2vt(t.top); |
1821 vertices[size++] = t.top; |
1824 vertices[size++] = f2vt(t.topRightX); |
1822 vertices[size++] = t.topRightX; |
1825 vertices[size++] = f2vt(t.top); |
1823 vertices[size++] = t.top; |
1826 vertices[size++] = f2vt(t.bottomRightX); |
1824 vertices[size++] = t.bottomRightX; |
1827 vertices[size++] = f2vt(t.bottom); |
1825 vertices[size++] = t.bottom; |
1828 vertices[size++] = f2vt(t.bottomLeftX); |
1826 vertices[size++] = t.bottomLeftX; |
1829 vertices[size++] = f2vt(t.bottom); |
1827 vertices[size++] = t.bottom; |
1830 #else |
1828 #else |
1831 // First triangle |
1829 // First triangle |
1832 vertices[size++] = f2vt(t.topLeftX); |
1830 vertices[size++] = t.topLeftX; |
1833 vertices[size++] = f2vt(t.top); |
1831 vertices[size++] = t.top; |
1834 vertices[size++] = f2vt(t.topRightX); |
1832 vertices[size++] = t.topRightX; |
1835 vertices[size++] = f2vt(t.top); |
1833 vertices[size++] = t.top; |
1836 vertices[size++] = f2vt(t.bottomRightX); |
1834 vertices[size++] = t.bottomRightX; |
1837 vertices[size++] = f2vt(t.bottom); |
1835 vertices[size++] = t.bottom; |
1838 |
1836 |
1839 // Second triangle |
1837 // Second triangle |
1840 vertices[size++] = f2vt(t.bottomLeftX); |
1838 vertices[size++] = t.bottomLeftX; |
1841 vertices[size++] = f2vt(t.bottom); |
1839 vertices[size++] = t.bottom; |
1842 vertices[size++] = f2vt(t.topLeftX); |
1840 vertices[size++] = t.topLeftX; |
1843 vertices[size++] = f2vt(t.top); |
1841 vertices[size++] = t.top; |
1844 vertices[size++] = f2vt(t.bottomRightX); |
1842 vertices[size++] = t.bottomRightX; |
1845 vertices[size++] = f2vt(t.bottom); |
1843 vertices[size++] = t.bottom; |
1846 #endif |
1844 #endif |
1847 } |
1845 } |
1848 |
1846 |
1849 |
1847 |
1850 void QOpenGLPaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount, |
1848 void QOpenGLPaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount, |
1867 #endif |
1865 #endif |
1868 |
1866 |
1869 if (use_fragment_programs && !(fast_style && has_fast_composition_mode)) { |
1867 if (use_fragment_programs && !(fast_style && has_fast_composition_mode)) { |
1870 composite(geometry_mode, tessellator.vertices, tessellator.size / 2); |
1868 composite(geometry_mode, tessellator.vertices, tessellator.size / 2); |
1871 } else { |
1869 } else { |
1872 glVertexPointer(2, q_vertexTypeEnum, 0, tessellator.vertices); |
1870 glVertexPointer(2, GL_FLOAT, 0, tessellator.vertices); |
1873 glEnableClientState(GL_VERTEX_ARRAY); |
1871 glEnableClientState(GL_VERTEX_ARRAY); |
1874 glDrawArrays(geometry_mode, 0, tessellator.size/2); |
1872 glDrawArrays(geometry_mode, 0, tessellator.size/2); |
1875 glDisableClientState(GL_VERTEX_ARRAY); |
1873 glDisableClientState(GL_VERTEX_ARRAY); |
1876 } |
1874 } |
1877 } |
1875 } |
2284 glDepthFunc(GL_ALWAYS); |
2284 glDepthFunc(GL_ALWAYS); |
2285 |
2285 |
2286 const QVector<QRect> rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects(); |
2286 const QVector<QRect> rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects(); |
2287 |
2287 |
2288 // rectangle count * 2 (triangles) * vertex count * component count (Z omitted) |
2288 // rectangle count * 2 (triangles) * vertex count * component count (Z omitted) |
2289 QDataBuffer<q_vertexType> clipVertex(rects.size()*2*3*2); |
2289 QDataBuffer<GLfloat> clipVertex(rects.size()*2*3*2); |
2290 for (int i = 0; i < rects.size(); ++i) { |
2290 for (int i = 0; i < rects.size(); ++i) { |
2291 q_vertexType x = i2vt(rects.at(i).left()); |
2291 GLfloat x = GLfloat(rects.at(i).left()); |
2292 q_vertexType w = i2vt(rects.at(i).width()); |
2292 GLfloat w = GLfloat(rects.at(i).width()); |
2293 q_vertexType h = i2vt(rects.at(i).height()); |
2293 GLfloat h = GLfloat(rects.at(i).height()); |
2294 q_vertexType y = i2vt(rects.at(i).top()); |
2294 GLfloat y = GLfloat(rects.at(i).top()); |
2295 |
2295 |
2296 // First triangle |
2296 // First triangle |
2297 clipVertex.add(x); |
2297 clipVertex.add(x); |
2298 clipVertex.add(y); |
2298 clipVertex.add(y); |
2299 |
2299 |
3141 |
3141 |
3142 QVector<QGLTrapezoid> trapezoids = generateTrapezoids(); |
3142 QVector<QGLTrapezoid> trapezoids = generateTrapezoids(); |
3143 |
3143 |
3144 // clear mask |
3144 // clear mask |
3145 glBlendFunc(GL_ZERO, GL_ZERO); // clear |
3145 glBlendFunc(GL_ZERO, GL_ZERO); // clear |
3146 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
3146 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
3147 glEnableClientState(GL_VERTEX_ARRAY); |
3147 glEnableClientState(GL_VERTEX_ARRAY); |
3148 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
3148 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
3149 glDisableClientState(GL_VERTEX_ARRAY); |
3149 glDisableClientState(GL_VERTEX_ARRAY); |
3150 |
3150 |
3151 glBlendFunc(GL_ONE, GL_ONE); // add mask |
3151 glBlendFunc(GL_ONE, GL_ONE); // add mask |
3348 |
3348 |
3349 QTransform translate(1, 0, 0, 1, -ellipseRect.center().x(), -ellipseRect.center().y()); |
3349 QTransform translate(1, 0, 0, 1, -ellipseRect.center().x(), -ellipseRect.center().y()); |
3350 QTransform gl_to_qt(1, 0, 0, -1, 0, offscreen->drawableSize().height()); |
3350 QTransform gl_to_qt(1, 0, 0, -1, 0, offscreen->drawableSize().height()); |
3351 QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate; |
3351 QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate; |
3352 |
3352 |
3353 float m[3][4] = { { inv_matrix.m11(), inv_matrix.m12(), inv_matrix.m13() }, |
3353 float m[3][4] = { { float(inv_matrix.m11()), float(inv_matrix.m12()), float(inv_matrix.m13()) }, |
3354 { inv_matrix.m21(), inv_matrix.m22(), inv_matrix.m23() }, |
3354 { float(inv_matrix.m21()), float(inv_matrix.m22()), float(inv_matrix.m23()) }, |
3355 { inv_matrix.m31(), inv_matrix.m32(), inv_matrix.m33() } }; |
3355 { float(inv_matrix.m31()), float(inv_matrix.m32()), float(inv_matrix.m33()) } }; |
3356 |
3356 |
3357 QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top()) |
3357 QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top()) |
3358 - (offscreen->offscreenSize().height() - rect.top())); |
3358 - (offscreen->offscreenSize().height() - rect.top())); |
3359 |
3359 |
3360 // last component needs to be 1.0f to avoid Nvidia bug on linux |
3360 // last component needs to be 1.0f to avoid Nvidia bug on linux |
3361 float ellipse_offset[4] = { offs.x(), offs.y(), 0.0f, 1.0f }; |
3361 float ellipse_offset[4] = { float(offs.x()), float(offs.y()), 0.0f, 1.0f }; |
3362 |
3362 |
3363 GLfloat vertexArray[4 * 2]; |
3363 GLfloat vertexArray[4 * 2]; |
3364 qt_add_rect_to_array(rect, vertexArray); |
3364 qt_add_rect_to_array(rect, vertexArray); |
3365 |
3365 |
3366 glBlendFunc(GL_ONE, GL_ZERO); // set mask |
3366 glBlendFunc(GL_ONE, GL_ZERO); // set mask |
3372 glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M2], m[2]); |
3372 glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M2], m[2]); |
3373 |
3373 |
3374 glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_ELLIPSE_OFFSET], ellipse_offset); |
3374 glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_ELLIPSE_OFFSET], ellipse_offset); |
3375 |
3375 |
3376 glEnableClientState(GL_VERTEX_ARRAY); |
3376 glEnableClientState(GL_VERTEX_ARRAY); |
3377 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
3377 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
3378 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
3378 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
3379 glDisableClientState(GL_VERTEX_ARRAY); |
3379 glDisableClientState(GL_VERTEX_ARRAY); |
3380 glDisable(GL_FRAGMENT_PROGRAM_ARB); |
3380 glDisable(GL_FRAGMENT_PROGRAM_ARB); |
3381 #endif |
3381 #endif |
3382 } |
3382 } |
3423 bool fast_style = current_style == Qt::LinearGradientPattern |
3423 bool fast_style = current_style == Qt::LinearGradientPattern |
3424 || current_style == Qt::SolidPattern; |
3424 || current_style == Qt::SolidPattern; |
3425 |
3425 |
3426 if (fast_style && has_fast_composition_mode) { |
3426 if (fast_style && has_fast_composition_mode) { |
3427 glEnableClientState(GL_VERTEX_ARRAY); |
3427 glEnableClientState(GL_VERTEX_ARRAY); |
3428 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
3428 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
3429 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
3429 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
3430 glDisableClientState(GL_VERTEX_ARRAY); |
3430 glDisableClientState(GL_VERTEX_ARRAY); |
3431 } else { |
3431 } else { |
3432 composite(r); |
3432 composite(r); |
3433 } |
3433 } |
3442 setGradientOps(cpen.brush(), r); |
3442 setGradientOps(cpen.brush(), r); |
3443 |
3443 |
3444 vertexArray[8] = vertexArray[0]; |
3444 vertexArray[8] = vertexArray[0]; |
3445 vertexArray[9] = vertexArray[1]; |
3445 vertexArray[9] = vertexArray[1]; |
3446 |
3446 |
3447 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
3447 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
3448 glEnableClientState(GL_VERTEX_ARRAY); |
3448 glEnableClientState(GL_VERTEX_ARRAY); |
3449 glDrawArrays(GL_LINE_STRIP, 0, 5); |
3449 glDrawArrays(GL_LINE_STRIP, 0, 5); |
3450 glDisableClientState(GL_VERTEX_ARRAY); |
3450 glDisableClientState(GL_VERTEX_ARRAY); |
3451 } else { |
3451 } else { |
3452 QPainterPath path; |
3452 QPainterPath path; |
3610 } |
3610 } |
3611 |
3611 |
3612 d->flushDrawQueue(); |
3612 d->flushDrawQueue(); |
3613 |
3613 |
3614 if (d->has_fast_pen) { |
3614 if (d->has_fast_pen) { |
3615 QVarLengthArray<q_vertexType> vertexArray(6 * pointCount); |
3615 QVarLengthArray<GLfloat> vertexArray(6 * pointCount); |
3616 |
3616 |
3617 glMatrixMode(GL_MODELVIEW); |
3617 glMatrixMode(GL_MODELVIEW); |
3618 glPushMatrix(); |
3618 glPushMatrix(); |
3619 glLoadIdentity(); |
3619 glLoadIdentity(); |
3620 |
3620 |
3621 int j = 0; |
3621 int j = 0; |
3622 for (int i = 0; i < pointCount; ++i) { |
3622 for (int i = 0; i < pointCount; ++i) { |
3623 QPointF mapped = d->matrix.map(points[i]); |
3623 QPointF mapped = d->matrix.map(points[i]); |
3624 |
3624 |
3625 qreal xf = qRound(mapped.x()); |
3625 GLfloat x = GLfloat(qRound(mapped.x())); |
3626 qreal yf = qRound(mapped.y()); |
3626 GLfloat y = GLfloat(qRound(mapped.y())); |
3627 |
|
3628 q_vertexType x = f2vt(xf); |
|
3629 q_vertexType y = f2vt(yf); |
|
3630 |
3627 |
3631 vertexArray[j++] = x; |
3628 vertexArray[j++] = x; |
3632 vertexArray[j++] = y - f2vt(0.5); |
3629 vertexArray[j++] = y - 0.5f; |
3633 |
3630 |
3634 vertexArray[j++] = x + f2vt(1.5); |
3631 vertexArray[j++] = x + 1.5f; |
3635 vertexArray[j++] = y + f2vt(1.0); |
3632 vertexArray[j++] = y + 1.0f; |
3636 |
3633 |
3637 vertexArray[j++] = x; |
3634 vertexArray[j++] = x; |
3638 vertexArray[j++] = y + f2vt(1.0); |
3635 vertexArray[j++] = y + 1.0f; |
3639 } |
3636 } |
3640 |
3637 |
3641 glEnableClientState(GL_VERTEX_ARRAY); |
3638 glEnableClientState(GL_VERTEX_ARRAY); |
3642 |
3639 |
3643 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); |
3640 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); |
3644 glDrawArrays(GL_TRIANGLES, 0, pointCount*3); |
3641 glDrawArrays(GL_TRIANGLES, 0, pointCount*3); |
3645 |
3642 |
3646 glDisableClientState(GL_VERTEX_ARRAY); |
3643 glDisableClientState(GL_VERTEX_ARRAY); |
3647 |
3644 |
3648 glPopMatrix(); |
3645 glPopMatrix(); |
3655 Q_ASSERT(sizeof(QPointF) == 16); |
3652 Q_ASSERT(sizeof(QPointF) == 16); |
3656 glVertexPointer(2, GL_DOUBLE, 0, vertexArray); |
3653 glVertexPointer(2, GL_DOUBLE, 0, vertexArray); |
3657 } |
3654 } |
3658 else { |
3655 else { |
3659 Q_ASSERT(sizeof(QPointF) == 8); |
3656 Q_ASSERT(sizeof(QPointF) == 8); |
3660 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
3657 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
3661 } |
3658 } |
3662 |
3659 |
3663 glEnableClientState(GL_VERTEX_ARRAY); |
3660 glEnableClientState(GL_VERTEX_ARRAY); |
3664 glDrawArrays(GL_POINTS, 0, pointCount); |
3661 glDrawArrays(GL_POINTS, 0, pointCount); |
3665 glDisableClientState(GL_VERTEX_ARRAY); |
3662 glDisableClientState(GL_VERTEX_ARRAY); |
3723 break; |
3720 break; |
3724 } |
3721 } |
3725 } |
3722 } |
3726 } |
3723 } |
3727 |
3724 |
3728 q_vertexType endCap = f2vt(d->cpen.capStyle() == Qt::FlatCap ? 0 : 0.5); |
3725 GLfloat endCap = d->cpen.capStyle() == Qt::FlatCap ? 0.0f : 0.5f; |
3729 if (useRects) { |
3726 if (useRects) { |
3730 QVarLengthArray<q_vertexType> vertexArray(12 * lineCount); |
3727 QVarLengthArray<GLfloat> vertexArray(12 * lineCount); |
3731 |
3728 |
3732 q_vertexType quad[8]; |
3729 GLfloat quad[8]; |
3733 for (int i = 0; i < lineCount; ++i) { |
3730 for (int i = 0; i < lineCount; ++i) { |
3734 q_vertexType x1 = f2vt(lines[i].x1()); |
3731 GLfloat x1 = lines[i].x1(); |
3735 q_vertexType x2 = f2vt(lines[i].x2()); |
3732 GLfloat x2 = lines[i].x2(); |
3736 q_vertexType y1 = f2vt(lines[i].y1()); |
3733 GLfloat y1 = lines[i].y1(); |
3737 q_vertexType y2 = f2vt(lines[i].y2()); |
3734 GLfloat y2 = lines[i].y2(); |
3738 |
3735 |
3739 if (x1 == x2) { |
3736 if (x1 == x2) { |
3740 if (y1 > y2) |
3737 if (y1 > y2) |
3741 qSwap(y1, y2); |
3738 qSwap(y1, y2); |
3742 |
3739 |
3743 quad[0] = x1 - f2vt(0.5); |
3740 quad[0] = x1 - 0.5f; |
3744 quad[1] = y1 - endCap; |
3741 quad[1] = y1 - endCap; |
3745 |
3742 |
3746 quad[2] = x1 + f2vt(0.5); |
3743 quad[2] = x1 + 0.5f; |
3747 quad[3] = y1 - endCap; |
3744 quad[3] = y1 - endCap; |
3748 |
3745 |
3749 quad[4] = x1 + f2vt(0.5); |
3746 quad[4] = x1 + 0.5f; |
3750 quad[5] = y2 + endCap; |
3747 quad[5] = y2 + endCap; |
3751 |
3748 |
3752 quad[6] = x1 - f2vt(0.5); |
3749 quad[6] = x1 - 0.5f; |
3753 quad[7] = y2 + endCap; |
3750 quad[7] = y2 + endCap; |
3754 } else { |
3751 } else { |
3755 if (x1 > x2) |
3752 if (x1 > x2) |
3756 qSwap(x1, x2); |
3753 qSwap(x1, x2); |
3757 |
3754 |
3758 quad[0] = x1 - endCap; |
3755 quad[0] = x1 - endCap; |
3759 quad[1] = y1 + f2vt(0.5); |
3756 quad[1] = y1 + 0.5f; |
3760 |
3757 |
3761 quad[2] = x1 - endCap; |
3758 quad[2] = x1 - endCap; |
3762 quad[3] = y1 - f2vt(0.5); |
3759 quad[3] = y1 - 0.5f; |
3763 |
3760 |
3764 quad[4] = x2 + endCap; |
3761 quad[4] = x2 + endCap; |
3765 quad[5] = y1 - f2vt(0.5); |
3762 quad[5] = y1 - 0.5f; |
3766 |
3763 |
3767 quad[6] = x2 + endCap; |
3764 quad[6] = x2 + endCap; |
3768 quad[7] = y1 + f2vt(0.5); |
3765 quad[7] = y1 + 0.5f; |
3769 } |
3766 } |
3770 |
3767 |
3771 addQuadAsTriangle(quad, &vertexArray[12*i]); |
3768 addQuadAsTriangle(quad, &vertexArray[12*i]); |
3772 } |
3769 } |
3773 |
3770 |
3774 glEnableClientState(GL_VERTEX_ARRAY); |
3771 glEnableClientState(GL_VERTEX_ARRAY); |
3775 |
3772 |
3776 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); |
3773 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); |
3777 glDrawArrays(GL_TRIANGLES, 0, lineCount*6); |
3774 glDrawArrays(GL_TRIANGLES, 0, lineCount*6); |
3778 |
3775 |
3779 glDisableClientState(GL_VERTEX_ARRAY); |
3776 glDisableClientState(GL_VERTEX_ARRAY); |
3780 } else { |
3777 } else { |
3781 QVarLengthArray<q_vertexType> vertexArray(4 * lineCount); |
3778 QVarLengthArray<GLfloat> vertexArray(4 * lineCount); |
3782 for (int i = 0; i < lineCount; ++i) { |
3779 for (int i = 0; i < lineCount; ++i) { |
3783 const QPointF a = lines[i].p1(); |
3780 const QPointF a = lines[i].p1(); |
3784 vertexArray[4*i] = f2vt(lines[i].x1()); |
3781 vertexArray[4*i] = lines[i].x1(); |
3785 vertexArray[4*i+1] = f2vt(lines[i].y1()); |
3782 vertexArray[4*i+1] = lines[i].y1(); |
3786 vertexArray[4*i+2] = f2vt(lines[i].x2()); |
3783 vertexArray[4*i+2] = lines[i].x2(); |
3787 vertexArray[4*i+3] = f2vt(lines[i].y2()); |
3784 vertexArray[4*i+3] = lines[i].y2(); |
3788 } |
3785 } |
3789 |
3786 |
3790 glEnableClientState(GL_VERTEX_ARRAY); |
3787 glEnableClientState(GL_VERTEX_ARRAY); |
3791 |
3788 |
3792 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); |
3789 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); |
3793 glDrawArrays(GL_LINES, 0, lineCount*2); |
3790 glDrawArrays(GL_LINES, 0, lineCount*2); |
3794 |
3791 |
3795 glVertexPointer(2, q_vertexTypeEnum, 4*sizeof(q_vertexType), vertexArray.constData() + 2); |
3792 glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), vertexArray.constData() + 2); |
3796 glDrawArrays(GL_POINTS, 0, lineCount); |
3793 glDrawArrays(GL_POINTS, 0, lineCount); |
3797 |
3794 |
3798 glDisableClientState(GL_VERTEX_ARRAY); |
3795 glDisableClientState(GL_VERTEX_ARRAY); |
3799 } |
3796 } |
3800 } else { |
3797 } else { |
3877 Q_ASSERT(sizeof(QPointF) == 16); |
3874 Q_ASSERT(sizeof(QPointF) == 16); |
3878 glVertexPointer(2, GL_DOUBLE, 0, vertexArray); |
3875 glVertexPointer(2, GL_DOUBLE, 0, vertexArray); |
3879 } |
3876 } |
3880 else { |
3877 else { |
3881 Q_ASSERT(sizeof(QPointF) == 8); |
3878 Q_ASSERT(sizeof(QPointF) == 8); |
3882 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
3879 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
3883 } |
3880 } |
3884 |
3881 |
3885 glEnableClientState(GL_VERTEX_ARRAY); |
3882 glEnableClientState(GL_VERTEX_ARRAY); |
3886 glDrawArrays(GL_TRIANGLE_FAN, 0, pointCount); |
3883 glDrawArrays(GL_TRIANGLE_FAN, 0, pointCount); |
3887 glDisableClientState(GL_VERTEX_ARRAY); |
3884 glDisableClientState(GL_VERTEX_ARRAY); |
3896 } |
3893 } |
3897 |
3894 |
3898 if (d->has_pen) { |
3895 if (d->has_pen) { |
3899 if (d->has_fast_pen && !d->high_quality_antialiasing) { |
3896 if (d->has_fast_pen && !d->high_quality_antialiasing) { |
3900 d->setGradientOps(d->cpen.brush(), bounds); |
3897 d->setGradientOps(d->cpen.brush(), bounds); |
3901 QVarLengthArray<q_vertexType> vertexArray(pointCount*2 + 2); |
3898 QVarLengthArray<GLfloat> vertexArray(pointCount*2 + 2); |
3902 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData()); |
3899 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); |
3903 int i; |
3900 int i; |
3904 for (i=0; i<pointCount; ++i) { |
3901 for (i=0; i<pointCount; ++i) { |
3905 vertexArray[i*2] = f2vt(points[i].x()); |
3902 vertexArray[i*2] = points[i].x(); |
3906 vertexArray[i*2+1] = f2vt(points[i].y()); |
3903 vertexArray[i*2+1] = points[i].y(); |
3907 } |
3904 } |
3908 |
3905 |
3909 glEnableClientState(GL_VERTEX_ARRAY); |
3906 glEnableClientState(GL_VERTEX_ARRAY); |
3910 if (mode != PolylineMode) { |
3907 if (mode != PolylineMode) { |
3911 vertexArray[i*2] = vertexArray[0]; |
3908 vertexArray[i*2] = vertexArray[0]; |
4077 for (int i=0; i<path.elementCount(); ++i) { |
4074 for (int i=0; i<path.elementCount(); ++i) { |
4078 const QPainterPath::Element &e = path.elementAt(i); |
4075 const QPainterPath::Element &e = path.elementAt(i); |
4079 switch (e.type) { |
4076 switch (e.type) { |
4080 case QPainterPath::MoveToElement: |
4077 case QPainterPath::MoveToElement: |
4081 if (i != 0) { |
4078 if (i != 0) { |
4082 glVertexPointer(2, q_vertexTypeEnum, 0, tess_points.data()); |
4079 glVertexPointer(2, GL_FLOAT, 0, tess_points.data()); |
4083 glDrawArrays(GL_LINE_STRIP, 0, tess_points.size()); |
4080 glDrawArrays(GL_LINE_STRIP, 0, tess_points.size()); |
4084 tess_points.reset(); |
4081 tess_points.reset(); |
4085 } |
4082 } |
4086 tess_points.add(QPointF(e.x, e.y)); |
4083 tess_points.add(QPointF(e.x, e.y)); |
4087 |
4084 |
4394 glPushMatrix(); |
4391 glPushMatrix(); |
4395 glRotatef(180.0, 0.0, 1.0, 0.0); |
4392 glRotatef(180.0, 0.0, 1.0, 0.0); |
4396 glRotatef(180.0, 0.0, 0.0, 1.0); |
4393 glRotatef(180.0, 0.0, 0.0, 1.0); |
4397 } |
4394 } |
4398 |
4395 |
4399 q_vertexType vertexArray[4*2]; |
4396 GLfloat vertexArray[4*2]; |
4400 q_vertexType texCoordArray[4*2]; |
4397 GLfloat texCoordArray[4*2]; |
4401 |
4398 |
4402 double offset_x = offset.x() / pm.width(); |
4399 double offset_x = offset.x() / pm.width(); |
4403 double offset_y = offset.y() / pm.height(); |
4400 double offset_y = offset.y() / pm.height(); |
4404 |
4401 |
4405 qt_add_rect_to_array(r, vertexArray); |
4402 qt_add_rect_to_array(r, vertexArray); |
4406 qt_add_texcoords_to_array(offset_x, offset_y, |
4403 qt_add_texcoords_to_array(offset_x, offset_y, |
4407 tc_w + offset_x, tc_h + offset_y, texCoordArray); |
4404 tc_w + offset_x, tc_h + offset_y, texCoordArray); |
4408 |
4405 |
4409 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
4406 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
4410 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); |
4407 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); |
4411 |
4408 |
4412 glEnableClientState(GL_VERTEX_ARRAY); |
4409 glEnableClientState(GL_VERTEX_ARRAY); |
4413 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
4410 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
4414 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
4411 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
4415 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
4412 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
4486 x2 = sr.right(); |
4483 x2 = sr.right(); |
4487 y1 = sr.bottom(); |
4484 y1 = sr.bottom(); |
4488 y2 = sr.y(); |
4485 y2 = sr.y(); |
4489 } |
4486 } |
4490 |
4487 |
4491 q_vertexType vertexArray[4*2]; |
4488 GLfloat vertexArray[4*2]; |
4492 q_vertexType texCoordArray[4*2]; |
4489 GLfloat texCoordArray[4*2]; |
4493 |
4490 |
4494 qt_add_rect_to_array(r, vertexArray); |
4491 qt_add_rect_to_array(r, vertexArray); |
4495 qt_add_texcoords_to_array(x1, y2, x2, y1, texCoordArray); |
4492 qt_add_texcoords_to_array(x1, y2, x2, y1, texCoordArray); |
4496 |
4493 |
4497 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
4494 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
4498 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); |
4495 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); |
4499 |
4496 |
4500 glEnableClientState(GL_VERTEX_ARRAY); |
4497 glEnableClientState(GL_VERTEX_ARRAY); |
4501 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
4498 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
4502 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
4499 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
4503 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
4500 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
4747 } else { |
4744 } else { |
4748 font_cache = dev_it.value(); |
4745 font_cache = dev_it.value(); |
4749 } |
4746 } |
4750 Q_ASSERT(font_cache != 0); |
4747 Q_ASSERT(font_cache != 0); |
4751 |
4748 |
4752 QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(ti.fontEngine); |
4749 QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(fontEngine); |
4753 QGLGlyphHash *cache = 0; |
4750 QGLGlyphHash *cache = 0; |
4754 if (cache_it == font_cache->constEnd()) { |
4751 if (cache_it == font_cache->constEnd()) { |
4755 cache = new QGLGlyphHash; |
4752 cache = new QGLGlyphHash; |
4756 font_cache->insert(ti.fontEngine, cache); |
4753 font_cache->insert(fontEngine, cache); |
4757 connect(ti.fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*))); |
4754 connect(fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*))); |
4758 } else { |
4755 } else { |
4759 cache = cache_it.value(); |
4756 cache = cache_it.value(); |
4760 } |
4757 } |
4761 current_cache = cache; |
4758 current_cache = cache; |
4762 |
4759 |
4763 quint64 font_key = (reinterpret_cast<quint64>(context_key ? context_key : context) << 32) |
4760 quint64 font_key = (reinterpret_cast<quint64>(context_key ? context_key : context) << 32) |
4764 | reinterpret_cast<quint64>(ti.fontEngine); |
4761 | reinterpret_cast<quint64>(fontEngine); |
4765 QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key); |
4762 QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key); |
4766 QGLFontTexture *font_tex; |
4763 QGLFontTexture *font_tex; |
4767 if (it == qt_font_textures.constEnd()) { |
4764 if (it == qt_font_textures.constEnd()) { |
4768 GLuint font_texture; |
4765 GLuint font_texture; |
4769 glGenTextures(1, &font_texture); |
4766 glGenTextures(1, &font_texture); |
4770 GLint tex_height = qt_next_power_of_two(qRound(ti.ascent.toReal() + ti.descent.toReal())+2); |
4767 GLint tex_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2); |
4771 GLint tex_width = qt_next_power_of_two(tex_height*30); // ### |
4768 GLint tex_width = qt_next_power_of_two(tex_height*30); // ### |
4772 GLint max_tex_size; |
4769 GLint max_tex_size; |
4773 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); |
4770 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); |
4774 Q_ASSERT(max_tex_size > 0); |
4771 Q_ASSERT(max_tex_size > 0); |
4775 if (tex_width > max_tex_size) |
4772 if (tex_width > max_tex_size) |
4787 } else { |
4784 } else { |
4788 font_tex = it.value(); |
4785 font_tex = it.value(); |
4789 glBindTexture(GL_TEXTURE_2D, font_tex->texture); |
4786 glBindTexture(GL_TEXTURE_2D, font_tex->texture); |
4790 } |
4787 } |
4791 |
4788 |
4792 for (int i=0; i< glyphs.size(); ++i) { |
4789 for (int i=0; i< numGlyphs; ++i) { |
4793 QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]); |
4790 QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]); |
4794 if (it == cache->constEnd()) { |
4791 if (it == cache->constEnd()) { |
4795 // render new glyph and put it in the cache |
4792 // render new glyph and put it in the cache |
4796 glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]); |
4793 glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]); |
4797 int glyph_width = qRound(metrics.width.toReal())+2; |
4794 int glyph_width = qRound(metrics.width.toReal())+2; |
4798 int glyph_height = qRound(ti.ascent.toReal() + ti.descent.toReal())+2; |
4795 int glyph_height = qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2; |
4799 |
4796 |
4800 if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) { |
4797 if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) { |
4801 int strip_height = qt_next_power_of_two(qRound(ti.ascent.toReal() + ti.descent.toReal())+2); |
4798 int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2); |
4802 font_tex->x_offset = x_margin; |
4799 font_tex->x_offset = x_margin; |
4803 font_tex->y_offset += strip_height; |
4800 font_tex->y_offset += strip_height; |
4804 if (font_tex->y_offset >= font_tex->height) { |
4801 if (font_tex->y_offset >= font_tex->height) { |
4805 // get hold of the old font texture |
4802 // get hold of the old font texture |
4806 uchar *old_tex_data = (uchar *) malloc(font_tex->width*font_tex->height*2); |
4803 uchar *old_tex_data = (uchar *) malloc(font_tex->width*font_tex->height*2); |
4909 void qgl_cleanup_glyph_cache(QGLContext *ctx) |
4906 void qgl_cleanup_glyph_cache(QGLContext *ctx) |
4910 { |
4907 { |
4911 qt_glyph_cache()->cleanupContext(ctx); |
4908 qt_glyph_cache()->cleanupContext(ctx); |
4912 } |
4909 } |
4913 |
4910 |
|
4911 void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) |
|
4912 { |
|
4913 Q_D(QOpenGLPaintEngine); |
|
4914 |
|
4915 d->flushDrawQueue(); |
|
4916 |
|
4917 // make sure the glyphs we want to draw are in the cache |
|
4918 qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine, textItem->glyphs, |
|
4919 textItem->numGlyphs); |
|
4920 |
|
4921 d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops |
|
4922 qt_glColor4ubv(d->pen_color); |
|
4923 glEnable(GL_TEXTURE_2D); |
|
4924 |
|
4925 #ifdef Q_WS_QWS |
|
4926 // XXX: it is necessary to disable alpha writes on GLES/embedded because we don't want |
|
4927 // text rendering to update the alpha in the window surface. |
|
4928 // XXX: This may not be needed as this behavior does seem to be caused by driver bug |
|
4929 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); |
|
4930 #endif |
|
4931 |
|
4932 // do the actual drawing |
|
4933 GLfloat vertexArray[4*2]; |
|
4934 GLfloat texCoordArray[4*2]; |
|
4935 |
|
4936 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
|
4937 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); |
|
4938 |
|
4939 glEnableClientState(GL_VERTEX_ARRAY); |
|
4940 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
4941 bool antialias = !(textItem->fontEngine->fontDef.styleStrategy & QFont::NoAntialias) |
|
4942 && (d->matrix.type() > QTransform::TxTranslate); |
|
4943 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST); |
|
4944 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST); |
|
4945 |
|
4946 for (int i=0; i< textItem->numGlyphs; ++i) { |
|
4947 QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine, textItem->glyphs[i]); |
|
4948 |
|
4949 // we don't cache glyphs with no width/height |
|
4950 if (!g) |
|
4951 continue; |
|
4952 |
|
4953 qreal x1, x2, y1, y2; |
|
4954 x1 = g->x; |
|
4955 y1 = g->y; |
|
4956 x2 = x1 + g->width; |
|
4957 y2 = y1 + g->height; |
|
4958 |
|
4959 QPointF logical_pos((textItem->glyphPositions[i].x - g->x_offset).toReal(), |
|
4960 (textItem->glyphPositions[i].y + g->y_offset).toReal()); |
|
4961 |
|
4962 qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray); |
|
4963 qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray); |
|
4964 |
|
4965 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
|
4966 } |
|
4967 |
|
4968 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
4969 glDisableClientState(GL_VERTEX_ARRAY); |
|
4970 |
|
4971 glDisable(GL_TEXTURE_2D); |
|
4972 |
|
4973 #ifdef Q_WS_QWS |
|
4974 // XXX: This may not be needed as this behavior does seem to be caused by driver bug |
|
4975 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
4976 #endif |
|
4977 |
|
4978 } |
|
4979 |
4914 void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) |
4980 void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) |
4915 { |
4981 { |
4916 Q_D(QOpenGLPaintEngine); |
4982 Q_D(QOpenGLPaintEngine); |
4917 |
4983 |
4918 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); |
4984 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); |
4923 && d->pen_brush_style <= Qt::ConicalGradientPattern)) { |
4989 && d->pen_brush_style <= Qt::ConicalGradientPattern)) { |
4924 QPaintEngine::drawTextItem(p, textItem); |
4990 QPaintEngine::drawTextItem(p, textItem); |
4925 return; |
4991 return; |
4926 } |
4992 } |
4927 |
4993 |
4928 d->flushDrawQueue(); |
|
4929 |
|
4930 // add the glyphs used to the glyph texture cache |
4994 // add the glyphs used to the glyph texture cache |
4931 QVarLengthArray<QFixedPoint> positions; |
4995 QVarLengthArray<QFixedPoint> positions; |
4932 QVarLengthArray<glyph_t> glyphs; |
4996 QVarLengthArray<glyph_t> glyphs; |
4933 QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y())); |
4997 QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y())); |
4934 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); |
4998 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); |
4935 |
4999 |
4936 // make sure the glyphs we want to draw are in the cache |
5000 { |
4937 qt_glyph_cache()->cacheGlyphs(d->device->context(), ti, glyphs); |
5001 QStaticTextItem staticTextItem; |
4938 |
5002 staticTextItem.chars = ti.chars; |
4939 d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops |
5003 staticTextItem.fontEngine = ti.fontEngine; |
4940 qt_glColor4ubv(d->pen_color); |
5004 staticTextItem.glyphs = glyphs.data(); |
4941 glEnable(GL_TEXTURE_2D); |
5005 staticTextItem.numChars = ti.num_chars; |
4942 |
5006 staticTextItem.numGlyphs = glyphs.size(); |
4943 #ifdef Q_WS_QWS |
5007 staticTextItem.glyphPositions = positions.data(); |
4944 // XXX: it is necessary to disable alpha writes on GLES/embedded because we don't want |
5008 drawStaticTextItem(&staticTextItem); |
4945 // text rendering to update the alpha in the window surface. |
5009 } |
4946 // XXX: This may not be needed as this behavior does seem to be caused by driver bug |
5010 |
4947 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); |
|
4948 #endif |
|
4949 |
|
4950 // do the actual drawing |
|
4951 q_vertexType vertexArray[4*2]; |
|
4952 q_vertexType texCoordArray[4*2]; |
|
4953 |
|
4954 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
|
4955 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); |
|
4956 |
|
4957 glEnableClientState(GL_VERTEX_ARRAY); |
|
4958 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
4959 bool antialias = !(ti.fontEngine->fontDef.styleStrategy & QFont::NoAntialias) |
|
4960 && (d->matrix.type() > QTransform::TxTranslate); |
|
4961 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST); |
|
4962 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST); |
|
4963 |
|
4964 for (int i=0; i< glyphs.size(); ++i) { |
|
4965 QGLGlyphCoord *g = qt_glyph_cache()->lookup(ti.fontEngine, glyphs[i]); |
|
4966 |
|
4967 // we don't cache glyphs with no width/height |
|
4968 if (!g) |
|
4969 continue; |
|
4970 |
|
4971 qreal x1, x2, y1, y2; |
|
4972 x1 = g->x; |
|
4973 y1 = g->y; |
|
4974 x2 = x1 + g->width; |
|
4975 y2 = y1 + g->height; |
|
4976 |
|
4977 QPointF logical_pos((positions[i].x - g->x_offset).toReal(), |
|
4978 (positions[i].y + g->y_offset).toReal()); |
|
4979 |
|
4980 qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray); |
|
4981 qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray); |
|
4982 |
|
4983 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
|
4984 } |
|
4985 |
|
4986 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
4987 glDisableClientState(GL_VERTEX_ARRAY); |
|
4988 |
|
4989 glDisable(GL_TEXTURE_2D); |
|
4990 |
|
4991 #ifdef Q_WS_QWS |
|
4992 // XXX: This may not be needed as this behavior does seem to be caused by driver bug |
|
4993 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
4994 #endif |
|
4995 } |
5011 } |
4996 |
5012 |
4997 |
5013 |
4998 void QOpenGLPaintEngine::drawEllipse(const QRectF &rect) |
5014 void QOpenGLPaintEngine::drawEllipse(const QRectF &rect) |
4999 { |
5015 { |
5163 { |
5179 { |
5164 #ifdef Q_WS_QWS |
5180 #ifdef Q_WS_QWS |
5165 Q_UNUSED(rect); |
5181 Q_UNUSED(rect); |
5166 Q_UNUSED(maskOffset); |
5182 Q_UNUSED(maskOffset); |
5167 #else |
5183 #else |
5168 q_vertexType vertexArray[8]; |
5184 GLfloat vertexArray[8]; |
5169 qt_add_rect_to_array(rect, vertexArray); |
5185 qt_add_rect_to_array(rect, vertexArray); |
5170 |
5186 |
5171 composite(GL_TRIANGLE_FAN, vertexArray, 4, maskOffset); |
5187 composite(GL_TRIANGLE_FAN, vertexArray, 4, maskOffset); |
5172 #endif |
5188 #endif |
5173 } |
5189 } |
5174 |
5190 |
5175 |
5191 |
5176 void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType *vertexArray, int vertexCount, const QPoint &maskOffset) |
5192 void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset) |
5177 { |
5193 { |
5178 #ifdef QT_OPENGL_ES |
5194 #ifdef QT_OPENGL_ES |
5179 Q_UNUSED(primitive); |
5195 Q_UNUSED(primitive); |
5180 Q_UNUSED(vertexArray); |
5196 Q_UNUSED(vertexArray); |
5181 Q_UNUSED(vertexCount); |
5197 Q_UNUSED(vertexCount); |
5194 q->updateCompositionMode(composition_mode); |
5210 q->updateCompositionMode(composition_mode); |
5195 else { |
5211 else { |
5196 qreal minX = 1e9, minY = 1e9, maxX = -1e9, maxY = -1e9; |
5212 qreal minX = 1e9, minY = 1e9, maxX = -1e9, maxY = -1e9; |
5197 |
5213 |
5198 for (int i = 0; i < vertexCount; ++i) { |
5214 for (int i = 0; i < vertexCount; ++i) { |
5199 qreal x = vt2f(vertexArray[2 * i]); |
5215 qreal x = vertexArray[2 * i]; |
5200 qreal y = vt2f(vertexArray[2 * i + 1]); |
5216 qreal y = vertexArray[2 * i + 1]; |
5201 |
5217 |
5202 qreal tx, ty; |
5218 qreal tx, ty; |
5203 matrix.map(x, y, &tx, &ty); |
5219 matrix.map(x, y, &tx, &ty); |
5204 |
5220 |
5205 minX = qMin(minX, tx); |
5221 minX = qMin(minX, tx); |
5254 |
5270 |
5255 updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, use_smooth_pixmap_transform); |
5271 updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, use_smooth_pixmap_transform); |
5256 } |
5272 } |
5257 |
5273 |
5258 glEnableClientState(GL_VERTEX_ARRAY); |
5274 glEnableClientState(GL_VERTEX_ARRAY); |
5259 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
5275 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
5260 glEnable(GL_FRAGMENT_PROGRAM_ARB); |
5276 glEnable(GL_FRAGMENT_PROGRAM_ARB); |
5261 GLuint program = qt_gl_program_cache()->getProgram(device->context(), |
5277 GLuint program = qt_gl_program_cache()->getProgram(device->context(), |
5262 fragment_brush, |
5278 fragment_brush, |
5263 fragment_composition_mode, false); |
5279 fragment_composition_mode, false); |
5264 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program); |
5280 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program); |