diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2011-04-14 10:23:42 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-04-14 10:23:42 (GMT) |
commit | b56444d86aa449e2da15d9b9fd08001f09ac9b25 (patch) | |
tree | 171f6c0be5cc1c2935f15757630c8583bf0b2dd9 /src/gui/painting | |
parent | 5f68933c9adbf2dc1d6150d5771c8443395d6780 (diff) | |
parent | 662174b78b7e08c759d0086e215e81e9e0eaf0c5 (diff) | |
download | Qt-b56444d86aa449e2da15d9b9fd08001f09ac9b25.zip Qt-b56444d86aa449e2da15d9b9fd08001f09ac9b25.tar.gz Qt-b56444d86aa449e2da15d9b9fd08001f09ac9b25.tar.bz2 |
Merge remote-tracking branch 'origin/master' into lighthouse-master
Diffstat (limited to 'src/gui/painting')
34 files changed, 489 insertions, 445 deletions
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index e5d8abc..42c1c35 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -588,7 +588,7 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up return; } - if (!windowSurface->hasPartialUpdateSupport()) { + if (!windowSurface->hasFeature(QWindowSurface::PartialUpdates)) { fullUpdatePending = true; sendUpdateRequest(tlw, updateImmediately); return; @@ -683,7 +683,7 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool upd return; } - if (!windowSurface->hasPartialUpdateSupport()) { + if (!windowSurface->hasFeature(QWindowSurface::PartialUpdates)) { fullUpdatePending = true; sendUpdateRequest(tlw, updateImmediately); return; @@ -1143,9 +1143,9 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg return; } - // If there's no partial update support we always need + // If there's no preserved contents support we always need // to do a full repaint before flushing - if (!windowSurface->hasPartialUpdateSupport()) + if (!windowSurface->hasFeature(QWindowSurface::PreservedContents)) fullUpdatePending = true; // Nothing to repaint. diff --git a/src/gui/painting/qbackingstore_p.h b/src/gui/painting/qbackingstore_p.h index 47387ab..05f4bfc 100644 --- a/src/gui/painting/qbackingstore_p.h +++ b/src/gui/painting/qbackingstore_p.h @@ -262,7 +262,7 @@ private: } inline bool hasStaticContents() const - { return !staticWidgets.isEmpty() && windowSurface->hasStaticContentsSupport(); } + { return !staticWidgets.isEmpty() && windowSurface->hasFeature(QWindowSurface::StaticContents); } friend QRegion qt_dirtyRegion(QWidget *); friend class QWidgetPrivate; diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp index 119cf1c..a2f0edd 100644 --- a/src/gui/painting/qbezier.cpp +++ b/src/gui/painting/qbezier.cpp @@ -65,13 +65,6 @@ QT_BEGIN_NAMESPACE #define M_SQRT2 1.41421356237309504880 #endif -#define log2(x) (qLn(x)/qLn(2.)) - -static inline qreal log4(qreal x) -{ - return qreal(0.5) * log2(x); -} - /*! \internal */ @@ -184,7 +177,7 @@ static inline bool findInflections(qreal a, qreal b, qreal c, *t2 = r1; } if (!qFuzzyIsNull(a)) - *tCups = 0.5 * (-b / a); + *tCups = qreal(0.5) * (-b / a); else *tCups = 2; @@ -274,8 +267,8 @@ static ShiftResult good_offset(const QBezier *b1, const QBezier *b2, qreal offse const qreal o2 = offset*offset; const qreal max_dist_line = threshold*offset*offset; const qreal max_dist_normal = threshold*offset; - const qreal spacing = 0.25; - for (qreal i = spacing; i < 0.99; i += spacing) { + const qreal spacing = qreal(0.25); + for (qreal i = spacing; i < qreal(0.99); i += spacing) { QPointF p1 = b1->pointAt(i); QPointF p2 = b2->pointAt(i); qreal d = (p1.x() - p2.x())*(p1.x() - p2.x()) + (p1.y() - p2.y())*(p1.y() - p2.y()); @@ -284,7 +277,7 @@ static ShiftResult good_offset(const QBezier *b1, const QBezier *b2, qreal offse QPointF normalPoint = b1->normalVector(i); qreal l = qAbs(normalPoint.x()) + qAbs(normalPoint.y()); - if (l != 0.) { + if (l != qreal(0.0)) { d = qAbs( normalPoint.x()*(p1.y() - p2.y()) - normalPoint.y()*(p1.x() - p2.x()) ) / l; if (d > max_dist_normal) return Split; @@ -350,7 +343,7 @@ static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qr QPointF normal_sum = prev_normal + next_normal; - qreal r = 1.0 + prev_normal.x() * next_normal.x() + qreal r = qreal(1.0) + prev_normal.x() * next_normal.x() + prev_normal.y() * next_normal.y(); if (qFuzzyIsNull(r)) { @@ -374,7 +367,7 @@ static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qr // This value is used to determine the length of control point vectors // when approximating arc segments as curves. The factor is multiplied // with the radius of the circle. -#define KAPPA 0.5522847498 +#define KAPPA qreal(0.5522847498) static bool addCircle(const QBezier *b, qreal offset, QBezier *o) @@ -417,11 +410,11 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o) QPointF circle[3]; circle[0] = QPointF(b->x1, b->y1) + normals[0]*offset; - circle[1] = QPointF(0.5*(b->x1 + b->x4), 0.5*(b->y1 + b->y4)) + normals[1]*offset; + circle[1] = QPointF(qreal(0.5)*(b->x1 + b->x4), qreal(0.5)*(b->y1 + b->y4)) + normals[1]*offset; circle[2] = QPointF(b->x4, b->y4) + normals[2]*offset; for (int i = 0; i < 2; ++i) { - qreal kappa = 2.*KAPPA * sign * offset * angles[i]; + qreal kappa = qreal(2.0) * KAPPA * sign * offset * angles[i]; o->x1 = circle[i].x(); o->y1 = circle[i].y(); @@ -456,8 +449,8 @@ redo: while (b >= beziers) { int stack_segments = b - beziers + 1; if ((stack_segments == 10) || (o - curveSegments == maxSegments - stack_segments)) { - threshold *= 1.5; - if (threshold > 2.) + threshold *= qreal(1.5); + if (threshold > qreal(2.0)) goto give_up; goto redo; } @@ -535,7 +528,7 @@ static inline void splitBezierAt(const QBezier &bez, qreal t, qreal QBezier::length(qreal error) const { - qreal length = 0.0; + qreal length = qreal(0.0); addIfClose(&length, error); @@ -546,8 +539,8 @@ void QBezier::addIfClose(qreal *length, qreal error) const { QBezier left, right; /* bez poly splits */ - qreal len = 0.0; /* arc length */ - qreal chord; /* chord length */ + qreal len = qreal(0.0); /* arc length */ + qreal chord; /* chord length */ len = len + QLineF(QPointF(x1, y1),QPointF(x2, y2)).length(); len = len + QLineF(QPointF(x2, y2),QPointF(x3, y3)).length(); @@ -589,7 +582,7 @@ qreal QBezier::tForY(qreal t0, qreal t1, qreal y) const qreal lt = t0; qreal dt; do { - qreal t = 0.5 * (t0 + t1); + qreal t = qreal(0.5) * (t0 + t1); qreal a, b, c, d; QBezier::coefficients(t, a, b, c, d); @@ -604,7 +597,7 @@ qreal QBezier::tForY(qreal t0, qreal t1, qreal y) const } dt = lt - t; lt = t; - } while (qAbs(dt) > 1e-7); + } while (qAbs(dt) > qreal(1e-7)); return t0; } @@ -661,15 +654,15 @@ int QBezier::stationaryYPoints(qreal &t0, qreal &t1) const qreal QBezier::tAtLength(qreal l) const { qreal len = length(); - qreal t = 1.0; - const qreal error = (qreal)0.01; + qreal t = qreal(1.0); + const qreal error = qreal(0.01); if (l > len || qFuzzyCompare(l, len)) return t; - t *= 0.5; + t *= qreal(0.5); //int iters = 0; //qDebug()<<"LEN is "<<l<<len; - qreal lastBigger = 1.; + qreal lastBigger = qreal(1.0); while (1) { //qDebug()<<"\tt is "<<t; QBezier right = *this; @@ -680,10 +673,10 @@ qreal QBezier::tAtLength(qreal l) const break; if (lLen < l) { - t += (lastBigger - t)*.5; + t += (lastBigger - t) * qreal(0.5); } else { lastBigger = t; - t -= t*.5; + t -= t * qreal(0.5); } //++iters; } diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h index 8aff912..81f8b70 100644 --- a/src/gui/painting/qblendfunctions_p.h +++ b/src/gui/painting/qblendfunctions_p.h @@ -275,8 +275,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y); int dx_l = int(leftSlope * 0x10000); int dx_r = int(rightSlope * 0x10000); - int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000); - int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000); + int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000); + int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000); int fromX, toX, x1, x2, u, v, i, ii; DestT *line; @@ -471,8 +471,8 @@ void qt_transform_image(DestT *destPixels, int dbpl, int dvdx = int(m21 * 0x10000); int dudy = int(m12 * 0x10000); int dvdy = int(m22 * 0x10000); - int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1; - int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1; + int u0 = qCeil((qreal(0.5) * m11 + qreal(0.5) * m12 + mdx) * 0x10000) - 1; + int v0 = qCeil((qreal(0.5) * m21 + qreal(0.5) * m22 + mdy) * 0x10000) - 1; int x1 = qFloor(sourceRect.left()); int y1 = qFloor(sourceRect.top()); diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 811f3ae..bf5764a 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -49,6 +49,7 @@ #include "qdebug.h" #include <QtCore/qcoreapplication.h> #include "private/qstylehelper_p.h" +#include <QtCore/qnumeric.h> QT_BEGIN_NAMESPACE @@ -1369,13 +1370,14 @@ QGradient::QGradient() void QGradient::setColorAt(qreal pos, const QColor &color) { - if (pos > 1 || pos < 0) { + if ((pos > 1 || pos < 0) && !qIsNaN(pos)) { qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1"); return; } int index = 0; - while (index < m_stops.size() && m_stops.at(index).first < pos) ++index; + if (!qIsNaN(pos)) + while (index < m_stops.size() && m_stops.at(index).first < pos) ++index; if (index < m_stops.size() && m_stops.at(index).first == pos) m_stops[index].second = color; @@ -1785,7 +1787,7 @@ static QPointF qt_radial_gradient_adapt_focal_point(const QPointF ¢er, // We have a one pixel buffer zone to avoid numerical instability on the // circle border //### this is hacky because technically we should adjust based on current matrix - const qreal compensated_radius = radius - radius * 0.001; + const qreal compensated_radius = radius - radius * qreal(0.001); QLineF line(center, focalPoint); if (line.length() > (compensated_radius)) line.setLength(compensated_radius); diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 73a6ed8..ff6c24e 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -629,7 +629,7 @@ void QColor::getHsvF(qreal *h, qreal *s, qreal *v, qreal *a) const return; } - *h = ct.ahsv.hue == USHRT_MAX ? -1.0 : ct.ahsv.hue / 36000.0; + *h = ct.ahsv.hue == USHRT_MAX ? qreal(-1.0) : ct.ahsv.hue / qreal(36000.0); *s = ct.ahsv.saturation / qreal(USHRT_MAX); *v = ct.ahsv.value / qreal(USHRT_MAX); @@ -676,17 +676,17 @@ void QColor::getHsv(int *h, int *s, int *v, int *a) const */ void QColor::setHsvF(qreal h, qreal s, qreal v, qreal a) { - if (((h < 0.0 || h > 1.0) && h != -1.0) - || (s < 0.0 || s > 1.0) - || (v < 0.0 || v > 1.0) - || (a < 0.0 || a > 1.0)) { + if (((h < qreal(0.0) || h > qreal(1.0)) && h != qreal(-1.0)) + || (s < qreal(0.0) || s > qreal(1.0)) + || (v < qreal(0.0) || v > qreal(1.0)) + || (a < qreal(0.0) || a > qreal(1.0))) { qWarning("QColor::setHsvF: HSV parameters out of range"); return; } cspec = Hsv; ct.ahsv.alpha = qRound(a * USHRT_MAX); - ct.ahsv.hue = h == -1.0 ? USHRT_MAX : qRound(h * 36000); + ct.ahsv.hue = h == qreal(-1.0) ? USHRT_MAX : qRound(h * 36000); ct.ahsv.saturation = qRound(s * USHRT_MAX); ct.ahsv.value = qRound(v * USHRT_MAX); ct.ahsv.pad = 0; @@ -740,7 +740,7 @@ void QColor::getHslF(qreal *h, qreal *s, qreal *l, qreal *a) const return; } - *h = ct.ahsl.hue == USHRT_MAX ? -1.0 : ct.ahsl.hue / 36000.0; + *h = ct.ahsl.hue == USHRT_MAX ? qreal(-1.0) : ct.ahsl.hue / qreal(36000.0); *s = ct.ahsl.saturation / qreal(USHRT_MAX); *l = ct.ahsl.lightness / qreal(USHRT_MAX); @@ -790,17 +790,17 @@ void QColor::getHsl(int *h, int *s, int *l, int *a) const */ void QColor::setHslF(qreal h, qreal s, qreal l, qreal a) { - if (((h < 0.0 || h > 1.0) && h != -1.0) - || (s < 0.0 || s > 1.0) - || (l < 0.0 || l > 1.0) - || (a < 0.0 || a > 1.0)) { + if (((h < qreal(0.0) || h > qreal(1.0)) && h != qreal(-1.0)) + || (s < qreal(0.0) || s > qreal(1.0)) + || (l < qreal(0.0) || l > qreal(1.0)) + || (a < qreal(0.0) || a > qreal(1.0))) { qWarning("QColor::setHsvF: HSV parameters out of range"); return; } cspec = Hsl; ct.ahsl.alpha = qRound(a * USHRT_MAX); - ct.ahsl.hue = h == -1.0 ? USHRT_MAX : qRound(h * 36000); + ct.ahsl.hue = h == qreal(-1.0) ? USHRT_MAX : qRound(h * 36000); ct.ahsl.saturation = qRound(s * USHRT_MAX); ct.ahsl.lightness = qRound(l * USHRT_MAX); ct.ahsl.pad = 0; @@ -909,10 +909,10 @@ void QColor::getRgb(int *r, int *g, int *b, int *a) const */ void QColor::setRgbF(qreal r, qreal g, qreal b, qreal a) { - if (r < 0.0 || r > 1.0 - || g < 0.0 || g > 1.0 - || b < 0.0 || b > 1.0 - || a < 0.0 || a > 1.0) { + if (r < qreal(0.0) || r > qreal(1.0) + || g < qreal(0.0) || g > qreal(1.0) + || b < qreal(0.0) || b > qreal(1.0) + || a < qreal(0.0) || a > qreal(1.0)) { qWarning("QColor::setRgbF: RGB parameters out of range"); invalidate(); return; @@ -1322,7 +1322,7 @@ qreal QColor::hsvHueF() const { if (cspec != Invalid && cspec != Hsv) return toHsv().hueF(); - return ct.ahsv.hue == USHRT_MAX ? -1.0 : ct.ahsv.hue / 36000.0; + return ct.ahsv.hue == USHRT_MAX ? qreal(-1.0) : ct.ahsv.hue / qreal(36000.0); } /*! @@ -1418,7 +1418,7 @@ qreal QColor::hslHueF() const { if (cspec != Invalid && cspec != Hsl) return toHsl().hslHueF(); - return ct.ahsl.hue == USHRT_MAX ? -1.0 : ct.ahsl.hue / 36000.0; + return ct.ahsl.hue == USHRT_MAX ? qreal(-1.0) : ct.ahsl.hue / qreal(36000.0); } /*! @@ -1584,10 +1584,10 @@ QColor QColor::toRgb() const const qreal v = ct.ahsv.value / qreal(USHRT_MAX); const int i = int(h); const qreal f = h - i; - const qreal p = v * (1.0 - s); + const qreal p = v * (qreal(1.0) - s); if (i & 1) { - const qreal q = v * (1.0 - (s * f)); + const qreal q = v * (qreal(1.0) - (s * f)); switch (i) { case 1: @@ -1607,7 +1607,7 @@ QColor QColor::toRgb() const break; } } else { - const qreal t = v * (1.0 - (s * (1.0 - f))); + const qreal t = v * (qreal(1.0) - (s * (qreal(1.0) - f))); switch (i) { case 0: @@ -1683,9 +1683,9 @@ QColor QColor::toRgb() const const qreal y = ct.acmyk.yellow / qreal(USHRT_MAX); const qreal k = ct.acmyk.black / qreal(USHRT_MAX); - color.ct.argb.red = qRound((1.0 - (c * (1.0 - k) + k)) * USHRT_MAX); - color.ct.argb.green = qRound((1.0 - (m * (1.0 - k) + k)) * USHRT_MAX); - color.ct.argb.blue = qRound((1.0 - (y * (1.0 - k) + k)) * USHRT_MAX); + color.ct.argb.red = qRound((qreal(1.0) - (c * (qreal(1.0) - k) + k)) * USHRT_MAX); + color.ct.argb.green = qRound((qreal(1.0) - (m * (qreal(1.0) - k) + k)) * USHRT_MAX); + color.ct.argb.blue = qRound((qreal(1.0) - (y * (qreal(1.0) - k) + k)) * USHRT_MAX); break; } default: @@ -1737,15 +1737,15 @@ QColor QColor::toHsv() const if (qFuzzyCompare(r, max)) { hue = ((g - b) /delta); } else if (qFuzzyCompare(g, max)) { - hue = (2.0 + (b - r) / delta); + hue = (qreal(2.0) + (b - r) / delta); } else if (qFuzzyCompare(b, max)) { - hue = (4.0 + (r - g) / delta); + hue = (qreal(4.0) + (r - g) / delta); } else { Q_ASSERT_X(false, "QColor::toHsv", "internal error"); } - hue *= 60.0; - if (hue < 0.0) - hue += 360.0; + hue *= qreal(60.0); + if (hue < qreal(0.0)) + hue += qreal(360.0); color.ct.ahsv.hue = qRound(hue * 100); } @@ -1793,15 +1793,15 @@ QColor QColor::toHsl() const if (qFuzzyCompare(r, max)) { hue = ((g - b) /delta); } else if (qFuzzyCompare(g, max)) { - hue = (2.0 + (b - r) / delta); + hue = (qreal(2.0) + (b - r) / delta); } else if (qFuzzyCompare(b, max)) { - hue = (4.0 + (r - g) / delta); + hue = (qreal(4.0) + (r - g) / delta); } else { Q_ASSERT_X(false, "QColor::toHsv", "internal error"); } - hue *= 60.0; - if (hue < 0.0) - hue += 360.0; + hue *= qreal(60.0); + if (hue < qreal(0.0)) + hue += qreal(360.0); color.ct.ahsl.hue = qRound(hue * 100); } @@ -1829,17 +1829,17 @@ QColor QColor::toCmyk() const const qreal r = ct.argb.red / qreal(USHRT_MAX); const qreal g = ct.argb.green / qreal(USHRT_MAX); const qreal b = ct.argb.blue / qreal(USHRT_MAX); - qreal c = 1.0 - r; - qreal m = 1.0 - g; - qreal y = 1.0 - b; + qreal c = qreal(1.0) - r; + qreal m = qreal(1.0) - g; + qreal y = qreal(1.0) - b; // cmy -> cmyk const qreal k = qMin(c, qMin(m, y)); if (!qFuzzyIsNull(k - 1)) { - c = (c - k) / (1.0 - k); - m = (m - k) / (1.0 - k); - y = (y - k) / (1.0 - k); + c = (c - k) / (qreal(1.0) - k); + m = (m - k) / (qreal(1.0) - k); + y = (y - k) / (qreal(1.0) - k); } color.ct.acmyk.cyan = qRound(c * USHRT_MAX); @@ -1942,10 +1942,10 @@ QColor QColor::fromRgb(int r, int g, int b, int a) */ QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a) { - if (r < 0.0 || r > 1.0 - || g < 0.0 || g > 1.0 - || b < 0.0 || b > 1.0 - || a < 0.0 || a > 1.0) { + if (r < qreal(0.0) || r > qreal(1.0) + || g < qreal(0.0) || g > qreal(1.0) + || b < qreal(0.0) || b > qreal(1.0) + || a < qreal(0.0) || a > qreal(1.0)) { qWarning("QColor::fromRgbF: RGB parameters out of range"); return QColor(); } @@ -2005,10 +2005,10 @@ QColor QColor::fromHsv(int h, int s, int v, int a) */ QColor QColor::fromHsvF(qreal h, qreal s, qreal v, qreal a) { - if (((h < 0.0 || h > 1.0) && h != -1.0) - || (s < 0.0 || s > 1.0) - || (v < 0.0 || v > 1.0) - || (a < 0.0 || a > 1.0)) { + if (((h < qreal(0.0) || h > qreal(1.0)) && h != qreal(-1.0)) + || (s < qreal(0.0) || s > qreal(1.0)) + || (v < qreal(0.0) || v > qreal(1.0)) + || (a < qreal(0.0) || a > qreal(1.0))) { qWarning("QColor::fromHsvF: HSV parameters out of range"); return QColor(); } @@ -2016,7 +2016,7 @@ QColor QColor::fromHsvF(qreal h, qreal s, qreal v, qreal a) QColor color; color.cspec = Hsv; color.ct.ahsv.alpha = qRound(a * USHRT_MAX); - color.ct.ahsv.hue = h == -1.0 ? USHRT_MAX : qRound(h * 36000); + color.ct.ahsv.hue = h == qreal(-1.0) ? USHRT_MAX : qRound(h * 36000); color.ct.ahsv.saturation = qRound(s * USHRT_MAX); color.ct.ahsv.value = qRound(v * USHRT_MAX); color.ct.ahsv.pad = 0; @@ -2069,10 +2069,10 @@ QColor QColor::fromHsl(int h, int s, int l, int a) */ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a) { - if (((h < 0.0 || h > 1.0) && h != -1.0) - || (s < 0.0 || s > 1.0) - || (l < 0.0 || l > 1.0) - || (a < 0.0 || a > 1.0)) { + if (((h < qreal(0.0) || h > qreal(1.0)) && h != qreal(-1.0)) + || (s < qreal(0.0) || s > qreal(1.0)) + || (l < qreal(0.0) || l > qreal(1.0)) + || (a < qreal(0.0) || a > qreal(1.0))) { qWarning("QColor::fromHsvF: HSV parameters out of range"); return QColor(); } @@ -2080,7 +2080,7 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a) QColor color; color.cspec = Hsl; color.ct.ahsl.alpha = qRound(a * USHRT_MAX); - color.ct.ahsl.hue = (h == -1.0) ? USHRT_MAX : qRound(h * 36000); + color.ct.ahsl.hue = (h == qreal(-1.0)) ? USHRT_MAX : qRound(h * 36000); if (color.ct.ahsl.hue == 36000) color.ct.ahsl.hue = 0; color.ct.ahsl.saturation = qRound(s * USHRT_MAX); @@ -2189,11 +2189,11 @@ void QColor::setCmyk(int c, int m, int y, int k, int a) */ void QColor::setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a) { - if (c < 0.0 || c > 1.0 - || m < 0.0 || m > 1.0 - || y < 0.0 || y > 1.0 - || k < 0.0 || k > 1.0 - || a < 0.0 || a > 1.0) { + if (c < qreal(0.0) || c > qreal(1.0) + || m < qreal(0.0) || m > qreal(1.0) + || y < qreal(0.0) || y > qreal(1.0) + || k < qreal(0.0) || k > qreal(1.0) + || a < qreal(0.0) || a > qreal(1.0)) { qWarning("QColor::setCmykF: CMYK parameters out of range"); return; } @@ -2251,11 +2251,11 @@ QColor QColor::fromCmyk(int c, int m, int y, int k, int a) */ QColor QColor::fromCmykF(qreal c, qreal m, qreal y, qreal k, qreal a) { - if (c < 0.0 || c > 1.0 - || m < 0.0 || m > 1.0 - || y < 0.0 || y > 1.0 - || k < 0.0 || k > 1.0 - || a < 0.0 || a > 1.0) { + if (c < qreal(0.0) || c > qreal(1.0) + || m < qreal(0.0) || m > qreal(1.0) + || y < qreal(0.0) || y > qreal(1.0) + || k < qreal(0.0) || k > qreal(1.0) + || a < qreal(0.0) || a > qreal(1.0)) { qWarning("QColor::fromCmykF: CMYK parameters out of range"); return QColor(); } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5904296..5e75e4a 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -570,8 +570,8 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const int image_width = data->texture.width; int image_height = data->texture.height; - const qreal cx = x + 0.5; - const qreal cy = y + 0.5; + const qreal cx = x + qreal(0.5); + const qreal cy = y + qreal(0.5); const uint *end = buffer + length; uint *b = buffer; @@ -792,8 +792,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * int image_x2 = data->texture.x2 - 1; int image_y2 = data->texture.y2 - 1; - const qreal cx = x + 0.5; - const qreal cy = y + 0.5; + const qreal cx = x + qreal(0.5); + const qreal cy = y + qreal(0.5); uint *end = buffer + length; uint *b = buffer; @@ -1188,8 +1188,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * while (b < end) { const qreal iw = fw == 0 ? 1 : 1 / fw; - const qreal px = fx * iw - 0.5; - const qreal py = fy * iw - 0.5; + const qreal px = fx * iw - qreal(0.5); + const qreal py = fy * iw - qreal(0.5); int x1 = int(px) - (px < 0); int x2; @@ -1349,7 +1349,7 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) { - int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + 0.5); + int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); // calculate the actual offset. if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { @@ -1430,8 +1430,8 @@ static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator if (op->linear.l == 0) { t = inc = 0; } else { - rx = data->m21 * (y + 0.5) + data->m11 * (x + 0.5) + data->dx; - ry = data->m22 * (y + 0.5) + data->m12 * (x + 0.5) + data->dy; + rx = data->m21 * (y + qreal(0.5)) + data->m11 * (x + qreal(0.5)) + data->dx; + ry = data->m22 * (y + qreal(0.5)) + data->m12 * (x + qreal(0.5)) + data->dy; t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off; inc = op->linear.dx * data->m11 + op->linear.dy * data->m12; affine = !data->m13 && !data->m23; @@ -1444,7 +1444,7 @@ static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator const uint *end = buffer + length; if (affine) { - if (inc > -1e-5 && inc < 1e-5) { + if (inc > qreal(-1e-5) && inc < qreal(1e-5)) { QT_MEMFILL_UINT(buffer, length, qt_gradient_pixel_fixed(&data->gradient, int(t * FIXPT_SIZE))); } else { if (t+inc*length < qreal(INT_MAX >> (FIXPT_BITS + 1)) && @@ -1467,7 +1467,7 @@ static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator } } } else { // fall back to float math here as well - qreal rw = data->m23 * (y + 0.5) + data->m13 * (x + 0.5) + data->m33; + qreal rw = data->m23 * (y + qreal(0.5)) + data->m13 * (x + qreal(0.5)) + data->m33; while (buffer < end) { qreal x = rx/rw; qreal y = ry/rw; @@ -1514,10 +1514,10 @@ static const uint * QT_FASTCALL fetchRadialGradient(uint *buffer, const Operator int y, int x, int length) { const uint *b = buffer; - qreal rx = data->m21 * (y + 0.5) - + data->dx + data->m11 * (x + 0.5); - qreal ry = data->m22 * (y + 0.5) - + data->dy + data->m12 * (x + 0.5); + qreal rx = data->m21 * (y + qreal(0.5)) + + data->dx + data->m11 * (x + qreal(0.5)); + qreal ry = data->m22 * (y + qreal(0.5)) + + data->dy + data->m12 * (x + qreal(0.5)); bool affine = !data->m13 && !data->m23; //qreal r = data->gradient.radial.radius; @@ -1563,8 +1563,8 @@ static const uint * QT_FASTCALL fetchRadialGradient(uint *buffer, const Operator ++buffer; } } else { - qreal rw = data->m23 * (y + 0.5) - + data->m33 + data->m13 * (x + 0.5); + qreal rw = data->m23 * (y + qreal(0.5)) + + data->m33 + data->m13 * (x + qreal(0.5)); if (!rw) rw = 1; while (buffer < end) { @@ -1593,10 +1593,10 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato int y, int x, int length) { const uint *b = buffer; - qreal rx = data->m21 * (y + 0.5) - + data->dx + data->m11 * (x + 0.5); - qreal ry = data->m22 * (y + 0.5) - + data->dy + data->m12 * (x + 0.5); + qreal rx = data->m21 * (y + qreal(0.5)) + + data->dx + data->m11 * (x + qreal(0.5)); + qreal ry = data->m22 * (y + qreal(0.5)) + + data->dy + data->m12 * (x + qreal(0.5)); bool affine = !data->m13 && !data->m23; const uint *end = buffer + length; @@ -1613,8 +1613,8 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato ++buffer; } } else { - qreal rw = data->m23 * (y + 0.5) - + data->m33 + data->m13 * (x + 0.5); + qreal rw = data->m23 * (y + qreal(0.5)) + + data->m33 + data->m13 * (x + qreal(0.5)); if (!rw) rw = 1; while (buffer < end) { @@ -2819,7 +2819,7 @@ static inline int soft_light_op(int dst, int src, int da, int sa) # ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2 return (dst * sa * 255 + da * (src2 - sa) * (qIntSqrtInt(dst_np * 255) - dst_np) + temp) / 65025; # else - return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025; + return (dst * sa * 255 + da * (src2 - sa) * (int(qSqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025; # endif } } @@ -5928,8 +5928,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s uint *target = ((uint *)t) + spans->x; uint *image_bits = (uint *)data->texture.imageData; - const qreal cx = spans->x + 0.5; - const qreal cy = spans->y + 0.5; + const qreal cx = spans->x + qreal(0.5); + const qreal cy = spans->y + qreal(0.5); int x = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale); @@ -5976,8 +5976,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s uint *target = ((uint *)t) + spans->x; uint *image_bits = (uint *)data->texture.imageData; - const qreal cx = spans->x + 0.5; - const qreal cy = spans->y + 0.5; + const qreal cx = spans->x + qreal(0.5); + const qreal cy = spans->y + qreal(0.5); qreal x = data->m21 * cy + data->m11 * cx + data->dx; qreal y = data->m22 * cy + data->m12 * cx + data->dy; @@ -6328,8 +6328,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS uint *target = ((uint *)t) + spans->x; uint *image_bits = (uint *)data->texture.imageData; - const qreal cx = spans->x + 0.5; - const qreal cy = spans->y + 0.5; + const qreal cx = spans->x + qreal(0.5); + const qreal cy = spans->y + qreal(0.5); int x = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale); @@ -6380,8 +6380,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS uint *target = ((uint *)t) + spans->x; uint *image_bits = (uint *)data->texture.imageData; - const qreal cx = spans->x + 0.5; - const qreal cy = spans->y + 0.5; + const qreal cx = spans->x + qreal(0.5); + const qreal cy = spans->y + qreal(0.5); qreal x = data->m21 * cy + data->m11 * cx + data->dx; qreal y = data->m22 * cy + data->m12 * cx + data->dy; @@ -7067,7 +7067,7 @@ static void qt_gradient_quint32(int count, const QSpan *spans, void *userData) */ const int gss = GRADIENT_STOPTABLE_SIZE - 1; int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE); - int off = int((((linear.dy * (data->m22 * 0.5 + data->dy) + linear.off) * gss) * FIXPT_SIZE)); + int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE)); while (count--) { int y = spans->y; @@ -7115,7 +7115,7 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData) */ const int gss = GRADIENT_STOPTABLE_SIZE - 1; int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE); - int off = int((((linear.dy * (data->m22 * 0.5 + data->dy) + linear.off) * gss) * FIXPT_SIZE)); + int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE)); uint oldColor = data->solid.color; while (count--) { @@ -7194,17 +7194,17 @@ void qt_build_pow_tables() { #ifdef Q_WS_MAC // decided by testing a few things on an iMac, should probably get this from the // system... - smoothing = 2.0; + smoothing = qreal(2.0); #endif #ifdef Q_WS_WIN int winSmooth; if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) - smoothing = winSmooth / 1000.0; + smoothing = winSmooth / qreal(1000.0); // Safeguard ourselves against corrupt registry values... if (smoothing > 5 || smoothing < 1) - smoothing = 1.4; + smoothing = qreal(1.4); #endif @@ -7226,7 +7226,7 @@ void qt_build_pow_tables() { for (int i=0; i<256; ++i) qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047)); for (int i=0; i<2048; ++i) - qt_pow_invgamma[i] = uchar(qRound(qPow(i / 2047.0, 1 / gray_gamma) * 255)); + qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255)); #endif } diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 00b103d..debca37 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -327,10 +327,8 @@ void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, blend_8_pixels_argb32_on_rgb16_neon(dstBuffer, srcBuffer, const_alpha); - for (int j = 0; j < tail; ++j) { + for (int j = 0; j < tail; ++j) dst[i + j] = dstBuffer[j]; - src[i + j] = srcBuffer[j]; - } } dst = (quint16 *)(((uchar *) dst) + dbpl); diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp index 33652ee..d1dd7ef 100644 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -319,6 +319,11 @@ QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const return m_windowSurface->offset(widget); } +QWindowSurface::WindowSurfaceFeatures QRuntimeWindowSurface::features() const +{ + return m_windowSurface->features(); +} + QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() : m_windowSurfaceDestroyPolicy(DestroyImmediately), m_graphicsSystem(0) diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h index 30b4e3e..26d3777 100644 --- a/src/gui/painting/qgraphicssystem_runtime_p.h +++ b/src/gui/painting/qgraphicssystem_runtime_p.h @@ -129,6 +129,8 @@ public: virtual QPoint offset(const QWidget *widget) const; + virtual WindowSurfaceFeatures features() const; + QScopedPointer<QWindowSurface> m_windowSurface; QScopedPointer<QWindowSurface> m_pendingWindowSurface; diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 5605fc1..62a60d7 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -45,6 +45,7 @@ #include "qmutex.h" #include "qapplication.h" +#include <private/qapplication_p.h> #include "qgraphicssystem_raster_p.h" #include "qgraphicssystem_runtime_p.h" #include "qdebug.h" @@ -79,6 +80,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) } #endif + QApplicationPrivate::graphics_system_name = system; if (system == QLatin1String("raster")) return new QRasterGraphicsSystem; else if (system == QLatin1String("runtime")) diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index fac356c..dd4b3db 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -54,8 +54,6 @@ QT_BEGIN_NAMESPACE -Q_GUI_EXPORT extern int qt_defaultDpiX(); -Q_GUI_EXPORT extern int qt_defaultDpiY(); extern void qt_format_text(const QFont &font, const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, int tabstops, int* tabarray, int tabarraylen, diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/gui/painting/qpaintengine_alpha.cpp index 339a002..171850d 100644 --- a/src/gui/painting/qpaintengine_alpha.cpp +++ b/src/gui/painting/qpaintengine_alpha.cpp @@ -46,6 +46,7 @@ #include "private/qpaintengine_alpha_p.h" #include "private/qpicture_p.h" +#include "private/qfont_p.h" #include "QtGui/qpicture.h" QT_BEGIN_NAMESPACE @@ -93,9 +94,6 @@ bool QAlphaPaintEngine::begin(QPaintDevice *pdev) return true; } -Q_GUI_EXPORT extern int qt_defaultDpiX(); -Q_GUI_EXPORT extern int qt_defaultDpiY(); - bool QAlphaPaintEngine::end() { Q_D(QAlphaPaintEngine); diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp index 2f35dcd..8aab7c7 100644 --- a/src/gui/painting/qpaintengine_mac.cpp +++ b/src/gui/painting/qpaintengine_mac.cpp @@ -972,7 +972,7 @@ void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, co return; bool differentSize = (QRectF(0, 0, pm.width(), pm.height()) != sr), doRestore = false; - CGRect rect = CGRectMake(qRound(r.x()), qRound(r.y()), qRound(r.width()), qRound(r.height())); + CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height()); QCFType<CGImageRef> image; bool isBitmap = (pm.depth() == 1); if (isBitmap) { diff --git a/src/gui/painting/qpaintengine_mac_p.h b/src/gui/painting/qpaintengine_mac_p.h index 5c459ee..3e71d6c 100644 --- a/src/gui/painting/qpaintengine_mac_p.h +++ b/src/gui/painting/qpaintengine_mac_p.h @@ -57,15 +57,12 @@ #include "private/qt_mac_p.h" #include "private/qpaintengine_p.h" #include "private/qpolygonclipper_p.h" +#include "private/qfont_p.h" #include "QtCore/qhash.h" typedef struct CGColorSpace *CGColorSpaceRef; QT_BEGIN_NAMESPACE -extern int qt_defaultDpi(); -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); - class QCoreGraphicsPaintEnginePrivate; class QCoreGraphicsPaintEngine : public QPaintEngine { diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9242fb6..6902543 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3076,65 +3076,145 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx blend(current, spans, &s->penData); } -void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, +bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine) { Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); - QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType; +#if !defined(QT_NO_FREETYPE) + if (fontEngine->type() == QFontEngine::Freetype) { + QFontEngineFT *fe = static_cast<QFontEngineFT *>(fontEngine); + QFontEngineFT::GlyphFormat neededFormat = + painter()->device()->devType() == QInternal::Widget + ? fe->defaultGlyphFormat() + : QFontEngineFT::Format_A8; + + if (d_func()->mono_surface + || fe->isBitmapFont() // alphaPenBlt can handle mono, too + ) + neededFormat = QFontEngineFT::Format_Mono; + + if (neededFormat == QFontEngineFT::Format_None) + neededFormat = QFontEngineFT::Format_A8; + + QFontEngineFT::QGlyphSet *gset = fe->defaultGlyphs(); + if (s->matrix.type() >= QTransform::TxScale) { + if (s->matrix.isAffine()) + gset = fe->loadTransformedGlyphSet(s->matrix); + else + gset = 0; + } - QImageTextureGlyphCache *cache = - static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix)); - if (!cache) { - cache = new QImageTextureGlyphCache(glyphType, s->matrix); - fontEngine->setGlyphCache(0, cache); - } + if (!gset || gset->outline_drawing + || !fe->loadGlyphs(gset, glyphs, numGlyphs, positions, neededFormat)) + return false; - cache->populate(fontEngine, numGlyphs, glyphs, positions); - cache->fillInPendingGlyphs(); + FT_Face lockedFace = 0; - const QImage &image = cache->image(); - int bpl = image.bytesPerLine(); + int depth; + switch (neededFormat) { + case QFontEngineFT::Format_Mono: + depth = 1; + break; + case QFontEngineFT::Format_A8: + depth = 8; + break; + case QFontEngineFT::Format_A32: + depth = 32; + break; + default: + Q_ASSERT(false); + depth = 0; + }; - int depth = image.depth(); - int rightShift = 0; - int leftShift = 0; - if (depth == 32) - leftShift = 2; // multiply by 4 - else if (depth == 1) - rightShift = 3; // divide by 8 + for (int i = 0; i < numGlyphs; i++) { + QFixed spp = fe->subPixelPositionForX(positions[i].x); + QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i], spp); - int margin = cache->glyphMargin(); + if (!glyph || glyph->format != neededFormat) { + if (!lockedFace) + lockedFace = fe->lockFace(); + glyph = fe->loadGlyph(gset, glyphs[i], spp, neededFormat); + } - bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions(); + if (!glyph || !glyph->data) + continue; - const uchar *bits = image.bits(); - for (int i=0; i<numGlyphs; ++i) { + int pitch; + switch (neededFormat) { + case QFontEngineFT::Format_Mono: + pitch = ((glyph->width + 31) & ~31) >> 3; + break; + case QFontEngineFT::Format_A8: + pitch = (glyph->width + 3) & ~3; + break; + case QFontEngineFT::Format_A32: + pitch = glyph->width * 4; + break; + default: + Q_ASSERT(false); + pitch = 0; + }; + + alphaPenBlt(glyph->data, pitch, depth, + qFloor(positions[i].x) + glyph->x, + qFloor(positions[i].y) - glyph->y, + glyph->width, glyph->height); + } + if (lockedFace) + fe->unlockFace(); + } else +#endif + { + QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType; - QFixed subPixelPosition; - if (supportsSubPixelPositions) - subPixelPosition = cache->subPixelPositionForX(positions[i].x); - QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition); - const QTextureGlyphCache::Coord &c = cache->coords[glyph]; - if (c.isNull()) - continue; + QImageTextureGlyphCache *cache = + static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix)); + if (!cache) { + cache = new QImageTextureGlyphCache(glyphType, s->matrix); + fontEngine->setGlyphCache(0, cache); + } - int x = qFloor(positions[i].x) + c.baseLineX - margin; - int y = qFloor(positions[i].y) - c.baseLineY - margin; + cache->populate(fontEngine, numGlyphs, glyphs, positions); + cache->fillInPendingGlyphs(); -// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n", -// c.x, c.y, -// c.w, c.h, -// c.baseLineX, c.baseLineY, -// glyphs[i], -// x, y, -// positions[i].x.toInt(), positions[i].y.toInt()); + const QImage &image = cache->image(); + int bpl = image.bytesPerLine(); - alphaPenBlt(bits + ((c.x << leftShift) >> rightShift) + c.y * bpl, bpl, depth, x, y, c.w, c.h); - } + int depth = image.depth(); + int rightShift = 0; + int leftShift = 0; + if (depth == 32) + leftShift = 2; // multiply by 4 + else if (depth == 1) + rightShift = 3; // divide by 8 - return; + int margin = cache->glyphMargin(); + const uchar *bits = image.bits(); + for (int i=0; i<numGlyphs; ++i) { + + QFixed subPixelPosition = cache->subPixelPositionForX(positions[i].x); + QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition); + const QTextureGlyphCache::Coord &c = cache->coords[glyph]; + if (c.isNull()) + continue; + + int x = qFloor(positions[i].x) + c.baseLineX - margin; + int y = qFloor(positions[i].y) - c.baseLineY - margin; + + // printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n", + // c.x, c.y, + // c.w, c.h, + // c.baseLineX, c.baseLineY, + // glyphs[i], + // x, y, + // positions[i].x.toInt(), positions[i].y.toInt()); + + alphaPenBlt(bits + ((c.x << leftShift) >> rightShift) + c.y * bpl, bpl, depth, x, y, c.w, c.h); + } + } + return true; } #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) @@ -3445,91 +3525,10 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte if (glyphs.size() == 0) return; - // only use subpixel antialiasing when drawing to widgets - QFontEngineFT::GlyphFormat neededFormat = - painter()->device()->devType() == QInternal::Widget - ? fe->defaultGlyphFormat() - : QFontEngineFT::Format_A8; - - if (d_func()->mono_surface - || fe->isBitmapFont() // alphaPenBlt can handle mono, too - ) - neededFormat = QFontEngineFT::Format_Mono; - - if (neededFormat == QFontEngineFT::Format_None) - neededFormat = QFontEngineFT::Format_A8; - - QFontEngineFT::QGlyphSet *gset = fe->defaultGlyphs(); - if (s->matrix.type() >= QTransform::TxScale) { - if (s->matrix.isAffine()) - gset = fe->loadTransformedGlyphSet(s->matrix); - else - gset = 0; - - } - - if (!gset || gset->outline_drawing - || !fe->loadGlyphs(gset, glyphs.data(), glyphs.size(), neededFormat)) - { + if (!drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), fontEngine)) QPaintEngine::drawTextItem(p, ti); - return; - } - - FT_Face lockedFace = 0; - - int depth; - switch (neededFormat) { - case QFontEngineFT::Format_Mono: - depth = 1; - break; - case QFontEngineFT::Format_A8: - depth = 8; - break; - case QFontEngineFT::Format_A32: - depth = 32; - break; - default: - Q_ASSERT(false); - depth = 0; - }; - - for(int i = 0; i < glyphs.size(); i++) { - QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i]); - if (!glyph || glyph->format != neededFormat) { - if (!lockedFace) - lockedFace = fe->lockFace(); - glyph = fe->loadGlyph(gset, glyphs[i], neededFormat); - } - - if (!glyph || !glyph->data) - continue; - - int pitch; - switch (neededFormat) { - case QFontEngineFT::Format_Mono: - pitch = ((glyph->width + 31) & ~31) >> 3; - break; - case QFontEngineFT::Format_A8: - pitch = (glyph->width + 3) & ~3; - break; - case QFontEngineFT::Format_A32: - pitch = glyph->width * 4; - break; - default: - Q_ASSERT(false); - pitch = 0; - }; - - alphaPenBlt(glyph->data, pitch, depth, - qFloor(positions[i].x) + glyph->x, - qFloor(positions[i].y) - glyph->y, - glyph->width, glyph->height); - } - if (lockedFace) - fe->unlockFace(); return; - #endif #endif diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 7f902a8..52f51fa 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -261,7 +261,7 @@ private: void fillRect(const QRectF &rect, QSpanData *data); void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill); - void drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, + bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine); #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 8b71b83..94828fb 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -2385,7 +2385,7 @@ void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti) set = ft->loadTransformedGlyphSet(d->matrix); if (!set || set->outline_drawing - || !ft->loadGlyphs(set, glyphs.data(), glyphs.size(), QFontEngineFT::Format_Render)) + || !ft->loadGlyphs(set, glyphs.constData(), glyphs.size(), positions.constData(), QFontEngineFT::Format_Render)) { QPaintEngine::drawTextItem(p, ti); return; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 2c25e70..50d65e6 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6463,12 +6463,13 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setWidthF(fe->lineThickness().toReal()); pen.setCapStyle(Qt::FlatCap); - QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y()); + QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y()); const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset); + const qreal aliasedCoordinateDelta = 0.5 - 0.015625; + const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta; if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); @@ -8246,12 +8247,16 @@ start_lengthVariant: QTextLine line = textLayout.lineAt(i); qreal advance = line.horizontalAdvance(); - if (tf & Qt::AlignRight) - xoff = r.width() - advance; + xoff = 0; + if (tf & Qt::AlignRight) { + QTextEngine *eng = textLayout.engine(); + xoff = r.width() - advance - + eng->leadingSpaceWidth(eng->lines[line.lineNumber()]).toReal(); + } else if (tf & Qt::AlignHCenter) - xoff = (r.width() - advance)/2; + xoff = (r.width() - advance) / 2; - line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff)); + line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff)); } if (restore) { diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 49f1a5f..27aed32 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1897,39 +1897,39 @@ static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y return false; } -static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2) +static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2, int depth = 0) { QRectF bounds = bezier.bounds(); if (y >= bounds.top() && y < bounds.bottom() && bounds.right() >= x1 && bounds.left() < x2) { const qreal lower_bound = qreal(.01); - if (bounds.width() < lower_bound && bounds.height() < lower_bound) + if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound)) return true; QBezier first_half, second_half; bezier.split(&first_half, &second_half); - if (qt_isect_curve_horizontal(first_half, y, x1, x2) - || qt_isect_curve_horizontal(second_half, y, x1, x2)) + if (qt_isect_curve_horizontal(first_half, y, x1, x2, depth + 1) + || qt_isect_curve_horizontal(second_half, y, x1, x2, depth + 1)) return true; } return false; } -static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2) +static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2, int depth = 0) { QRectF bounds = bezier.bounds(); if (x >= bounds.left() && x < bounds.right() && bounds.bottom() >= y1 && bounds.top() < y2) { const qreal lower_bound = qreal(.01); - if (bounds.width() < lower_bound && bounds.height() < lower_bound) + if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound)) return true; QBezier first_half, second_half; bezier.split(&first_half, &second_half); - if (qt_isect_curve_vertical(first_half, x, y1, y2) - || qt_isect_curve_vertical(second_half, x, y1, y2)) + if (qt_isect_curve_vertical(first_half, x, y1, y2, depth + 1) + || qt_isect_curve_vertical(second_half, x, y1, y2, depth + 1)) return true; } return false; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index bc30038..0271a39 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -47,6 +47,7 @@ #include "private/qcups_p.h" #include "qprinterinfo.h" #include <qnumeric.h> +#include "private/qfont_p.h" #ifdef Q_OS_UNIX #include "private/qcore_unix_p.h" // overrides QT_OPEN @@ -54,8 +55,6 @@ QT_BEGIN_NAMESPACE -Q_GUI_EXPORT extern int qt_defaultDpi(); - #ifndef QT_NO_PRINTER extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size); diff --git a/src/gui/painting/qprintengine_mac.mm b/src/gui/painting/qprintengine_mac.mm index ec842a9..1dce303 100644 --- a/src/gui/painting/qprintengine_mac.mm +++ b/src/gui/painting/qprintengine_mac.mm @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size); -extern int qt_defaultDpi(); QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode) : QPaintEngine(*(new QMacPrintEnginePrivate)) { diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index e75c0f5..53f025f 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -102,7 +102,7 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const QFixed QTextureGlyphCache::subPixelPositionForX(QFixed x) const { - if (m_subPixelPositionCount == 0) + if (m_subPixelPositionCount <= 1) return QFixed(); QFixed subPixelPosition; @@ -134,9 +134,13 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const if (!supportsSubPixelPositions) { m_subPixelPositionCount = 1; } else { +#if !defined(Q_WS_X11) int i = 0; while (m_subPixelPositionCount == 0 && i < numGlyphs) m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]); +#else + m_subPixelPositionCount = 4; +#endif } } @@ -164,7 +168,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const continue; if (listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))) continue; - glyph_metrics_t metrics = fontEngine->alphaMapBoundingBox(glyph, m_transform, format); + glyph_metrics_t metrics = fontEngine->alphaMapBoundingBox(glyph, subPixelPosition, m_transform, format); #ifdef CACHE_DEBUG printf("(%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n", @@ -234,6 +238,11 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const } } + if (maxTextureHeight() > 0 && m_cy + c.h > maxTextureHeight()) { + // We can't make a cache of the required size, so we bail out + return false; + } + c.x = m_cx; c.y = m_cy; @@ -307,9 +316,11 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine); QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform); + QFixedPoint positions[1]; + positions[0].x = subPixelPosition; - if (gset && ft->loadGlyphs(gset, &g, 1, format)) { - QFontEngineFT::Glyph *glyph = gset->getGlyph(g); + if (gset && ft->loadGlyphs(gset, &g, 1, positions, format)) { + QFontEngineFT::Glyph *glyph = gset->getGlyph(g, subPixelPosition); const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3 : (glyph->width + 3) & ~3); return QImage(glyph->data, glyph->width, glyph->height, bytesPerLine, imageFormat); @@ -356,7 +367,7 @@ void QImageTextureGlyphCache::createTextureData(int width, int height) int QImageTextureGlyphCache::glyphMargin() const { -#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) +#if (defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) || defined(Q_WS_X11) return 0; #else return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 4441b30..7d11e2f 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1085,8 +1085,11 @@ QDebug operator<<(QDebug dbg, const QTransform &m) "TxNone", "TxTranslate", "TxScale", + 0, "TxRotate", + 0, 0, 0, "TxShear", + 0, 0, 0, 0, 0, 0, 0, "TxProject" }; diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp index e7434c7..3876c3d 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp +++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp @@ -55,7 +55,6 @@ QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget) { d_ptr->image = 0; d_ptr->inSetGeometry = false; - setStaticContentsSupport(true); setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height. } @@ -71,7 +70,7 @@ QPaintDevice *QUnifiedToolbarSurface::paintDevice() return &d_ptr->image->image; } -void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &offset) +void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, QWidget *parent_toolbar, const QPoint &offset) { if (object != 0) { if (object->isWidgetType()) { @@ -83,9 +82,10 @@ void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &of widget->d_func()->unifiedSurface = this; widget->d_func()->isInUnifiedToolbar = true; widget->d_func()->toolbar_offset = offset; + widget->d_func()->toolbar_ancestor = parent_toolbar; for (int i = 0; i < object->children().size(); ++i) { - recursiveRedirect(object->children().at(i), offset); + recursiveRedirect(object->children().at(i), parent_toolbar, offset); } } } @@ -95,7 +95,35 @@ void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &of void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset) { setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME - recursiveRedirect(toolbar, offset); + recursiveRedirect(toolbar, toolbar, offset); +} + +// We basically undo what we set in recursiveRedirect(). +void QUnifiedToolbarSurface::recursiveRemoval(QObject *object) +{ + if (object != 0) { + if (object->isWidgetType()) { + QWidget *widget = qobject_cast<QWidget *>(object); + + // If it's a pop-up or something similar, we don't redirect it. + if (widget->windowType() & Qt::Window) + return; + + widget->d_func()->unifiedSurface = 0; + widget->d_func()->isInUnifiedToolbar = false; + widget->d_func()->toolbar_offset = QPoint(); + widget->d_func()->toolbar_ancestor = 0; + } + + for (int i = 0; i < object->children().size(); ++i) { + recursiveRemoval(object->children().at(i)); + } + } +} + +void QUnifiedToolbarSurface::removeToolbar(QToolBar *toolbar) +{ + recursiveRemoval(toolbar); } void QUnifiedToolbarSurface::setGeometry(const QRect &rect) @@ -127,70 +155,25 @@ void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget) mlayout->updateUnifiedToolbarOffset(); } -void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) +void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { - Q_D(QUnifiedToolbarSurface); - - QRegion flushingRegion(widget->rect()); - - if (!d->image || rgn.rectCount() == 0) { - return; - } - + Q_UNUSED(region); Q_UNUSED(offset); - // Get a context for the widget. - CGContextRef context; - if (!(widget->d_func()->hasOwnContext)) { - widget->d_func()->ut_rg = rgn; - widget->d_func()->ut_pt = offset; - qt_mac_display(widget); - return; - } else { - // We render the content of the toolbar in the surface. - updateToolbarOffset(widget); - QRect beginPaintRect(widget->d_func()->toolbar_offset.x(), widget->d_func()->toolbar_offset.y(), widget->geometry().width(), widget->geometry().height()); - QRegion beginPaintRegion(beginPaintRect); - - context = widget->d_func()->cgContext; - beginPaint(beginPaintRegion); - widget->render(widget->d_func()->unifiedSurface->paintDevice(), widget->d_func()->toolbar_offset, QRegion(), QWidget::DrawChildren); - } + this->flush(widget); +} - CGContextSaveGState(context); +void QUnifiedToolbarSurface::flush(QWidget *widget) +{ + Q_D(QUnifiedToolbarSurface); - int areaX = widget->d_func()->toolbar_offset.x(); - int areaY = widget->d_func()->toolbar_offset.y(); - int areaWidth = widget->geometry().width(); - int areaHeight = widget->geometry().height(); - const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight); + if (!d->image) + return; - // Clip to region. - const QVector<QRect> &rects = flushingRegion.rects(); - for (int i = 0; i < rects.size(); ++i) { - const QRect &rect = rects.at(i); - CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); + if (widget->d_func()->flushRequested) { + // We call display: directly to avoid flickering in the toolbar. + qt_mac_display(widget); } - CGContextAddRect(context, area); - CGContextClip(context); - - - CGImageRef image = CGBitmapContextCreateImage(d->image->cg); - CGImageRef subImage = CGImageCreateWithImageInRect(image, area); - - const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight); - qt_mac_drawCGImage(context, &drawingArea, subImage); - - CGImageRelease(subImage); - CGImageRelease(image); - - CGContextFlush(context); - - // Restore context. - CGContextRestoreGState(context); - CGContextRelease(context); - widget->d_func()->cgContext = 0; - widget->d_func()->hasOwnContext = false; } void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget) @@ -198,7 +181,7 @@ void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widge Q_D(QUnifiedToolbarSurface); int width = geometry().width(); - int height = geometry().height(); + int height = 100; // FIXME if (d->image) { width = qMax(d->image->width(), width); height = qMax(d->image->height(), height); @@ -254,6 +237,28 @@ void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widge delete oldImage; } +CGContextRef QUnifiedToolbarSurface::imageContext() +{ + Q_D(QUnifiedToolbarSurface); + return d->image->cg; +} + +void QUnifiedToolbarSurface::renderToolbar(QWidget *widget, bool forceFlush) +{ + QWidget *toolbar = widget->d_func()->toolbar_ancestor; + + updateToolbarOffset(toolbar); + QRect beginPaintRect(toolbar->d_func()->toolbar_offset.x(), toolbar->d_func()->toolbar_offset.y(), toolbar->geometry().width(), toolbar->geometry().height()); + QRegion beginPaintRegion(beginPaintRect); + + beginPaint(beginPaintRegion); + toolbar->render(paintDevice(), toolbar->d_func()->toolbar_offset, QRegion(toolbar->geometry()), QWidget::DrawChildren); + toolbar->d_func()->flushRequested = true; + + if (forceFlush) + flush(toolbar); +} + QT_END_NAMESPACE #endif // QT_MAC_USE_COCOA diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h index e1157d7..0a7ebf1 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h +++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h @@ -55,6 +55,7 @@ #include <private/qwindowsurface_raster_p.h> #include <QWidget> +#include <QToolBar> #include <private/qwidget_p.h> #include <private/qnativeimage_p.h> @@ -78,16 +79,22 @@ public: QUnifiedToolbarSurface(QWidget *widget); ~QUnifiedToolbarSurface(); + void flush(QWidget *widget); void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); void setGeometry(const QRect &rect); void beginPaint(const QRegion &rgn); void insertToolbar(QWidget *toolbar, const QPoint &offset); + void removeToolbar(QToolBar *toolbar); + void updateToolbarOffset(QWidget *widget); + void renderToolbar(QWidget *widget, bool forceFlush = false); + void recursiveRedirect(QObject *widget, QWidget *parent_toolbar, const QPoint &offset); -private: QPaintDevice *paintDevice(); - void updateToolbarOffset(QWidget *widget); + CGContextRef imageContext(); + +private: void prepareBuffer(QImage::Format format, QWidget *widget); - void recursiveRedirect(QObject *widget, const QPoint &offset); + void recursiveRemoval(QObject *object); Q_DECLARE_PRIVATE(QUnifiedToolbarSurface) QScopedPointer<QUnifiedToolbarSurfacePrivate> d_ptr; diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index 029b9dc..0fb9bf7 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -52,8 +52,6 @@ class QWindowSurfacePrivate public: QWindowSurfacePrivate(QWidget *w) : window(w) - , staticContentsSupport(0) - , partialUpdateSupport(1) { } @@ -65,8 +63,6 @@ public: #endif //Q_WS_QPA QRegion staticContents; QList<QImage*> bufferImages; - uint staticContentsSupport : 1; - uint partialUpdateSupport : 1; }; /*! @@ -311,20 +307,6 @@ QPoint QWindowSurface::offset(const QWidget *widget) const window surface. */ -bool QWindowSurface::hasStaticContentsSupport() const -{ - return d_ptr->staticContentsSupport; -} - -void QWindowSurface::setStaticContentsSupport(bool enable) -{ - if (enable && !d_ptr->partialUpdateSupport) { - qWarning("QWindowSurface::setStaticContentsSupport: static contents support requires partial update support"); - return; - } - d_ptr->staticContentsSupport = enable; -} - void QWindowSurface::setStaticContents(const QRegion ®ion) { d_ptr->staticContents = region; @@ -337,21 +319,12 @@ QRegion QWindowSurface::staticContents() const bool QWindowSurface::hasStaticContents() const { - return d_ptr->staticContentsSupport && !d_ptr->staticContents.isEmpty(); -} - -bool QWindowSurface::hasPartialUpdateSupport() const -{ - return d_ptr->partialUpdateSupport; + return hasFeature(QWindowSurface::StaticContents) && !d_ptr->staticContents.isEmpty(); } -void QWindowSurface::setPartialUpdateSupport(bool enable) +QWindowSurface::WindowSurfaceFeatures QWindowSurface::features() const { - if (!enable && d_ptr->staticContentsSupport) { - qWarning("QWindowSurface::setPartialUpdateSupport: static contents support requires partial update support"); - return; - } - d_ptr->partialUpdateSupport = enable; + return PartialUpdates | PreservedContents; } #ifdef Q_WS_QPA diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h index 62137ef..a3fea67 100644 --- a/src/gui/painting/qwindowsurface_p.h +++ b/src/gui/painting/qwindowsurface_p.h @@ -68,6 +68,14 @@ class QPlatformWindow; class Q_GUI_EXPORT QWindowSurface { public: + enum WindowSurfaceFeature { + PartialUpdates = 0x00000001, // Supports doing partial updates. + PreservedContents = 0x00000002, // Supports doing flush without first doing a repaint. + StaticContents = 0x00000004, // Supports having static content regions when being resized. + AllFeatures = 0xffffffff // For convenience + }; + Q_DECLARE_FLAGS(WindowSurfaceFeatures, WindowSurfaceFeature) + QWindowSurface(QWidget *window, bool setDefaultSurface = true); virtual ~QWindowSurface(); @@ -100,26 +108,31 @@ public: virtual QPoint offset(const QWidget *widget) const; inline QRect rect(const QWidget *widget) const; - bool hasStaticContentsSupport() const; - bool hasPartialUpdateSupport() const; + bool hasFeature(WindowSurfaceFeature feature) const; + virtual WindowSurfaceFeatures features() const; void setStaticContents(const QRegion ®ion); QRegion staticContents() const; protected: bool hasStaticContents() const; - void setStaticContentsSupport(bool enable); - void setPartialUpdateSupport(bool enable); private: QWindowSurfacePrivate *d_ptr; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowSurface::WindowSurfaceFeatures) + inline QRect QWindowSurface::rect(const QWidget *widget) const { return widget->rect().translated(offset(widget)); } +inline bool QWindowSurface::hasFeature(WindowSurfaceFeature feature) const +{ + return (features() & feature) != 0; +} + QT_END_NAMESPACE #endif // QWINDOWSURFACE_P_H diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 419518ac..9860841 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -103,7 +103,11 @@ QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurfa #endif d_ptr->image = 0; d_ptr->inSetGeometry = false; - setStaticContentsSupport(true); + +#ifdef QT_MAC_USE_COCOA + needsFlush = false; + regionToFlush = QRegion(); +#endif // QT_MAC_USE_COCOA } @@ -272,41 +276,26 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi #ifdef Q_WS_MAC + Q_UNUSED(offset); + // This is mainly done for native components like native "open file" dialog. if (widget->testAttribute(Qt::WA_DontShowOnScreen)) { return; } #ifdef QT_MAC_USE_COCOA - // Unified toolbar hack. - QMainWindow* mWindow = qobject_cast<QMainWindow*>(widget->window()); - if (mWindow) { - QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout()); - QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList; - for (int i = 0; i < toolbarList.size(); ++i) { - QToolBar* toolbar = toolbarList.at(i); - if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) { - QWidget* tbWidget = (QWidget*) toolbar; - if (tbWidget->d_func()->unifiedSurface) { - tbWidget->d_func()->unifiedSurface->flush(tbWidget, rgn, offset); - } - } - } - } -#endif // QT_MAC_USE_COCOA + this->needsFlush = true; + this->regionToFlush += rgn; - Q_UNUSED(offset); + // The actual flushing will be processed in [view drawRect:rect] + qt_mac_setNeedsDisplay(widget); + +#else // Get a context for the widget. -#ifndef QT_MAC_USE_COCOA CGContextRef context; CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); QDBeginCGContext(port, &context); -#else - QMacCocoaAutoReleasePool pool; - extern CGContextRef qt_mac_graphicsContextFor(QWidget *); - CGContextRef context = qt_mac_graphicsContextFor(widget); -#endif CGContextRetain(context); CGContextSaveGState(context); @@ -332,16 +321,12 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi CGImageRelease(subImage); CGImageRelease(image); -#ifndef QT_MAC_USE_COCOA QDEndCGContext(port, &context); -#else - CGContextFlush(context); -#endif // Restore context. CGContextRestoreGState(context); CGContextRelease(context); - +#endif // QT_MAC_USE_COCOA #endif // Q_WS_MAC @@ -425,6 +410,10 @@ bool QRasterWindowSurface::scroll(const QRegion &area, int dx, int dy) #endif } +QWindowSurface::WindowSurfaceFeatures QRasterWindowSurface::features() const +{ + return QWindowSurface::AllFeatures; +} void QRasterWindowSurface::prepareBuffer(QImage::Format format, QWidget *widget) { @@ -487,4 +476,12 @@ void QRasterWindowSurface::prepareBuffer(QImage::Format format, QWidget *widget) delete oldImage; } +#ifdef QT_MAC_USE_COCOA +CGContextRef QRasterWindowSurface::imageContext() +{ + Q_D(QRasterWindowSurface); + return d->image->cg; +} +#endif // QT_MAC_USE_COCOA + QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h index 903810b..06abcd3 100644 --- a/src/gui/painting/qwindowsurface_raster_p.h +++ b/src/gui/painting/qwindowsurface_raster_p.h @@ -56,6 +56,10 @@ #include <qglobal.h> #include "private/qwindowsurface_p.h" +#ifdef QT_MAC_USE_COCOA +# include <private/qt_cocoa_helpers_mac_p.h> +#endif // QT_MAC_USE_COCOA + QT_BEGIN_NAMESPACE #ifdef Q_WS_WIN @@ -105,6 +109,14 @@ public: void beginPaint(const QRegion &rgn); void setGeometry(const QRect &rect); bool scroll(const QRegion &area, int dx, int dy); + WindowSurfaceFeatures features() const; + +#ifdef QT_MAC_USE_COCOA + CGContextRef imageContext(); + + bool needsFlush; + QRegion regionToFlush; +#endif // QT_MAC_USE_COCOA private: #if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index 71556d7..9fa01ed 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -63,7 +63,6 @@ struct QS60WindowSurfacePrivate TDisplayMode displayMode(bool opaque) { - TDisplayMode mode = S60->screenDevice()->DisplayMode(); if (opaque) { mode = EColor16MU; @@ -76,10 +75,18 @@ TDisplayMode displayMode(bool opaque) return mode; } +bool blitWriteAlpha(QWidgetPrivate *widgetPrivate) +{ + QWExtra *extra = widgetPrivate->extraData(); + return extra ? extra->nativePaintMode == QWExtra::BlitWriteAlpha : false; +} + QS60WindowSurface::QS60WindowSurface(QWidget* widget) : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate) { - TDisplayMode mode = displayMode(qt_widget_private(widget)->isOpaque); + QWidgetPrivate *widgetPrivate = qt_widget_private(widget); + const bool opaque = widgetPrivate->isOpaque && !blitWriteAlpha(widgetPrivate); + TDisplayMode mode = displayMode(opaque); // We create empty CFbsBitmap here -> it will be resized in setGeometry CFbsBitmap *bitmap = new CFbsBitmap; // CBase derived object needs check on new Q_CHECK_PTR(bitmap); @@ -90,8 +97,6 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget) data->fromSymbianBitmap(bitmap, true); d_ptr->device = QPixmap(data); } - - setStaticContentsSupport(true); } QS60WindowSurface::~QS60WindowSurface() @@ -124,7 +129,8 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn) S60->wsSession().Finish(); #endif - if (!qt_widget_private(window())->isOpaque) { + QWidgetPrivate *windowPrivate = qt_widget_private(window()); + if (!windowPrivate->isOpaque || blitWriteAlpha(windowPrivate)) { QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data()); TDisplayMode mode = displayMode(false); @@ -133,12 +139,14 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn) pixmapData->beginDataAccess(); - QPainter p(&pixmapData->image); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = rgn.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { - p.fillRect(*it, blank); + if (!windowPrivate->isOpaque) { + QPainter p(&pixmapData->image); + p.setCompositionMode(QPainter::CompositionMode_Source); + const QVector<QRect> rects = rgn.rects(); + const QColor blank = Qt::transparent; + for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { + p.fillRect(*it, blank); + } } pixmapData->endDataAccess(); @@ -231,6 +239,11 @@ void QS60WindowSurface::setGeometry(const QRect& rect) QWindowSurface::setGeometry(rect); } +QWindowSurface::WindowSurfaceFeatures QS60WindowSurface::features() const +{ + return QWindowSurface::AllFeatures; +} + CFbsBitmap* QS60WindowSurface::symbianBitmap() const { QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); diff --git a/src/gui/painting/qwindowsurface_s60_p.h b/src/gui/painting/qwindowsurface_s60_p.h index d0d4925..25018d8 100644 --- a/src/gui/painting/qwindowsurface_s60_p.h +++ b/src/gui/painting/qwindowsurface_s60_p.h @@ -79,6 +79,8 @@ public: void setGeometry(const QRect &rect); + WindowSurfaceFeatures features() const; + CFbsBitmap *symbianBitmap() const; private: diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp index 2324bc2..deb83b4 100644 --- a/src/gui/painting/qwindowsurface_x11.cpp +++ b/src/gui/painting/qwindowsurface_x11.cpp @@ -70,9 +70,6 @@ QX11WindowSurface::QX11WindowSurface(QWidget *widget) #ifndef QT_NO_XRENDER d_ptr->translucentBackground = X11->use_xrender && widget->x11Info().depth() == 32; - setStaticContentsSupport(!d_ptr->translucentBackground); -#else - setStaticContentsSupport(true); #endif } @@ -253,4 +250,16 @@ QPixmap QX11WindowSurface::grabWidget(const QWidget *widget, return px; } +QWindowSurface::WindowSurfaceFeatures QX11WindowSurface::features() const +{ + WindowSurfaceFeatures features = QWindowSurface::PartialUpdates | QWindowSurface::PreservedContents; +#ifndef QT_NO_XRENDER + if (!d_ptr->translucentBackground) + features |= QWindowSurface::StaticContents; +#else + features |= QWindowSurface::StaticContents; +#endif + return features; +} + QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_x11_p.h b/src/gui/painting/qwindowsurface_x11_p.h index 88753ea..df76f98 100644 --- a/src/gui/painting/qwindowsurface_x11_p.h +++ b/src/gui/painting/qwindowsurface_x11_p.h @@ -80,6 +80,8 @@ public: bool scroll(const QRegion &area, int dx, int dy); QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const; + WindowSurfaceFeatures features() const; + private: QX11WindowSurfacePrivate *d_ptr; GC gc; |