summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qbezier.cpp24
-rw-r--r--src/gui/painting/qcolor.cpp4
-rw-r--r--src/gui/painting/qdrawhelper.cpp1010
-rw-r--r--src/gui/painting/qmatrix.cpp63
-rw-r--r--src/gui/painting/qmatrix.h20
-rw-r--r--src/gui/painting/qpaintengine_alpha.cpp12
-rw-r--r--src/gui/painting/qpaintengine_alpha_p.h1
-rw-r--r--src/gui/painting/qpaintengine_d3d.cpp6
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp140
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp19
-rw-r--r--src/gui/painting/qpainter.cpp49
-rw-r--r--src/gui/painting/qpainterpath.cpp31
-rw-r--r--src/gui/painting/qpainterpath.h2
-rw-r--r--src/gui/painting/qpainterpath_p.h11
-rw-r--r--src/gui/painting/qpathclipper.cpp36
-rw-r--r--src/gui/painting/qpdf.cpp5
-rw-r--r--src/gui/painting/qprintengine_mac.mm66
-rw-r--r--src/gui/painting/qprintengine_mac_p.h1
-rw-r--r--src/gui/painting/qprintengine_win.cpp2
-rw-r--r--src/gui/painting/qprinter.cpp6
-rw-r--r--src/gui/painting/qregion.cpp22
-rw-r--r--src/gui/painting/qstroker.cpp12
-rw-r--r--src/gui/painting/qtessellator.cpp2
-rw-r--r--src/gui/painting/qtransform.cpp243
-rw-r--r--src/gui/painting/qtransform.h30
-rw-r--r--src/gui/painting/qwindowsurface.cpp7
27 files changed, 866 insertions, 960 deletions
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index 8317dd8..7ed521e 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -127,13 +127,13 @@ static inline void flattenBezierWithoutInflections(QBezier &bez,
qreal dy = bez.y2 - bez.y1;
qreal normalized = qSqrt(dx * dx + dy * dy);
- if (qFuzzyCompare(normalized + 1, 1))
+ if (qFuzzyIsNull(normalized))
break;
qreal d = qAbs(dx * (bez.y3 - bez.y2) - dy * (bez.x3 - bez.x2));
qreal t = qSqrt(4. / 3. * normalized * flatness / d);
- if (t > 1 || qFuzzyCompare(t, (qreal)1.))
+ if (t > 1 || qFuzzyIsNull(t - (qreal)1.))
break;
bez.parameterSplitLeft(t, &left);
p->append(bez.pt1());
@@ -144,19 +144,19 @@ static inline void flattenBezierWithoutInflections(QBezier &bez,
static inline int quadraticRoots(qreal a, qreal b, qreal c,
qreal *x1, qreal *x2)
{
- if (qFuzzyCompare(a + 1, 1)) {
- if (qFuzzyCompare(b + 1, 1))
+ if (qFuzzyIsNull(a)) {
+ if (qFuzzyIsNull(b))
return 0;
*x1 = *x2 = (-c / b);
return 1;
} else {
const qreal det = b * b - 4 * a * c;
- if (qFuzzyCompare(det + 1, 1)) {
+ if (qFuzzyIsNull(det)) {
*x1 = *x2 = -b / (2 * a);
return 1;
}
if (det > 0) {
- if (qFuzzyCompare(b + 1, 1)) {
+ if (qFuzzyIsNull(b)) {
*x2 = qSqrt(-c / a);
*x1 = -(*x2);
return 2;
@@ -187,7 +187,7 @@ static inline bool findInflections(qreal a, qreal b, qreal c,
*t1 = r2;
*t2 = r1;
}
- if (!qFuzzyCompare(a + 1, 1))
+ if (!qFuzzyIsNull(a))
*tCups = 0.5 * (-b / a);
else
*tCups = 2;
@@ -243,7 +243,7 @@ void QBezier::addToPolygonMixed(QPolygonF *polygon) const
qreal b = 6 * (ay * cx - ax * cy);
qreal c = 2 * (by * cx - bx * cy);
- if ((qFuzzyCompare(a + 1, 1) && qFuzzyCompare(b + 1, 1)) ||
+ if ((qFuzzyIsNull(a) && qFuzzyIsNull(b)) ||
(b * b - 4 * a *c) < 0) {
QBezier bez(*this);
flattenBezierWithoutInflections(bez, polygon);
@@ -447,7 +447,7 @@ static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qr
qreal r = 1.0 + prev_normal.x() * next_normal.x()
+ prev_normal.y() * next_normal.y();
- if (qFuzzyCompare(r + 1, 1)) {
+ if (qFuzzyIsNull(r)) {
points_shifted[i] = points[i] + offset * prev_normal;
} else {
qreal k = offset / r;
@@ -477,12 +477,12 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o)
normals[0] = QPointF(b->y2 - b->y1, b->x1 - b->x2);
qreal dist = qSqrt(normals[0].x()*normals[0].x() + normals[0].y()*normals[0].y());
- if (qFuzzyCompare(dist + 1, 1))
+ if (qFuzzyIsNull(dist))
return false;
normals[0] /= dist;
normals[2] = QPointF(b->y4 - b->y3, b->x3 - b->x4);
dist = qSqrt(normals[2].x()*normals[2].x() + normals[2].y()*normals[2].y());
- if (qFuzzyCompare(dist + 1, 1))
+ if (qFuzzyIsNull(dist))
return false;
normals[2] /= dist;
@@ -1022,7 +1022,7 @@ int QBezier::stationaryYPoints(qreal &t0, qreal &t1) const
QList<qreal> result;
- if (qFuzzyCompare(reciprocal + 1, 1)) {
+ if (qFuzzyIsNull(reciprocal)) {
t0 = -b / (2 * a);
return 1;
} else if (reciprocal > 0) {
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 5d7d4ab..24d167e 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -1387,7 +1387,7 @@ QColor QColor::toHsv() const
const qreal min = Q_MIN_3(r, g, b);
const qreal delta = max - min;
color.ct.ahsv.value = qRound(max * USHRT_MAX);
- if (qFuzzyCompare(delta + 1, 1)) {
+ if (qFuzzyIsNull(delta)) {
// achromatic case, hue is undefined
color.ct.ahsv.hue = USHRT_MAX;
color.ct.ahsv.saturation = 0;
@@ -1441,7 +1441,7 @@ QColor QColor::toCmyk() const
// cmy -> cmyk
const qreal k = qMin(c, qMin(m, y));
- if (!qFuzzyCompare(k,1)) {
+ if (!qFuzzyIsNull(k - 1)) {
c = (c - k) / (1.0 - k);
m = (m - k) / (1.0 - k);
y = (y - k) / (1.0 - k);
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index efdc778..63e14ca 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -157,46 +157,9 @@ static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuff
return buffer;
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-template <typename EnumType, int value>
-class QEnumToType
-{
-public:
- inline EnumType operator()() const
- {
- return EnumType(value);
- }
-};
-template <QImage::Format format>
-class QImageFormatToType
-{
-public:
- inline QImage::Format operator()() const
- {
- return format;
- }
-};
-// Would have used QEnumToType instead of creating a specialized version for QImageFormatToType,
-// but that causes internal compiler error on VC6
-#define Q_TEMPLATE_IMAGEFORMAT_FIX(format) , const QImageFormatToType<format> &imageFormatType
-#define Q_TEMPLATE_IMAGEFORMAT_CALL(format) , QImageFormatToType<format>()
-#define Q_TEMPLATE_ENUM_FIX(Type, Value) , const QEnumToType<Type, Value> &enumTemplateType
-#define Q_TEMPLATE_ENUM_CALL(Type, Value) , QEnumToType<Type, Value>()
-#define Q_TEMPLATE_FIX(Type) , const QTypeInfo<Type> &templateType
-#define Q_TEMPLATE_CALL(Type) , QTypeInfo<Type>()
-#else
-#define Q_TEMPLATE_IMAGEFORMAT_FIX(format)
-#define Q_TEMPLATE_IMAGEFORMAT_CALL(format)
-#define Q_TEMPLATE_ENUM_FIX(Type, Value)
-#define Q_TEMPLATE_ENUM_CALL(Type, Value)
-#define Q_TEMPLATE_FIX(Type)
-#define Q_TEMPLATE_CALL(Type)
-#endif
-
template <class DST>
Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer,
- int x, int y, int length
- Q_TEMPLATE_FIX(DST))
+ int x, int y, int length)
{
const DST *src = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x;
quint32 *dest = reinterpret_cast<quint32*>(buffer);
@@ -205,28 +168,7 @@ Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuf
return buffer;
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-#define DEST_FETCH_DECL(DST) \
- static uint * QT_FASTCALL destFetch_##DST(uint *buffer, \
- QRasterBuffer *rasterBuffer, \
- int x, int y, int length) \
- { \
- return destFetch<DST>(buffer, rasterBuffer, x, y, length Q_TEMPLATE_CALL(DST)); \
- }
-
-DEST_FETCH_DECL(qargb8565)
-DEST_FETCH_DECL(qrgb666)
-DEST_FETCH_DECL(qargb6666)
-DEST_FETCH_DECL(qrgb555)
-DEST_FETCH_DECL(qrgb888)
-DEST_FETCH_DECL(qargb8555)
-DEST_FETCH_DECL(qrgb444)
-DEST_FETCH_DECL(qargb4444)
-#undef DEST_FETCH_DECL
-# define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch_##Arg
-#else // !VC6 && !VC2002
# define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch<Arg>
-#endif
static const DestFetchProc destFetchProc[QImage::NImageFormats] =
{
@@ -366,8 +308,7 @@ static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer, int x, int y
template <class DST>
Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer,
int x, int y,
- const uint *buffer, int length
- Q_TEMPLATE_FIX(DST))
+ const uint *buffer, int length)
{
DST *dest = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x;
const quint32 *src = reinterpret_cast<const quint32*>(buffer);
@@ -375,28 +316,7 @@ Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffe
*dest++ = DST(*src++);
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-# define DEST_STORE_DECL(DST) \
- static void QT_FASTCALL destStore_##DST(QRasterBuffer *rasterBuffer, \
- int x, int y, \
- const uint *buffer, int length) \
- { \
- destStore<DST>(rasterBuffer, x, y, buffer, length Q_TEMPLATE_CALL(DST)); \
- }
-
-DEST_STORE_DECL(qargb8565)
-DEST_STORE_DECL(qrgb555)
-DEST_STORE_DECL(qrgb666)
-DEST_STORE_DECL(qargb6666)
-DEST_STORE_DECL(qargb8555)
-DEST_STORE_DECL(qrgb888)
-DEST_STORE_DECL(qrgb444)
-DEST_STORE_DECL(qargb4444)
-# undef DEST_FETCH_DECL
-# define SPANFUNC_POINTER_DESTSTORE(DEST) destStore_##DEST
-#else // !VC6 && !VC2002
# define SPANFUNC_POINTER_DESTSTORE(DEST) destStore<DEST>
-#endif
static const DestStoreProc destStoreProc[QImage::NImageFormats] =
{
@@ -425,10 +345,8 @@ static const DestStoreProc destStoreProc[QImage::NImageFormats] =
We need 5 fetch methods per surface type:
untransformed
- transformed
- transformed tiled
- transformed bilinear
- transformed bilinear tiled
+ transformed (tiled and not tiled)
+ transformed bilinear (tiled and not tiled)
We don't need bounds checks for untransformed, but we need them for the other ones.
@@ -436,14 +354,12 @@ static const DestStoreProc destStoreProc[QImage::NImageFormats] =
*/
template <QImage::Format format>
-Q_STATIC_TEMPLATE_FUNCTION uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, int x, const QVector<QRgb> *rgb
- Q_TEMPLATE_IMAGEFORMAT_FIX(format));
+Q_STATIC_TEMPLATE_FUNCTION uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, int x, const QVector<QRgb> *rgb);
template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_Mono>(const uchar *scanLine,
- int x, const QVector<QRgb> *rgb
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_Mono))
+ int x, const QVector<QRgb> *rgb)
{
bool pixel = scanLine[x>>3] & (0x80 >> (x & 7));
if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0));
@@ -453,8 +369,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_Mono>(const uchar *scanLine,
template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_MonoLSB>(const uchar *scanLine,
- int x, const QVector<QRgb> *rgb
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_MonoLSB))
+ int x, const QVector<QRgb> *rgb)
{
bool pixel = scanLine[x>>3] & (0x1 << (x & 7));
if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0));
@@ -464,8 +379,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_MonoLSB>(const uchar *scanLine,
template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_Indexed8>(const uchar *scanLine,
- int x, const QVector<QRgb> *rgb
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_Indexed8))
+ int x, const QVector<QRgb> *rgb)
{
return PREMUL(rgb->at(scanLine[x]));
}
@@ -473,8 +387,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_Indexed8>(const uchar *scanLine,
template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32>(const uchar *scanLine,
- int x, const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB32))
+ int x, const QVector<QRgb> *)
{
return PREMUL(((const uint *)scanLine)[x]);
}
@@ -482,8 +395,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32>(const uchar *scanLine,
template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32_Premultiplied>(const uchar *scanLine,
- int x, const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB32_Premultiplied))
+ int x, const QVector<QRgb> *)
{
return ((const uint *)scanLine)[x];
}
@@ -491,8 +403,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32_Premultiplied>(const uchar
template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB16>(const uchar *scanLine,
- int x, const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB16))
+ int x, const QVector<QRgb> *)
{
return qConvertRgb16To32(((const ushort *)scanLine)[x]);
}
@@ -501,8 +412,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB8565_Premultiplied>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB8565_Premultiplied))
+ const QVector<QRgb> *)
{
const qargb8565 color = reinterpret_cast<const qargb8565*>(scanLine)[x];
return qt_colorConvert<quint32, qargb8565>(color, 0);
@@ -512,8 +422,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB666>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB666))
+ const QVector<QRgb> *)
{
const qrgb666 color = reinterpret_cast<const qrgb666*>(scanLine)[x];
return qt_colorConvert<quint32, qrgb666>(color, 0);
@@ -523,8 +432,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB6666_Premultiplied>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB6666_Premultiplied))
+ const QVector<QRgb> *)
{
const qargb6666 color = reinterpret_cast<const qargb6666*>(scanLine)[x];
return qt_colorConvert<quint32, qargb6666>(color, 0);
@@ -534,8 +442,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB555>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB555))
+ const QVector<QRgb> *)
{
const qrgb555 color = reinterpret_cast<const qrgb555*>(scanLine)[x];
return qt_colorConvert<quint32, qrgb555>(color, 0);
@@ -545,8 +452,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB8555_Premultiplied>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB8555_Premultiplied))
+ const QVector<QRgb> *)
{
const qargb8555 color = reinterpret_cast<const qargb8555*>(scanLine)[x];
return qt_colorConvert<quint32, qargb8555>(color, 0);
@@ -556,8 +462,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB888>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB888))
+ const QVector<QRgb> *)
{
const qrgb888 color = reinterpret_cast<const qrgb888*>(scanLine)[x];
return qt_colorConvert<quint32, qrgb888>(color, 0);
@@ -567,8 +472,7 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB444>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB444))
+ const QVector<QRgb> *)
{
const qrgb444 color = reinterpret_cast<const qrgb444*>(scanLine)[x];
return qt_colorConvert<quint32, qrgb444>(color, 0);
@@ -578,47 +482,24 @@ template<>
Q_STATIC_TEMPLATE_SPECIALIZATION
uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB4444_Premultiplied>(const uchar *scanLine,
int x,
- const QVector<QRgb> *
- Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB4444_Premultiplied))
+ const QVector<QRgb> *)
{
const qargb4444 color = reinterpret_cast<const qargb4444*>(scanLine)[x];
return qt_colorConvert<quint32, qargb4444>(color, 0);
}
-typedef uint (QT_FASTCALL *FetchPixelProc)(const uchar *scanLine, int x, const QVector<QRgb> *);
-
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-
-// explicit template instantiations needed to compile with VC6 and VC2002
-
-#define SPANFUNC_INSTANTIATION_FETCHPIXEL(Arg) \
- static inline uint fetchPixel_##Arg(const uchar * scanLine, int x, const QVector<QRgb> * rgb) \
-{ \
- return qt_fetchPixel<QImage::Arg>(scanLine, x, rgb Q_TEMPLATE_IMAGEFORMAT_CALL(QImage::Arg)); \
+template<>
+Q_STATIC_TEMPLATE_SPECIALIZATION
+uint QT_FASTCALL qt_fetchPixel<QImage::Format_Invalid>(const uchar *,
+ int ,
+ const QVector<QRgb> *)
+{
+ return 0;
}
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_Mono);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_MonoLSB);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_Indexed8);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB32_Premultiplied);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB32);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB16);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB8565_Premultiplied);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB666);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB6666_Premultiplied);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB555);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB8555_Premultiplied);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB888);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB444);
-SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB4444_Premultiplied);
-
-#undef SPANFUNC_INSTANTIATION_FETCHPIXEL
-
-#define SPANFUNC_POINTER_FETCHPIXEL(Arg) fetchPixel_##Arg
+typedef uint (QT_FASTCALL *FetchPixelProc)(const uchar *scanLine, int x, const QVector<QRgb> *);
-#else // !VC6 && !VC2002
-# define SPANFUNC_POINTER_FETCHPIXEL(Arg) qt_fetchPixel<QImage::Arg>
-#endif
+#define SPANFUNC_POINTER_FETCHPIXEL(Arg) qt_fetchPixel<QImage::Arg>
static const FetchPixelProc fetchPixelProc[QImage::NImageFormats] =
@@ -653,11 +534,11 @@ enum TextureBlendType {
template <QImage::Format format>
Q_STATIC_TEMPLATE_FUNCTION const uint * QT_FASTCALL qt_fetchUntransformed(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length Q_TEMPLATE_IMAGEFORMAT_FIX(format))
+ int y, int x, int length)
{
const uchar *scanLine = data->texture.scanLine(y);
for (int i = 0; i < length; ++i)
- buffer[i] = qt_fetchPixel<format>(scanLine, x + i, data->texture.colorTable Q_TEMPLATE_IMAGEFORMAT_CALL(format));
+ buffer[i] = qt_fetchPixel<format>(scanLine, x + i, data->texture.colorTable);
return buffer;
}
@@ -665,13 +546,15 @@ template <>
Q_STATIC_TEMPLATE_SPECIALIZATION const uint * QT_FASTCALL
qt_fetchUntransformed<QImage::Format_ARGB32_Premultiplied>(uint *, const Operator *,
const QSpanData *data,
- int y, int x, int Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB32_Premultiplied))
+ int y, int x, int)
{
const uchar *scanLine = data->texture.scanLine(y);
return ((const uint *)scanLine) + x;
}
-static const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data,
+template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */
+Q_STATIC_TEMPLATE_FUNCTION
+const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data,
int y, int x, int length)
{
FetchPixelProc fetch = fetchPixelProc[data->texture.format];
@@ -698,84 +581,23 @@ static const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
int px = fx >> 16;
int py = fy >> 16;
- bool out = (px < 0) || (px >= image_width)
- || (py < 0) || (py >= image_height);
+ if (blendType == BlendTransformedTiled) {
+ px %= image_width;
+ py %= image_height;
+ if (px < 0) px += image_width;
+ if (py < 0) py += image_height;
- const uchar *scanLine = data->texture.scanLine(py);
- *b = out ? uint(0) : fetch(scanLine, px, data->texture.colorTable);
- fx += fdx;
- fy += fdy;
- ++b;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
- qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
- qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
-
- while (b < end) {
- const qreal iw = fw == 0 ? 1 : 1 / fw;
- const qreal tx = fx * iw;
- const qreal ty = fy * iw;
- const int px = int(tx) - (tx < 0);
- const int py = int(ty) - (ty < 0);
-
- bool out = (px < 0) || (px >= image_width)
- || (py < 0) || (py >= image_height);
-
- const uchar *scanLine = data->texture.scanLine(py);
- *b = out ? uint(0) : fetch(scanLine, px, data->texture.colorTable);
- fx += fdx;
- fy += fdy;
- fw += fdw;
- //force increment to avoid /0
- if (!fw) {
- fw += fdw;
+ const uchar *scanLine = data->texture.scanLine(py);
+ *b = fetch(scanLine, px, data->texture.colorTable);
+ } else {
+ if ((px < 0) || (px >= image_width)
+ || (py < 0) || (py >= image_height)) {
+ *b = uint(0);
+ } else {
+ const uchar *scanLine = data->texture.scanLine(py);
+ *b = fetch(scanLine, px, data->texture.colorTable);
+ }
}
- ++b;
- }
- }
-
- return buffer;
-}
-
-static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
-{
- FetchPixelProc fetch = fetchPixelProc[data->texture.format];
-
- 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 uint *end = buffer + length;
- uint *b = buffer;
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
-
- int fx = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale);
- int fy = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale);
-
- while (b < end) {
- int px = fx >> 16;
- int py = fy >> 16;
-
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
-
- const uchar *scanLine = data->texture.scanLine(py);
- *b = fetch(scanLine, px, data->texture.colorTable);
fx += fdx;
fy += fdy;
++b;
@@ -796,13 +618,23 @@ static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operat
int px = int(tx) - (tx < 0);
int py = int(ty) - (ty < 0);
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
+ if (blendType == BlendTransformedTiled) {
+ px %= image_width;
+ py %= image_height;
+ if (px < 0) px += image_width;
+ if (py < 0) py += image_height;
- const uchar *scanLine = data->texture.scanLine(py);
- *b = fetch(scanLine, px, data->texture.colorTable);
+ const uchar *scanLine = data->texture.scanLine(py);
+ *b = fetch(scanLine, px, data->texture.colorTable);
+ } else {
+ if ((px < 0) || (px >= image_width)
+ || (py < 0) || (py >= image_height)) {
+ *b = uint(0);
+ } else {
+ const uchar *scanLine = data->texture.scanLine(py);
+ *b = fetch(scanLine, px, data->texture.colorTable);
+ }
+ }
fx += fdx;
fy += fdy;
fw += fdw;
@@ -817,10 +649,12 @@ static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operat
return buffer;
}
-static const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
+template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
+Q_STATIC_TEMPLATE_FUNCTION
+const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
{
- FetchPixelProc fetch = fetchPixelProc[data->texture.format];
+ FetchPixelProc fetch = (format != QImage::Format_Invalid) ? FetchPixelProc(qt_fetchPixel<format>) : fetchPixelProc[data->texture.format];
int image_width = data->texture.width;
int image_height = data->texture.height;
@@ -853,130 +687,27 @@ static const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Ope
int idistx = 256 - distx;
int idisty = 256 - disty;
- x1 = qBound(0, x1, image_width - 1);
- x2 = qBound(0, x2, image_width - 1);
- y1 = qBound(0, y1, image_height - 1);
- y2 = qBound(0, y2, image_height - 1);
-
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
-
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
-
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
-
- fx += fdx;
- fy += fdy;
- ++b;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
- qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
- qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
-
- 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;
-
- int x1 = int(px) - (px < 0);
- int x2 = x1 + 1;
- int y1 = int(py) - (py < 0);
- int y2 = y1 + 1;
-
- int distx = int((px - x1) * 256);
- int disty = int((py - y1) * 256);
- int idistx = 256 - distx;
- int idisty = 256 - disty;
-
- x1 = qBound(0, x1, image_width - 1);
- x2 = qBound(0, x2, image_width - 1);
- y1 = qBound(0, y1, image_height - 1);
- y2 = qBound(0, y2, image_height - 1);
-
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
-
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
-
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
-
- fx += fdx;
- fy += fdy;
- fw += fdw;
- //force increment to avoid /0
- if (!fw) {
- fw += fdw;
+ if (blendType == BlendTransformedBilinearTiled) {
+ x1 %= image_width;
+ x2 %= image_width;
+ y1 %= image_height;
+ y2 %= image_height;
+
+ if (x1 < 0) x1 += image_width;
+ if (x2 < 0) x2 += image_width;
+ if (y1 < 0) y1 += image_height;
+ if (y2 < 0) y2 += image_height;
+
+ Q_ASSERT(x1 >= 0 && x1 < image_width);
+ Q_ASSERT(x2 >= 0 && x2 < image_width);
+ Q_ASSERT(y1 >= 0 && y1 < image_height);
+ Q_ASSERT(y2 >= 0 && y2 < image_height);
+ } else {
+ x1 = qBound(0, x1, image_width - 1);
+ x2 = qBound(0, x2, image_width - 1);
+ y1 = qBound(0, y1, image_height - 1);
+ y2 = qBound(0, y2, image_height - 1);
}
- ++b;
- }
- }
-
- return buffer;
-}
-
-static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
-{
- FetchPixelProc fetch = fetchPixelProc[data->texture.format];
-
- 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 uint *end = buffer + length;
- uint *b = buffer;
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
-
- int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
- int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
-
- fx -= half_point;
- fy -= half_point;
- while (b < end) {
- int x1 = (fx >> 16);
- int x2 = x1 + 1;
- int y1 = (fy >> 16);
- int y2 = y1 + 1;
-
- int distx = ((fx - (x1 << 16)) >> 8);
- int disty = ((fy - (y1 << 16)) >> 8);
- int idistx = 256 - distx;
- int idisty = 256 - disty;
-
- x1 %= image_width;
- x2 %= image_width;
- y1 %= image_height;
- y2 %= image_height;
-
- if (x1 < 0) x1 += image_width;
- if (x2 < 0) x2 += image_width;
- if (y1 < 0) y1 += image_height;
- if (y2 < 0) y2 += image_height;
-
- Q_ASSERT(x1 >= 0 && x1 < image_width);
- Q_ASSERT(x2 >= 0 && x2 < image_width);
- Q_ASSERT(y1 >= 0 && y1 < image_height);
- Q_ASSERT(y2 >= 0 && y2 < image_height);
const uchar *s1 = data->texture.scanLine(y1);
const uchar *s2 = data->texture.scanLine(y2);
@@ -1018,20 +749,27 @@ static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, cons
int idistx = 256 - distx;
int idisty = 256 - disty;
- x1 %= image_width;
- x2 %= image_width;
- y1 %= image_height;
- y2 %= image_height;
-
- if (x1 < 0) x1 += image_width;
- if (x2 < 0) x2 += image_width;
- if (y1 < 0) y1 += image_height;
- if (y2 < 0) y2 += image_height;
-
- Q_ASSERT(x1 >= 0 && x1 < image_width);
- Q_ASSERT(x2 >= 0 && x2 < image_width);
- Q_ASSERT(y1 >= 0 && y1 < image_height);
- Q_ASSERT(y2 >= 0 && y2 < image_height);
+ if (blendType == BlendTransformedBilinearTiled) {
+ x1 %= image_width;
+ x2 %= image_width;
+ y1 %= image_height;
+ y2 %= image_height;
+
+ if (x1 < 0) x1 += image_width;
+ if (x2 < 0) x2 += image_width;
+ if (y1 < 0) y1 += image_height;
+ if (y2 < 0) y2 += image_height;
+
+ Q_ASSERT(x1 >= 0 && x1 < image_width);
+ Q_ASSERT(x2 >= 0 && x2 < image_width);
+ Q_ASSERT(y1 >= 0 && y1 < image_height);
+ Q_ASSERT(y2 >= 0 && y2 < image_height);
+ } else {
+ x1 = qBound(0, x1, image_width - 1);
+ x2 = qBound(0, x2, image_width - 1);
+ y1 = qBound(0, y1, image_height - 1);
+ y2 = qBound(0, y2, image_height - 1);
+ }
const uchar *s1 = data->texture.scanLine(y1);
const uchar *s2 = data->texture.scanLine(y2);
@@ -1059,39 +797,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, cons
return buffer;
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-
-// explicit template instantiations needed to compile with VC6 and VC2002
-
-#define SPANFUNC_POINTER_FETCHUNTRANSFORMED(Arg) \
- const uint *qt_fetchUntransformed_##Arg(uint *buffer, const Operator *op, const QSpanData *data, \
- int y, int x, int length) \
-{ \
- return qt_fetchUntransformed<QImage::Arg>(buffer, op, data, y, x, length Q_TEMPLATE_IMAGEFORMAT_CALL(QImage::Arg)); \
-}
-
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_Mono);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_MonoLSB);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_Indexed8);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB32_Premultiplied);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB32);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB16);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB8565_Premultiplied);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB666);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB6666_Premultiplied);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB555);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB8555_Premultiplied);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB888);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB444);
-SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB4444_Premultiplied);
-
-#undef SPANFUNC_POINTER_FETCHUNTRANSFORMED
-
-#define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed_##Arg
-
-#else // !VC6 && !VC2002
-# define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed<QImage::Arg>
-#endif
+#define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed<QImage::Arg>
static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
@@ -1135,75 +841,75 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
// Transformed
{
0, // Invalid
- fetchTransformed, // Mono
- fetchTransformed, // MonoLsb
- fetchTransformed, // Indexed8
- fetchTransformed, // RGB32
- fetchTransformed, // ARGB32
- fetchTransformed, // ARGB32_Premultiplied
- fetchTransformed, // RGB16
- fetchTransformed, // ARGB8565_Premultiplied
- fetchTransformed, // RGB666
- fetchTransformed, // ARGB6666_Premultiplied
- fetchTransformed, // RGB555
- fetchTransformed, // ARGB8555_Premultiplied
- fetchTransformed, // RGB888
- fetchTransformed, // RGB444
- fetchTransformed, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformed>, // Mono
+ fetchTransformed<BlendTransformed>, // MonoLsb
+ fetchTransformed<BlendTransformed>, // Indexed8
+ fetchTransformed<BlendTransformed>, // RGB32
+ fetchTransformed<BlendTransformed>, // ARGB32
+ fetchTransformed<BlendTransformed>, // ARGB32_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB16
+ fetchTransformed<BlendTransformed>, // ARGB8565_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB666
+ fetchTransformed<BlendTransformed>, // ARGB6666_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB555
+ fetchTransformed<BlendTransformed>, // ARGB8555_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB888
+ fetchTransformed<BlendTransformed>, // RGB444
+ fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
},
{
0, // TransformedTiled
- fetchTransformedTiled, // Mono
- fetchTransformedTiled, // MonoLsb
- fetchTransformedTiled, // Indexed8
- fetchTransformedTiled, // RGB32
- fetchTransformedTiled, // ARGB32
- fetchTransformedTiled, // ARGB32_Premultiplied
- fetchTransformedTiled, // RGB16
- fetchTransformedTiled, // ARGB8565_Premultiplied
- fetchTransformedTiled, // RGB666
- fetchTransformedTiled, // ARGB6666_Premultiplied
- fetchTransformedTiled, // RGB555
- fetchTransformedTiled, // ARGB8555_Premultiplied
- fetchTransformedTiled, // RGB888
- fetchTransformedTiled, // RGB444
- fetchTransformedTiled, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // Mono
+ fetchTransformed<BlendTransformedTiled>, // MonoLsb
+ fetchTransformed<BlendTransformedTiled>, // Indexed8
+ fetchTransformed<BlendTransformedTiled>, // RGB32
+ fetchTransformed<BlendTransformedTiled>, // ARGB32
+ fetchTransformed<BlendTransformedTiled>, // ARGB32_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB16
+ fetchTransformed<BlendTransformedTiled>, // ARGB8565_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB666
+ fetchTransformed<BlendTransformedTiled>, // ARGB6666_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB555
+ fetchTransformed<BlendTransformedTiled>, // ARGB8555_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB888
+ fetchTransformed<BlendTransformedTiled>, // RGB444
+ fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
},
{
0, // Bilinear
- fetchTransformedBilinear, // Mono
- fetchTransformedBilinear, // MonoLsb
- fetchTransformedBilinear, // Indexed8
- fetchTransformedBilinear, // RGB32
- fetchTransformedBilinear, // ARGB32
- fetchTransformedBilinear, // ARGB32_Premultiplied
- fetchTransformedBilinear, // RGB16
- fetchTransformedBilinear, // ARGB8565_Premultiplied
- fetchTransformedBilinear, // RGB666
- fetchTransformedBilinear, // ARGB6666_Premultiplied
- fetchTransformedBilinear, // RGB555
- fetchTransformedBilinear, // ARGB8555_Premultiplied
- fetchTransformedBilinear, // RGB888
- fetchTransformedBilinear, // RGB444
- fetchTransformedBilinear // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // Mono
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // MonoLsb
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // Indexed8
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32_Premultiplied>, // RGB32
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32>, // ARGB32
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32_Premultiplied>, // ARGB32_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB16
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB8565_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB666
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB6666_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB555
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB8555_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB888
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB444
+ fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid> // ARGB4444_Premultiplied
},
{
0, // BilinearTiled
- fetchTransformedBilinearTiled, // Mono
- fetchTransformedBilinearTiled, // MonoLsb
- fetchTransformedBilinearTiled, // Indexed8
- fetchTransformedBilinearTiled, // RGB32
- fetchTransformedBilinearTiled, // ARGB32
- fetchTransformedBilinearTiled, // ARGB32_Premultiplied
- fetchTransformedBilinearTiled, // RGB16
- fetchTransformedBilinearTiled, // ARGB8565_Premultiplied
- fetchTransformedBilinearTiled, // RGB666
- fetchTransformedBilinearTiled, // ARGB6666_Premultiplied
- fetchTransformedBilinearTiled, // RGB555
- fetchTransformedBilinearTiled, // ARGB8555_Premultiplied
- fetchTransformedBilinearTiled, // RGB888
- fetchTransformedBilinearTiled, // RGB444
- fetchTransformedBilinearTiled // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // Mono
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // MonoLsb
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // Indexed8
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32_Premultiplied>, // RGB32
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32>, // ARGB32
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32_Premultiplied>, // ARGB32_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB16
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB8565_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB666
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB6666_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB555
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB8555_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB888
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB444
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid> // ARGB4444_Premultiplied
},
};
@@ -3220,8 +2926,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
}
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_FIX(T))
+Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
Operator op = getOperator(data, spans, count);
@@ -3267,28 +2972,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *
blend_color_generic(count, spans, userData);
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-#define BLEND_COLOR_DECL(DST) \
- static void blendColor_##DST(int count, \
- const QSpan *spans, \
- void *userData) \
- { \
- blendColor<DST>(count, spans, userData Q_TEMPLATE_CALL(DST)); \
- }
-
-BLEND_COLOR_DECL(qargb8565)
-BLEND_COLOR_DECL(qrgb666)
-BLEND_COLOR_DECL(qargb6666)
-BLEND_COLOR_DECL(qrgb555)
-BLEND_COLOR_DECL(qargb8555)
-BLEND_COLOR_DECL(qrgb888)
-BLEND_COLOR_DECL(qrgb444)
-BLEND_COLOR_DECL(qargb4444)
-#undef DEST_FETCH_DECL
-#define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor_##DST
-#else // !VC6 && !VC2002
-# define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor<DST>
-#endif
+#define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor<DST>
static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
{
@@ -3366,45 +3050,117 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
blend_color_generic(count, spans, userData);
}
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_src_generic(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+template <typename T>
+void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handler)
{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- uint buffer[buffer_size];
- uint src_buffer[buffer_size];
- Operator op = getOperator(data, spans, count);
-
uint const_alpha = 256;
if (data->type == QSpanData::Texture)
const_alpha = data->texture.const_alpha;
- while (count--) {
+ int coverage = 0;
+ while (count) {
int x = spans->x;
- int length = spans->len;
- const int coverage = (spans->coverage * const_alpha) >> 8;
+ const int y = spans->y;
+ int right = x + spans->len;
+
+ // compute length of adjacent spans
+ for (int i = 1; i < count && spans[i].y == y && spans[i].x == right; ++i)
+ right += spans[i].len;
+ int length = right - x;
+
while (length) {
int l = qMin(buffer_size, length);
- const uint *src = op.src_fetch(src_buffer, &op, data, spans->y, x, l);
- if (spanMethod == RegularSpans) {
- uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
- op.func(dest, src, l, coverage);
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
- } else {
- drawBufferSpan(data, src, l, x, spans->y, l, coverage);
- }
- x += l;
length -= l;
+
+ int process_length = l;
+ int process_x = x;
+
+ const uint *src = handler.fetch(process_x, y, process_length);
+ int offset = 0;
+ while (l > 0) {
+ if (x == spans->x) // new span?
+ coverage = (spans->coverage * const_alpha) >> 8;
+
+ int right = spans->x + spans->len;
+ int len = qMin(l, right - x);
+
+ handler.process(x, y, len, coverage, src, offset);
+
+ l -= len;
+ x += len;
+ offset += len;
+
+ if (x == right) { // done with current span?
+ ++spans;
+ --count;
+ }
+ }
+ handler.store(process_x, y, process_length);
}
- ++spans;
}
}
+struct QBlendBase
+{
+ QBlendBase(QSpanData *d, Operator o)
+ : data(d)
+ , op(o)
+ , dest(0)
+ {
+ }
+
+ QSpanData *data;
+ Operator op;
+
+ uint *dest;
+
+ uint buffer[buffer_size];
+ uint src_buffer[buffer_size];
+};
+
+template <SpanMethod spanMethod>
+class BlendSrcGeneric : public QBlendBase
+{
+public:
+ BlendSrcGeneric(QSpanData *d, Operator o)
+ : QBlendBase(d, o)
+ {
+ }
+
+ const uint *fetch(int x, int y, int len)
+ {
+ if (spanMethod == RegularSpans)
+ dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer;
+
+ return op.src_fetch(src_buffer, &op, data, y, x, len);
+ }
+
+ void process(int x, int y, int len, int coverage, const uint *src, int offset)
+ {
+ if (spanMethod == RegularSpans)
+ op.func(dest + offset, src + offset, len, coverage);
+ else
+ drawBufferSpan(data, src + offset, len, x, y, len, coverage);
+ }
+
+ void store(int x, int y, int len)
+ {
+ if (spanMethod == RegularSpans && op.dest_store) {
+ op.dest_store(data->rasterBuffer, x, y, dest, len);
+ }
+ }
+};
+
+template <SpanMethod spanMethod>
+Q_STATIC_TEMPLATE_FUNCTION void blend_src_generic(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+ BlendSrcGeneric<spanMethod> blend(data, getOperator(data, spans, count));
+ handleSpans(count, spans, data, blend);
+}
+
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -3455,13 +3211,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSp
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_untransformed_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod));
+ blend_untransformed_generic<spanMethod>(count, spans, userData);
return;
}
@@ -4707,8 +4462,7 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat
if (mode != QPainter::CompositionMode_SourceOver &&
mode != QPainter::CompositionMode_Source)
{
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
return;
}
@@ -4770,8 +4524,7 @@ static void blend_untransformed_rgb888(int count, const QSpan *spans,
blendUntransformed<qrgb888, qrgb888>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb6666(int count, const QSpan *spans,
@@ -4786,8 +4539,7 @@ static void blend_untransformed_argb6666(int count, const QSpan *spans,
blendUntransformed<qargb6666, qrgb666>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb666(int count, const QSpan *spans,
@@ -4802,8 +4554,7 @@ static void blend_untransformed_rgb666(int count, const QSpan *spans,
blendUntransformed<qrgb666, qrgb666>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb8565(int count, const QSpan *spans,
@@ -4818,8 +4569,7 @@ static void blend_untransformed_argb8565(int count, const QSpan *spans,
blendUntransformed<qargb8565, qrgb565>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb565(int count, const QSpan *spans,
@@ -4834,8 +4584,7 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans,
blendUntransformed<qrgb565, qrgb565>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb8555(int count, const QSpan *spans,
@@ -4850,8 +4599,7 @@ static void blend_untransformed_argb8555(int count, const QSpan *spans,
blendUntransformed<qargb8555, qrgb555>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb555(int count, const QSpan *spans,
@@ -4866,8 +4614,7 @@ static void blend_untransformed_rgb555(int count, const QSpan *spans,
blendUntransformed<qrgb555, qrgb555>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb4444(int count, const QSpan *spans,
@@ -4882,8 +4629,7 @@ static void blend_untransformed_argb4444(int count, const QSpan *spans,
blendUntransformed<qargb4444, qrgb444>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb444(int count, const QSpan *spans,
@@ -4898,13 +4644,11 @@ static void blend_untransformed_rgb444(int count, const QSpan *spans,
blendUntransformed<qrgb444, qrgb444>(count, spans, userData);
else
#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -4958,13 +4702,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *span
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_tiled_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod));
+ blend_tiled_generic<spanMethod>(count, spans, userData);
return;
}
@@ -5020,8 +4763,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
if (mode != QPainter::CompositionMode_SourceOver &&
mode != QPainter::CompositionMode_Source)
{
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
return;
}
@@ -5091,8 +4833,7 @@ static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData)
blendTiled<qrgb888, qrgb888>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData)
@@ -5106,8 +4847,7 @@ static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData)
blendTiled<qargb6666, qrgb666>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData)
@@ -5121,8 +4861,7 @@ static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData)
blendTiled<qrgb666, qrgb666>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData)
@@ -5136,8 +4875,7 @@ static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData)
blendTiled<qargb8565, qrgb565>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
@@ -5151,8 +4889,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
blendTiled<qrgb565, qrgb565>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData)
@@ -5166,8 +4903,7 @@ static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData)
blendTiled<qargb8555, qrgb555>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData)
@@ -5181,8 +4917,7 @@ static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData)
blendTiled<qrgb555, qrgb555>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData)
@@ -5196,8 +4931,7 @@ static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData)
blendTiled<qargb4444, qrgb444>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData)
@@ -5211,19 +4945,17 @@ static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData)
blendTiled<qrgb444, qrgb444>(count, spans, userData);
else
#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod));
+ blend_src_generic<spanMethod>(count, spans, userData);
return;
}
@@ -5402,8 +5134,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
if (mode != QPainter::CompositionMode_SourceOver) {
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
return;
}
@@ -5606,8 +5337,7 @@ static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, voi
blendTransformedBilinear<qrgb888, qrgb888>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData)
@@ -5621,8 +5351,7 @@ static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, v
blendTransformedBilinear<qargb6666, qrgb666>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData)
@@ -5636,8 +5365,7 @@ static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, voi
blendTransformedBilinear<qrgb666, qrgb666>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData)
@@ -5651,8 +5379,7 @@ static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, v
blendTransformedBilinear<qargb8565, qrgb565>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
@@ -5667,8 +5394,7 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
blendTransformedBilinear<qrgb565, qargb8565>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData)
@@ -5682,8 +5408,7 @@ static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, v
blendTransformedBilinear<qargb8555, qrgb555>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData)
@@ -5697,8 +5422,7 @@ static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, voi
blendTransformedBilinear<qrgb555, qrgb555>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData)
@@ -5712,8 +5436,7 @@ static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, v
blendTransformedBilinear<qargb4444, qrgb444>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData)
@@ -5727,18 +5450,16 @@ static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, voi
blendTransformedBilinear<qrgb444, qrgb444>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod));
+ blend_src_generic<spanMethod>(count, spans, userData);
return;
}
@@ -5924,13 +5645,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count,
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod));
+ blend_src_generic<spanMethod>(count, spans, userData);
return;
}
@@ -6052,8 +5772,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
if (mode != QPainter::CompositionMode_SourceOver) {
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
return;
}
@@ -6202,8 +5921,7 @@ static void blend_transformed_rgb888(int count, const QSpan *spans,
blendTransformed<qrgb888, qrgb888>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb6666(int count, const QSpan *spans,
@@ -6218,8 +5936,7 @@ static void blend_transformed_argb6666(int count, const QSpan *spans,
blendTransformed<qargb6666, qrgb666>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb666(int count, const QSpan *spans,
@@ -6234,8 +5951,7 @@ static void blend_transformed_rgb666(int count, const QSpan *spans,
blendTransformed<qrgb666, qrgb666>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb8565(int count, const QSpan *spans,
@@ -6250,8 +5966,7 @@ static void blend_transformed_argb8565(int count, const QSpan *spans,
blendTransformed<qargb8565, qrgb565>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb565(int count, const QSpan *spans,
@@ -6266,8 +5981,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans,
blendTransformed<qrgb565, qrgb565>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb8555(int count, const QSpan *spans,
@@ -6282,8 +5996,7 @@ static void blend_transformed_argb8555(int count, const QSpan *spans,
blendTransformed<qargb8555, qrgb555>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb555(int count, const QSpan *spans,
@@ -6298,8 +6011,7 @@ static void blend_transformed_rgb555(int count, const QSpan *spans,
blendTransformed<qrgb555, qrgb555>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb4444(int count, const QSpan *spans,
@@ -6314,8 +6026,7 @@ static void blend_transformed_argb4444(int count, const QSpan *spans,
blendTransformed<qargb4444, qrgb444>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb444(int count, const QSpan *spans,
@@ -6330,18 +6041,16 @@ static void blend_transformed_rgb444(int count, const QSpan *spans,
blendTransformed<qrgb444, qrgb444>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData
- Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod))
+Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod));
+ blend_src_generic<spanMethod>(count, spans, userData);
return;
}
@@ -6475,8 +6184,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
if (mode != QPainter::CompositionMode_SourceOver) {
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
return;
}
@@ -6626,8 +6334,7 @@ static void blend_transformed_tiled_rgb888(int count, const QSpan *spans,
blendTransformedTiled<qrgb888, qrgb888>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb6666(int count, const QSpan *spans,
@@ -6642,8 +6349,7 @@ static void blend_transformed_tiled_argb6666(int count, const QSpan *spans,
blendTransformedTiled<qargb6666, qrgb666>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb666(int count, const QSpan *spans,
@@ -6658,8 +6364,7 @@ static void blend_transformed_tiled_rgb666(int count, const QSpan *spans,
blendTransformedTiled<qrgb666, qrgb666>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
@@ -6674,8 +6379,7 @@ static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
blendTransformedTiled<qargb8565, qrgb565>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
@@ -6690,8 +6394,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
blendTransformedTiled<qrgb565, qrgb565>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb8555(int count, const QSpan *spans,
@@ -6706,8 +6409,7 @@ static void blend_transformed_tiled_argb8555(int count, const QSpan *spans,
blendTransformedTiled<qargb8555, qrgb555>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb555(int count, const QSpan *spans,
@@ -6722,8 +6424,7 @@ static void blend_transformed_tiled_rgb555(int count, const QSpan *spans,
blendTransformedTiled<qrgb555, qrgb555>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb4444(int count, const QSpan *spans,
@@ -6738,8 +6439,7 @@ static void blend_transformed_tiled_argb4444(int count, const QSpan *spans,
blendTransformedTiled<qargb4444, qrgb444>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb444(int count, const QSpan *spans,
@@ -6754,36 +6454,10 @@ static void blend_transformed_tiled_rgb444(int count, const QSpan *spans,
blendTransformedTiled<qrgb444, qrgb444>(count, spans, userData);
else
#endif
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
-#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL)
-
-// explicit template instantiations needed to compile with VC6 and VC2002
-
-#define SPANFUNC_INSTANTIATION(Name, Arg) \
-static inline void Name##_##Arg(int count, const QSpan *spans, void *userData) \
-{ \
- Name<Arg>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, Arg)); \
-}
-
-SPANFUNC_INSTANTIATION(blend_untransformed_generic, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_untransformed_argb, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_tiled_generic, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_tiled_argb, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_src_generic, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_transformed_argb, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_transformed_tiled_argb, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_transformed_bilinear_argb, RegularSpans);
-SPANFUNC_INSTANTIATION(blend_transformed_bilinear_tiled_argb, RegularSpans);
-#undef SPANFUNC_INSTANTIATION
-
-#define SPANFUNC_POINTER(Name, Arg) Name##_##Arg
-
-#else // !VC6 && !VC2002
# define SPANFUNC_POINTER(Name, Arg) Name<Arg>
-#endif
/* Image formats here are target formats */
@@ -7150,8 +6824,7 @@ static void qt_gradient_quint32(int count, const QSpan *spans, void *userData)
}
} else {
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
}
@@ -7199,8 +6872,7 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData)
data->solid.color = oldColor;
} else {
- blend_src_generic<RegularSpans>(count, spans, userData
- Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans));
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
}
@@ -7261,6 +6933,12 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
void qt_build_pow_tables() {
qreal smoothing = 1.7;
+#ifdef Q_WS_MAC
+ // decided by testing a few things on an iMac, should probably get this from the
+ // system...
+ smoothing = 2.0;
+#endif
+
#ifdef Q_WS_WIN
int winSmooth;
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
@@ -7405,7 +7083,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
#endif
{
int ialpha = 255 - coverage;
- dest[i] = BYTE_MUL(c, uint(coverage)) + BYTE_MUL(dest[i], ialpha);
+ dest[i] = INTERPOLATE_PIXEL_255(c, coverage, dest[i], ialpha);
}
}
}
@@ -7446,7 +7124,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
#endif
{
int ialpha = 255 - coverage;
- dest[xp] = BYTE_MUL(c, uint(coverage)) + BYTE_MUL(dest[xp], ialpha);
+ dest[xp] = INTERPOLATE_PIXEL_255(c, coverage, dest[xp], ialpha);
}
}
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index 4439d52..31abcad 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -208,9 +208,13 @@ QT_BEGIN_NAMESPACE
*/
QMatrix::QMatrix()
+ : _m11(1.)
+ , _m12(0.)
+ , _m21(0.)
+ , _m22(1.)
+ , _dx(0.)
+ , _dy(0.)
{
- _m11 = _m22 = 1.0;
- _m12 = _m21 = _dx = _dy = 0.0;
}
/*!
@@ -220,12 +224,14 @@ QMatrix::QMatrix()
\sa setMatrix()
*/
-QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22,
- qreal dx, qreal dy)
+QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
+ : _m11(m11)
+ , _m12(m12)
+ , _m21(m21)
+ , _m22(m22)
+ , _dx(dx)
+ , _dy(dy)
{
- _m11 = m11; _m12 = m12;
- _m21 = m21; _m22 = m22;
- _dx = dx; _dy = dy;
}
@@ -233,8 +239,13 @@ QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22,
Constructs a matrix that is a copy of the given \a matrix.
*/
QMatrix::QMatrix(const QMatrix &matrix)
+ : _m11(matrix._m11)
+ , _m12(matrix._m12)
+ , _m21(matrix._m21)
+ , _m22(matrix._m22)
+ , _dx(matrix._dx)
+ , _dy(matrix._dy)
{
- *this = matrix;
}
/*!
@@ -249,12 +260,14 @@ QMatrix::QMatrix(const QMatrix &matrix)
\sa QMatrix()
*/
-void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22,
- qreal dx, qreal dy)
+void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
{
- _m11 = m11; _m12 = m12;
- _m21 = m21; _m22 = m22;
- _dx = dx; _dy = dy;
+ _m11 = m11;
+ _m12 = m12;
+ _m21 = m21;
+ _m22 = m22;
+ _dx = dx;
+ _dy = dy;
}
@@ -968,18 +981,17 @@ QMatrix QMatrix::inverted(bool *invertible) const
if (determinant == 0.0) {
if (invertible)
*invertible = false; // singular matrix
- QMatrix defaultMatrix;
- return defaultMatrix;
+ return QMatrix(true);
}
else { // invertible matrix
if (invertible)
*invertible = true;
qreal dinv = 1.0/determinant;
- QMatrix imatrix((_m22*dinv), (-_m12*dinv),
- (-_m21*dinv), (_m11*dinv),
- ((_m21*_dy - _m22*_dx)*dinv),
- ((_m12*_dx - _m11*_dy)*dinv));
- return imatrix;
+ return QMatrix((_m22*dinv), (-_m12*dinv),
+ (-_m21*dinv), (_m11*dinv),
+ ((_m21*_dy - _m22*_dx)*dinv),
+ ((_m12*_dx - _m11*_dy)*dinv),
+ true);
}
}
@@ -1054,9 +1066,14 @@ QMatrix &QMatrix::operator *=(const QMatrix &m)
QMatrix QMatrix::operator *(const QMatrix &m) const
{
- QMatrix result = *this;
- result *= m;
- return result;
+ qreal tm11 = _m11*m._m11 + _m12*m._m21;
+ qreal tm12 = _m11*m._m12 + _m12*m._m22;
+ qreal tm21 = _m21*m._m11 + _m22*m._m21;
+ qreal tm22 = _m21*m._m12 + _m22*m._m22;
+
+ qreal tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
+ qreal tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
+ return QMatrix(tm11, tm12, tm21, tm22, tdx, tdy, true);
}
/*!
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
index bf53c32..1e5fbb4 100644
--- a/src/gui/painting/qmatrix.h
+++ b/src/gui/painting/qmatrix.h
@@ -99,7 +99,7 @@ public:
QMatrix &shear(qreal sh, qreal sv);
QMatrix &rotate(qreal a);
- bool isInvertible() const { return !qFuzzyCompare(_m11*_m22 - _m12*_m21 + 1, 1); }
+ bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); }
qreal det() const { return _m11*_m22 - _m12*_m21; }
QMatrix inverted(bool *invertible = 0) const;
@@ -121,6 +121,20 @@ public:
#endif
private:
+ inline QMatrix(bool)
+ : _m11(1.)
+ , _m12(0.)
+ , _m21(0.)
+ , _m22(1.)
+ , _dx(0.)
+ , _dy(0.) {}
+ inline QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy, bool)
+ : _m11(m11)
+ , _m12(m12)
+ , _m21(m21)
+ , _m22(m22)
+ , _dx(dx)
+ , _dy(dy) {}
friend class QTransform;
qreal _m11, _m12;
qreal _m21, _m22;
@@ -147,8 +161,8 @@ Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m);
inline bool QMatrix::isIdentity() const
{
- return qFuzzyCompare(_m11, 1) && qFuzzyCompare(_m22, 1) && qFuzzyCompare(_m12 + 1, 1)
- && qFuzzyCompare(_m21 + 1, 1) && qFuzzyCompare(_dx + 1, 1) && qFuzzyCompare(_dy + 1, 1);
+ return qFuzzyIsNull(_m11 - 1) && qFuzzyIsNull(_m22 - 1) && qFuzzyIsNull(_m12)
+ && qFuzzyIsNull(_m21) && qFuzzyIsNull(_dx) && qFuzzyIsNull(_dy);
}
/*****************************************************************************
diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/gui/painting/qpaintengine_alpha.cpp
index e38f6a4..74cbebe 100644
--- a/src/gui/painting/qpaintengine_alpha.cpp
+++ b/src/gui/painting/qpaintengine_alpha.cpp
@@ -80,6 +80,7 @@ bool QAlphaPaintEngine::begin(QPaintDevice *pdev)
d->m_advancedPen = false;
d->m_advancedBrush = false;
d->m_complexTransform = false;
+ d->m_emulateProjectiveTransforms = false;
// clear alpha region
d->m_alphargn = QRegion();
@@ -116,6 +117,9 @@ void QAlphaPaintEngine::updateState(const QPaintEngineState &state)
if (flags & QPaintEngine::DirtyTransform) {
d->m_transform = state.transform();
d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale);
+ d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform)
+ && !(d->m_savedcaps & QPaintEngine::AlphaBlend)
+ && (d->m_transform.type() >= QTransform::TxProject);
}
if (flags & QPaintEngine::DirtyPen) {
d->m_pen = state.pen();
@@ -163,7 +167,9 @@ void QAlphaPaintEngine::drawPath(const QPainterPath &path)
if (d->m_pass == 0) {
d->m_continueCall = false;
- if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) {
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
d->addAlphaRect(tr);
}
if (d->m_picengine)
@@ -187,7 +193,9 @@ void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg
if (d->m_pass == 0) {
d->m_continueCall = false;
- if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) {
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
d->addAlphaRect(tr);
}
diff --git a/src/gui/painting/qpaintengine_alpha_p.h b/src/gui/painting/qpaintengine_alpha_p.h
index f510c73..f7d7a34 100644
--- a/src/gui/painting/qpaintengine_alpha_p.h
+++ b/src/gui/painting/qpaintengine_alpha_p.h
@@ -113,6 +113,7 @@ public:
bool m_advancedPen;
bool m_advancedBrush;
bool m_complexTransform;
+ bool m_emulateProjectiveTransforms;
bool m_continueCall;
QTransform m_transform;
diff --git a/src/gui/painting/qpaintengine_d3d.cpp b/src/gui/painting/qpaintengine_d3d.cpp
index bb81623..9a7638b 100644
--- a/src/gui/painting/qpaintengine_d3d.cpp
+++ b/src/gui/painting/qpaintengine_d3d.cpp
@@ -2506,8 +2506,8 @@ void QD3DDrawHelper::addTrap(const Trapezoid &trap)
qreal _rightA = (qreal)_w/_h;
qreal _rightB = topRightX - _rightA * topRightY;
- qreal invLeftA = qFuzzyCompare(_leftA + 1, 1) ? 0.0 : 1.0 / _leftA;
- qreal invRightA = qFuzzyCompare(_rightA + 1, 1) ? 0.0 : 1.0 / _rightA;
+ qreal invLeftA = qFuzzyIsNull(_leftA) ? 0.0 : 1.0 / _leftA;
+ qreal invRightA = qFuzzyIsNull(_rightA) ? 0.0 : 1.0 / _rightA;
vertex v1 = { {1.f, top - 1.f, 0.5f}, 0.f,
top, bottom, invLeftA, -invRightA,
@@ -2970,7 +2970,7 @@ qreal calculateAngle(qreal dx, qreal dy)
{
qreal angle;
- if (qFuzzyCompare(dx + 1, 1)) {
+ if (qFuzzyIsNull(dx)) {
angle = (dy < 0) ? -M_PI/2 : M_PI/2;
} else {
angle = atanf(dy/dx);
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index ba79b5b..8e3d822 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -509,16 +509,20 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
if (d->mono_surface)
d->glyphCacheType = QFontEngineGlyphCache::Raster_Mono;
-#ifdef Q_WS_WIN
- else if (qt_cleartype_enabled) {
+#if defined(Q_WS_WIN)
+ else if (qt_cleartype_enabled)
+#elif defined (Q_WS_MAC)
+ else if (true)
+#else
+ else if (false)
+#endif
+ {
QImage::Format format = static_cast<QImage *>(d->device)->format();
if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
else
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
- }
-#endif
- else
+ } else
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
setActive(true);
@@ -618,22 +622,22 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
d->isPlain45DegreeRotation = false;
if (txop >= QTransform::TxRotate) {
d->isPlain45DegreeRotation =
- (qFuzzyCompare(matrix.m11() + 1, qreal(1))
- && qFuzzyCompare(matrix.m12(), qreal(1))
- && qFuzzyCompare(matrix.m21(), qreal(-1))
- && qFuzzyCompare(matrix.m22() + 1, qreal(1))
+ (qFuzzyIsNull(matrix.m11())
+ && qFuzzyIsNull(matrix.m12() - qreal(1))
+ && qFuzzyIsNull(matrix.m21() + qreal(1))
+ && qFuzzyIsNull(matrix.m22())
)
||
- (qFuzzyCompare(matrix.m11(), qreal(-1))
- && qFuzzyCompare(matrix.m12() + 1, qreal(1))
- && qFuzzyCompare(matrix.m21() + 1, qreal(1))
- && qFuzzyCompare(matrix.m22(), qreal(-1))
+ (qFuzzyIsNull(matrix.m11() + qreal(1))
+ && qFuzzyIsNull(matrix.m12())
+ && qFuzzyIsNull(matrix.m21())
+ && qFuzzyIsNull(matrix.m22() + qreal(1))
)
||
- (qFuzzyCompare(matrix.m11() + 1, qreal(1))
- && qFuzzyCompare(matrix.m12(), qreal(-1))
- && qFuzzyCompare(matrix.m21(), qreal(1))
- && qFuzzyCompare(matrix.m22() + 1, qreal(1))
+ (qFuzzyIsNull(matrix.m11())
+ && qFuzzyIsNull(matrix.m12() + qreal(1))
+ && qFuzzyIsNull(matrix.m21() - qreal(1))
+ && qFuzzyIsNull(matrix.m22())
)
;
}
@@ -1529,7 +1533,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->initializeRasterizer(&s->brushData);
for (int i = 0; i < rectCount; ++i) {
const QRectF &rect = rects[i].normalized();
- if (rects[i].isEmpty())
+ if (rect.isEmpty())
continue;
const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);
@@ -2355,11 +2359,6 @@ void QRasterPaintEngine::strokePolygonCosmetic(const QPoint *points, int pointCo
}
}
-#define IMAGE_FROM_PIXMAP(pixmap) \
- pixmap.data->classId() == QPixmapData::RasterClass \
- ? ((QRasterPixmapData *) pixmap.data)->image \
- : pixmap.toImage()
-
/*!
\internal
*/
@@ -2368,16 +2367,33 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)
#ifdef QT_DEBUG_DRAW
qDebug() << " - QRasterPaintEngine::drawPixmap(), pos=" << pos << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- if (pixmap.depth() == 1) {
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
- if (s->matrix.type() <= QTransform::TxTranslate) {
- drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData);
+
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ const QImage &image = ((QRasterPixmapData *) pixmap.data)->image;
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate) {
+ drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ } else {
+ drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
+ }
} else {
- drawImage(pos, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color()));
+ QRasterPaintEngine::drawImage(pos, image);
}
} else {
- QRasterPaintEngine::drawImage(pos, IMAGE_FROM_PIXMAP(pixmap));
+ const QImage image = pixmap.toImage();
+ if (pixmap.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate) {
+ drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ } else {
+ drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
+ }
+ } else {
+ QRasterPaintEngine::drawImage(pos, image);
+ }
}
}
@@ -2390,22 +2406,40 @@ void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, cons
qDebug() << " - QRasterPaintEngine::drawPixmap(), r=" << r << " sr=" << sr << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- if (pixmap.depth() == 1) {
- if (s->matrix.type() <= QTransform::TxTranslate
- && r.size() == sr.size()
- && r.size() == pixmap.size()) {
- ensurePen();
- drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData);
- return;
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ const QImage &image = ((QRasterPixmapData *) pixmap.data)->image;
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate
+ && r.size() == sr.size()
+ && r.size() == pixmap.size()) {
+ ensurePen();
+ drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ return;
+ } else {
+ drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
+ }
} else {
- drawImage(r, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap),
- s->pen.color()), sr);
+ drawImage(r, image, sr);
}
} else {
- drawImage(r, IMAGE_FROM_PIXMAP(pixmap), sr);
+ const QImage image = pixmap.toImage();
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate
+ && r.size() == sr.size()
+ && r.size() == pixmap.size()) {
+ ensurePen();
+ drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ return;
+ } else {
+ drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
+ }
+ } else {
+ drawImage(r, image, sr);
+ }
}
}
@@ -2614,10 +2648,15 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
QRasterPaintEngineState *s = state();
QImage image;
- if (pixmap.depth() == 1)
- image = d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color());
- else
- image = IMAGE_FROM_PIXMAP(pixmap);
+
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ image = ((QRasterPixmapData *) pixmap.data)->image;
+ } else {
+ image = pixmap.toImage();
+ }
+
+ if (image.depth() == 1)
+ image = d->rasterBuffer->colorizeBitmap(image, s->pen.color());
if (s->matrix.type() > QTransform::TxTranslate) {
QTransform copy = s->matrix;
@@ -3650,14 +3689,13 @@ void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
}
#endif // Q_WS_QWS
-void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpanData *fg)
+void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg)
{
Q_ASSERT(fg);
if (!fg->blend)
return;
Q_D(QRasterPaintEngine);
- const QImage image = IMAGE_FROM_PIXMAP(pm);
Q_ASSERT(image.depth() == 1);
const int spanCount = 256;
@@ -3665,8 +3703,8 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpan
int n = 0;
// Boundaries
- int w = pm.width();
- int h = pm.height();
+ int w = image.width();
+ int h = image.height();
int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height());
int ymin = qMax(qRound(pos.y()), 0);
int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width());
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 0f8060a..26a2b3f 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -256,7 +256,7 @@ private:
void init();
void fillRect(const QRectF &rect, QSpanData *data);
- void drawBitmap(const QPointF &pos, const QPixmap &image, QSpanData *fill);
+ void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti);
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index e9f1bb3..39ce59f 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -62,6 +62,7 @@
#include <private/qpaintengine_x11_p.h>
#include <private/qfontengine_x11_p.h>
#include <private/qwidget_p.h>
+#include <private/qpainterpath_p.h>
#include "qpen.h"
#include "qcolor.h"
@@ -1479,14 +1480,10 @@ void QX11PaintEngine::drawEllipse(const QRect &rect)
return;
}
d->setupAdaptedOrigin(rect.topLeft());
- if (d->has_brush) { // draw filled ellipse
- if (!d->has_pen) {
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
+ if (d->has_brush) { // draw filled ellipse
+ XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
+ if (!d->has_pen) // make smoother outline
XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
- return;
- } else{
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
- }
}
if (d->has_pen) // draw outline
XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
@@ -1760,9 +1757,14 @@ void QX11PaintEngine::drawPath(const QPainterPath &path)
QPainterPath stroke;
qreal width = d->cpen.widthF();
QPolygonF poly;
+ QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height());
// necessary to get aliased alphablended primitives to be drawn correctly
if (d->cpen.isCosmetic() || d->has_scaling_xform) {
- stroker.setWidth(width == 0 ? 1 : width * d->xform_scale);
+ if (d->cpen.isCosmetic())
+ stroker.setWidth(width == 0 ? 1 : width);
+ else
+ stroker.setWidth(width * d->xform_scale);
+ stroker.d_ptr->stroker.setClipRect(deviceRect);
stroke = stroker.createStroke(path * d->matrix);
if (stroke.isEmpty())
return;
@@ -1770,6 +1772,7 @@ void QX11PaintEngine::drawPath(const QPainterPath &path)
d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false);
} else {
stroker.setWidth(width);
+ stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect));
stroke = stroker.createStroke(path);
if (stroke.isEmpty())
return;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index e2d9b32..82c22c2 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1293,7 +1293,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
destination.
Note that composition transformation operates pixelwise. For that
- reason, there is a difference between using the grahic primitive
+ reason, there is a difference between using the graphic primitive
itself and its bounding rectangle: The bounding rect contains
pixels with alpha == 0 (i.e the pixels surrounding the
primitive). These pixels will overwrite the other image's pixels,
@@ -1465,8 +1465,8 @@ bool QPainter::isActive() const
/*!
Initializes the painters pen, background and font to the same as
- the given \a widget. Call this function after begin() while the
- painter is active.
+ the given \a widget. This function is called automatically when the
+ painter is opened on a QWidget.
\sa begin(), {QPainter#Settings}{Settings}
*/
@@ -2371,6 +2371,11 @@ void QPainter::setClipping(bool enable)
Returns the currently set clip region. Note that the clip region
is given in logical coordinates.
+ \warning QPainter does not store the combined clip explicitly as
+ this is handled by the underlying QPaintEngine, so the path is
+ recreated on demand and transformed to the current logical
+ coordinate system. This is potentially an expensive operation.
+
\sa setClipRegion(), clipPath(), setClipping()
*/
@@ -2486,6 +2491,11 @@ extern QPainterPath qt_regionToPath(const QRegion &region);
Returns the currently clip as a path. Note that the clip path is
given in logical coordinates.
+ \warning QPainter does not store the combined clip explicitly as
+ this is handled by the underlying QPaintEngine, so the path is
+ recreated on demand and transformed to the current logical
+ coordinate system. This is potentially an expensive operation.
+
\sa setClipPath(), clipRegion(), setClipping()
*/
QPainterPath QPainter::clipPath() const
@@ -5155,9 +5165,6 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
Q_D(QPainter);
- if (!d->engine || pm.isNull())
- return;
-
#ifndef QT_NO_DEBUG
qt_painter_thread_test(d->device->devType(), "drawPixmap()");
#endif
@@ -5167,12 +5174,18 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
return;
}
+ if (!d->engine)
+ return;
+
qreal x = p.x();
qreal y = p.y();
int w = pm.width();
int h = pm.height();
+ if (w <= 0)
+ return;
+
// Emulate opaque background for bitmaps
if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
@@ -6042,22 +6055,22 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
const QTransform &m = d->state->matrix;
if (d->state->matrix.type() < QTransform::TxShear) {
bool isPlain90DegreeRotation =
- (qFuzzyCompare(m.m11() + 1, qreal(1))
- && qFuzzyCompare(m.m12(), qreal(1))
- && qFuzzyCompare(m.m21(), qreal(-1))
- && qFuzzyCompare(m.m22() + 1, qreal(1))
+ (qFuzzyIsNull(m.m11())
+ && qFuzzyIsNull(m.m12() - qreal(1))
+ && qFuzzyIsNull(m.m21() + qreal(1))
+ && qFuzzyIsNull(m.m22())
)
||
- (qFuzzyCompare(m.m11(), qreal(-1))
- && qFuzzyCompare(m.m12() + 1, qreal(1))
- && qFuzzyCompare(m.m21() + 1, qreal(1))
- && qFuzzyCompare(m.m22(), qreal(-1))
+ (qFuzzyIsNull(m.m11() + qreal(1))
+ && qFuzzyIsNull(m.m12())
+ && qFuzzyIsNull(m.m21())
+ && qFuzzyIsNull(m.m22() + qreal(1))
)
||
- (qFuzzyCompare(m.m11() + 1, qreal(1))
- && qFuzzyCompare(m.m12(), qreal(-1))
- && qFuzzyCompare(m.m21(), qreal(1))
- && qFuzzyCompare(m.m22() + 1, qreal(1))
+ (qFuzzyIsNull(m.m11())
+ && qFuzzyIsNull(m.m12() + qreal(1))
+ && qFuzzyIsNull(m.m21() - qreal(1))
+ && qFuzzyIsNull(m.m22())
)
;
aa = !isPlain90DegreeRotation;
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 0d985c3..d471aaa 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1299,10 +1299,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b)
qreal bx = QT_BEZIER_B(b, x);
qreal cx = QT_BEZIER_C(b, x);
// specialcase quadratic curves to avoid div by zero
- if (qFuzzyCompare(ax + 1, 1)) {
+ if (qFuzzyIsNull(ax)) {
// linear curves are covered by initialization.
- if (!qFuzzyCompare(bx + 1, 1)) {
+ if (!qFuzzyIsNull(bx)) {
qreal t = -cx / bx;
QT_BEZIER_CHECK_T(b, t);
}
@@ -1329,10 +1329,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b)
qreal cy = QT_BEZIER_C(b, y);
// specialcase quadratic curves to avoid div by zero
- if (qFuzzyCompare(ay + 1, 1)) {
+ if (qFuzzyIsNull(ay)) {
// linear curves are covered by initialization.
- if (!qFuzzyCompare(by + 1, 1)) {
+ if (!qFuzzyIsNull(by)) {
qreal t = -cy / by;
QT_BEZIER_CHECK_T(b, t);
}
@@ -1725,7 +1725,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
*/
bool QPainterPath::contains(const QPointF &pt) const
{
- if (isEmpty())
+ if (isEmpty() || !controlPointRect().contains(pt))
return false;
QPainterPathData *d = d_func();
@@ -2443,21 +2443,13 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y,
\sa QPen, QBrush
*/
-class QPainterPathStrokerPrivate
+QPainterPathStrokerPrivate::QPainterPathStrokerPrivate()
+ : dashOffset(0)
{
-public:
- QPainterPathStrokerPrivate()
- : dashOffset(0)
- {
- stroker.setMoveToHook(qt_path_stroke_move_to);
- stroker.setLineToHook(qt_path_stroke_line_to);
- stroker.setCubicToHook(qt_path_stroke_cubic_to);
- }
-
- QStroker stroker;
- QVector<qfixed> dashPattern;
- qreal dashOffset;
-};
+ stroker.setMoveToHook(qt_path_stroke_move_to);
+ stroker.setLineToHook(qt_path_stroke_line_to);
+ stroker.setCubicToHook(qt_path_stroke_cubic_to);
+}
/*!
Creates a new stroker.
@@ -2501,6 +2493,7 @@ QPainterPath QPainterPathStroker::createStroke(const QPainterPath &path) const
QDashStroker dashStroker(&d->stroker);
dashStroker.setDashPattern(d->dashPattern);
dashStroker.setDashOffset(d->dashOffset);
+ dashStroker.setClipRect(d->stroker.clipRect());
dashStroker.strokePath(path, &stroke, QTransform());
}
stroke.setFillRule(Qt::WindingFill);
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index 56d783d..e343a28 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -283,6 +283,8 @@ public:
QPainterPath createStroke(const QPainterPath &path) const;
private:
+ friend class QX11PaintEngine;
+
QPainterPathStrokerPrivate *d_ptr;
};
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index 93f9704..29c48df 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -61,9 +61,20 @@
#include <qdebug.h>
#include <private/qvectorpath_p.h>
+#include <private/qstroker_p.h>
QT_BEGIN_NAMESPACE
+class QPainterPathStrokerPrivate
+{
+public:
+ QPainterPathStrokerPrivate();
+
+ QStroker stroker;
+ QVector<qfixed> dashPattern;
+ qreal dashOffset;
+};
+
class QPolygonF;
class QVectorPathConverter;
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 297cdd3..9ef3eb7 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -138,11 +138,11 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x();
- if (qFuzzyCompare(par + 1, 1)) {
+ if (qFuzzyIsNull(par)) {
const QPointF normal(-pDelta.y(), pDelta.x());
// coinciding?
- if (qFuzzyCompare(dot(normal, q1 - p1) + 1, 1)) {
+ if (qFuzzyIsNull(dot(normal, q1 - p1))) {
const qreal dp = dot(pDelta, pDelta);
const qreal tq1 = dot(pDelta, q1 - p1);
@@ -202,13 +202,13 @@ void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &tw
qreal alpha_q = t.at(i).second;
QPointF pt;
- if (qFuzzyCompare(alpha_p + 1, 1)) {
+ if (qFuzzyIsNull(alpha_p)) {
pt = one.pt1();
- } else if (qFuzzyCompare(alpha_p, 1)) {
+ } else if (qFuzzyIsNull(alpha_p - 1)) {
pt = one.pt4();
- } else if (qFuzzyCompare(alpha_q + 1, 1)) {
+ } else if (qFuzzyIsNull(alpha_q)) {
pt = two.pt1();
- } else if (qFuzzyCompare(alpha_q, 1)) {
+ } else if (qFuzzyIsNull(alpha_q - 1)) {
pt = two.pt4();
} else {
pt = one.pointAt(alpha_p);
@@ -250,11 +250,11 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData
const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x();
- if (qFuzzyCompare(par + 1, 1)) {
+ if (qFuzzyIsNull(par)) {
const QPointF normal(-pDelta.y(), pDelta.x());
// coinciding?
- if (qFuzzyCompare(dot(normal, q1 - p1) + 1, 1)) {
+ if (qFuzzyIsNull(dot(normal, q1 - p1))) {
const qreal invDp = 1 / dot(pDelta, pDelta);
const qreal tq1 = dot(pDelta, q1 - p1) * invDp;
@@ -315,11 +315,11 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData
if (tp<0 || tp>1 || tq<0 || tq>1)
return;
- const bool p_zero = qFuzzyCompare(tp + 1, 1);
- const bool p_one = qFuzzyCompare(tp, 1);
+ const bool p_zero = qFuzzyIsNull(tp);
+ const bool p_one = qFuzzyIsNull(tp - 1);
- const bool q_zero = qFuzzyCompare(tq + 1, 1);
- const bool q_one = qFuzzyCompare(tq, 1);
+ const bool q_zero = qFuzzyIsNull(tq);
+ const bool q_one = qFuzzyIsNull(tq - 1);
if ((q_zero || q_one) && (p_zero || p_one))
return;
@@ -922,7 +922,7 @@ qreal QWingedEdge::delta(int vertex, int a, int b) const
qreal result = b_angle - a_angle;
- if (qFuzzyCompare(result + 1, 1) || qFuzzyCompare(result, 128))
+ if (qFuzzyIsNull(result) || qFuzzyCompare(result, 128))
return 0;
if (result < 0)
@@ -951,7 +951,7 @@ static inline QPointF tangentAt(const QWingedEdge &list, int vi, int ei)
if (ep->bezier) {
normal = ep->bezier->derivedAt(t);
- if (qFuzzyCompare(normal.x() + 1, 1) && qFuzzyCompare(normal.y() + 1, 1))
+ if (qFuzzyIsNull(normal.x()) && qFuzzyIsNull(normal.y()))
normal = ep->bezier->secondDerivedAt(t);
} else {
const QPointF a = *list.vertex(ep->first);
@@ -1080,7 +1080,7 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
qDebug() << "Delta to edge" << status.edge << d2 << ", angles: " << op->angle << op->invAngle;
#endif
- if (!(qFuzzyCompare(d2 + 1, 1) && isLeftOf(*this, vi, status.edge, ei))
+ if (!(qFuzzyIsNull(d2) && isLeftOf(*this, vi, status.edge, ei))
&& (d2 < d || (qFuzzyCompare(d2, d) && isLeftOf(*this, vi, status.edge, position)))) {
position = status.edge;
d = d2;
@@ -1232,10 +1232,10 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal
QPointF aTangent = bezier->derivedAt(t0);
QPointF bTangent = -bezier->derivedAt(t1);
- if (qFuzzyCompare(aTangent.x() + 1, 1) && qFuzzyCompare(aTangent.y() + 1, 1))
+ if (qFuzzyIsNull(aTangent.x()) && qFuzzyIsNull(aTangent.y()))
aTangent = bezier->secondDerivedAt(t0);
- if (qFuzzyCompare(bTangent.x() + 1, 1) && qFuzzyCompare(bTangent.y() + 1, 1))
+ if (qFuzzyIsNull(bTangent.x()) && qFuzzyIsNull(bTangent.y()))
bTangent = bezier->secondDerivedAt(t1);
ep->angle = computeAngle(aTangent);
@@ -1400,7 +1400,7 @@ static void addLineTo(QPainterPath &path, const QPointF &point)
const QPointF p(-d1.y(), d1.x());
- if (qFuzzyCompare(dot(p, d2) + 1, 1)) {
+ if (qFuzzyIsNull(dot(p, d2))) {
path.setElementPositionAt(elementCount - 1, point.x(), point.y());
return;
}
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index b010209..55006f6 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1106,6 +1106,11 @@ void QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
if (!d->hasPen || (d->clipEnabled && d->allClipped))
return;
+ if (d->stroker.matrix.type() >= QTransform::TxProject) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
*d->currentPage << "q\n";
if(!d->simplePen)
*d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
diff --git a/src/gui/painting/qprintengine_mac.mm b/src/gui/painting/qprintengine_mac.mm
index 7a77e47..b1216b7 100644
--- a/src/gui/painting/qprintengine_mac.mm
+++ b/src/gui/painting/qprintengine_mac.mm
@@ -62,6 +62,10 @@ bool QMacPrintEngine::begin(QPaintDevice *dev)
{
Q_D(QMacPrintEngine);
+ Q_ASSERT(dev && dev->devType() == QInternal::Printer);
+ if (!static_cast<QPrinter *>(dev)->isValid())
+ return false;
+
if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize
d->initialize();
@@ -121,24 +125,8 @@ bool QMacPrintEngine::end()
if(d->paintEngine->type() == QPaintEngine::CoreGraphics)
static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0;
d->paintEngine->end();
- if (d->state != QPrinter::Idle) {
-#ifndef QT_MAC_USE_COCOA
- if (d->shouldSuppressStatus()) {
- PMSessionEndPageNoDialog(d->session);
- PMSessionEndDocumentNoDialog(d->session);
- } else {
- PMSessionEndPage(d->session);
- PMSessionEndDocument(d->session);
- }
- PMRelease(d->session);
-#else
- PMSessionEndPageNoDialog(d->session);
- PMSessionEndDocumentNoDialog(d->session);
- [d->printInfo release];
-#endif
- d->printInfo = 0;
- d->session = 0;
- }
+ if (d->state != QPrinter::Idle)
+ d->releaseSession();
d->state = QPrinter::Idle;
return true;
}
@@ -509,6 +497,26 @@ void QMacPrintEnginePrivate::initialize()
}
}
+void QMacPrintEnginePrivate::releaseSession()
+{
+#ifndef QT_MAC_USE_COCOA
+ if (shouldSuppressStatus()) {
+ PMSessionEndPageNoDialog(session);
+ PMSessionEndDocumentNoDialog(session);
+ } else {
+ PMSessionEndPage(session);
+ PMSessionEndDocument(session);
+ }
+ PMRelease(session);
+#else
+ PMSessionEndPageNoDialog(session);
+ PMSessionEndDocumentNoDialog(session);
+ [printInfo release];
+#endif
+ printInfo = 0;
+ session = 0;
+}
+
bool QMacPrintEnginePrivate::newPage_helper()
{
Q_Q(QMacPrintEngine);
@@ -737,6 +745,7 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->setPaperSize(QPrinter::PaperSize(value.toInt()));
break;
case PPK_PrinterName: {
+ bool printerNameSet = false;
OSStatus status = noErr;
QCFType<CFArrayRef> printerList;
status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
@@ -747,12 +756,18 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
QString name = QCFString::toQString(PMPrinterGetName(printer));
if (name == value.toString()) {
status = PMSessionSetCurrentPMPrinter(d->session, printer);
+ printerNameSet = true;
break;
}
}
}
if (status != noErr)
qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
+ if (!printerNameSet) {
+ qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString()));
+ d->releaseSession();
+ d->state = QPrinter::Idle;
+ }
break; }
case PPK_SuppressSystemPrintStatus:
d->suppressStatus = value.toBool();
@@ -876,17 +891,12 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
ret = r;
break; }
case PPK_PrinterName: {
- CFIndex currIndex;
- PMPrinter unused;
- QCFType<CFArrayRef> printerList;
- OSStatus status = PMSessionCreatePrinterList(d->session, &printerList, &currIndex, &unused);
+ PMPrinter printer;
+ OSStatus status = PMSessionGetCurrentPrinter(d->session, &printer);
if (status != noErr)
- qWarning("QMacPrintEngine::printerName: Problem getting list of printers: %ld", long(status));
- if (currIndex != -1 && printerList && currIndex < CFArrayGetCount(printerList)) {
- const CFStringRef name = static_cast<CFStringRef>(CFArrayGetValueAtIndex(printerList, currIndex));
- if (name)
- ret = QCFString::toQString(name);
- }
+ qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status));
+ if (printer)
+ ret = QCFString::toQString(PMPrinterGetName(printer));
break; }
case PPK_Resolution: {
ret = d->resolution.hRes;
diff --git a/src/gui/painting/qprintengine_mac_p.h b/src/gui/painting/qprintengine_mac_p.h
index 5e18845..bc917e7 100644
--- a/src/gui/painting/qprintengine_mac_p.h
+++ b/src/gui/painting/qprintengine_mac_p.h
@@ -143,6 +143,7 @@ public:
hasCustomPaperSize(false), hasCustomPageMargins(false) {}
~QMacPrintEnginePrivate();
void initialize();
+ void releaseSession();
bool newPage_helper();
void setPaperSize(QPrinter::PaperSize ps);
QPrinter::PaperSize paperSize() const;
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp
index d48b525..c8674b7 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/gui/painting/qprintengine_win.cpp
@@ -369,7 +369,7 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem
QRgb brushColor = state->pen().brush().color().rgb();
bool fallBack = state->pen().brush().style() != Qt::SolidPattern
|| qAlpha(brushColor) != 0xff
- || QT_WA_INLINE(false, d->txop >= QTransform::TxScale)
+ || QT_WA_INLINE(d->txop >= QTransform::TxProject, d->txop >= QTransform::TxScale)
|| ti.fontEngine->type() != QFontEngine::Win;
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index 413f4a1..4f3e71c 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -284,6 +284,10 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke
to send PostScript or PDF output to the printer. As an alternative,
the printProgram() function can be used to specify the command or utility
to use instead of the system default.
+
+ Note that setting parameters like paper size and resolution on an
+ invalid printer is undefined. You can use QPrinter::isValid() to
+ verify this before changing any parameters.
QPrinter supports a number of parameters, most of which can be
changed by the end user through a \l{QPrintDialog}{print dialog}. In
@@ -849,7 +853,7 @@ void QPrinter::setPrinterName(const QString &name)
Returns true if the printer currently selected is a valid printer
in the system, or a pure PDF/PostScript printer; otherwise returns false.
- To detect other failures check the output of QPainter::begin() or QPainter::nextPage().
+ To detect other failures check the output of QPainter::begin() or QPrinter::newPage().
\snippet doc/src/snippets/printing-qprinter/errors.cpp 0
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index 8169ef8..c88af7c 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -65,9 +65,17 @@ QT_BEGIN_NAMESPACE
\ingroup shared
QRegion is used with QPainter::setClipRegion() to limit the paint
- area to what needs to be painted. There is also a
- QWidget::repaint() function that takes a QRegion parameter.
- QRegion is the best tool for reducing flicker.
+ area to what needs to be painted. There is also a QWidget::repaint()
+ function that takes a QRegion parameter. QRegion is the best tool for
+ minimizing the amount of screen area to be updated by a repaint.
+
+ This class is not suitable for constructing shapes for rendering, especially
+ as outlines. Use QPainterPath to create paths and shapes for use with
+ QPainter.
+
+ QRegion is an \l{implicitly shared} class.
+
+ \section1 Creating and Using Regions
A region can be created from a rectangle, an ellipse, a polygon or
a bitmap. Complex regions may be created by combining simple
@@ -84,8 +92,6 @@ QT_BEGIN_NAMESPACE
Example of using complex regions:
\snippet doc/src/snippets/code/src_gui_painting_qregion.cpp 0
- QRegion is an \l{implicitly shared} class.
-
\warning Due to window system limitations, the whole coordinate space for a
region is limited to the points between -32767 and 32767 on Windows
95/98/ME. You can circumvent this limitation by using a QPainterPath.
@@ -93,7 +99,7 @@ QT_BEGIN_NAMESPACE
\section1 Additional License Information
On Embedded Linux, Windows CE and X11 platforms, parts of this class rely on
- code obtained under the following license:
+ code obtained under the following licenses:
\legalese
Copyright (c) 1987 X Consortium
@@ -120,9 +126,7 @@ QT_BEGIN_NAMESPACE
in this Software without prior written authorization from the X Consortium.
\endlegalese
- \raw HTML
- <hr />
- \endraw
+ \br
\legalese
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index b894c62..5fffc72 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -763,7 +763,7 @@ template <class Iterator> bool qt_stroke_side(Iterator *it,
qreal qt_t_for_arc_angle(qreal angle)
{
- if (qFuzzyCompare(angle + 1, qreal(1)))
+ if (qFuzzyIsNull(angle))
return 0;
if (qFuzzyCompare(angle, qreal(90)))
@@ -904,13 +904,13 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt
}
// avoid empty start segment
- if (qFuzzyCompare(startT, qreal(1))) {
+ if (qFuzzyIsNull(startT - qreal(1))) {
startT = 0;
startSegment += delta;
}
// avoid empty end segment
- if (qFuzzyCompare(endT + 1, qreal(1))) {
+ if (qFuzzyIsNull(endT)) {
endT = 1;
endSegment -= delta;
}
@@ -918,8 +918,8 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt
startT = qt_t_for_arc_angle(startT * 90);
endT = qt_t_for_arc_angle(endT * 90);
- const bool splitAtStart = !qFuzzyCompare(startT + 1, qreal(1));
- const bool splitAtEnd = !qFuzzyCompare(endT, qreal(1));
+ const bool splitAtStart = !qFuzzyIsNull(startT);
+ const bool splitAtEnd = !qFuzzyIsNull(endT - qreal(1));
const int end = endSegment + delta;
@@ -1018,7 +1018,7 @@ void QDashStroker::processCurrentSubpath()
sumLength += dashes[i];
}
- if (qFuzzyCompare(sumLength + 1, qreal(1)))
+ if (qFuzzyIsNull(sumLength))
return;
Q_ASSERT(dashCount > 0);
diff --git a/src/gui/painting/qtessellator.cpp b/src/gui/painting/qtessellator.cpp
index e02f02d..ce5ab74 100644
--- a/src/gui/painting/qtessellator.cpp
+++ b/src/gui/painting/qtessellator.cpp
@@ -1436,7 +1436,7 @@ void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal wi
QPointF perp(pb.y() - pa.y(), pa.x() - pb.x());
qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y());
- if (qFuzzyCompare(length + 1, static_cast<qreal>(1)))
+ if (qFuzzyIsNull(length))
return;
// need the half of the width
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 39b3319..d06107f 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -168,10 +168,10 @@ QT_BEGIN_NAMESPACE
\image qtransform-representation.png
- A QTransform object contains a 3 x 3 matrix. The \c dx and \c dy
- elements specify horizontal and vertical translation. The \c m11
- and \c m22 elements specify horizontal and vertical scaling. The
- \c m21 and \c m12 elements specify horizontal and vertical \e shearing.
+ A QTransform object contains a 3 x 3 matrix. The \c m31 (\c dx) and
+ \c m32 (\c dy) elements specify horizontal and vertical translation.
+ The \c m11 and \c m22 elements specify horizontal and vertical scaling.
+ The \c m21 and \c m12 elements specify horizontal and vertical \e shearing.
And finally, the \c m13 and \c m23 elements specify horizontal and vertical
projection, with \c m33 as an additional projection factor.
@@ -238,44 +238,45 @@ QT_BEGIN_NAMESPACE
\sa reset()
*/
QTransform::QTransform()
- : m_13(0), m_23(0), m_33(1)
+ : affine(true)
+ , m_13(0), m_23(0), m_33(1)
, m_type(TxNone)
, m_dirty(TxNone)
{
-
}
/*!
- Constructs a matrix with the elements, \a h11, \a h12, \a h13,
- \a h21, \a h22, \a h23, \a h31, \a h32, \a h33.
+ \fn QTransform::QTransform(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33)
+
+ Constructs a matrix with the elements, \a m11, \a m12, \a m13,
+ \a m21, \a m22, \a m23, \a m31, \a m32, \a m33.
\sa setMatrix()
*/
QTransform::QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33)
- : affine(h11, h12, h21, h22, h31, h32),
- m_13(h13), m_23(h23), m_33(h33)
+ : affine(h11, h12, h21, h22, h31, h32, true)
+ , m_13(h13), m_23(h23), m_33(h33)
, m_type(TxNone)
, m_dirty(TxProject)
{
-
}
/*!
- Constructs a matrix with the elements, \a h11, \a h12, \a h21, \a
- h22, \a dx and \a dy.
+ \fn QTransform::QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
+
+ Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a m22, \a dx and \a dy.
\sa setMatrix()
*/
QTransform::QTransform(qreal h11, qreal h12, qreal h21,
qreal h22, qreal dx, qreal dy)
- : affine(h11, h12, h21, h22, dx, dy),
- m_13(0), m_23(0), m_33(1)
+ : affine(h11, h12, h21, h22, dx, dy, true)
+ , m_13(0), m_23(0), m_33(1)
, m_type(TxNone)
, m_dirty(TxShear)
{
-
}
/*!
@@ -286,12 +287,11 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h21,
and 1 respectively.
*/
QTransform::QTransform(const QMatrix &mtx)
- : affine(mtx),
+ : affine(mtx._m11, mtx._m12, mtx._m21, mtx._m22, mtx._dx, mtx._dy, true),
m_13(0), m_23(0), m_33(1)
, m_type(TxNone)
, m_dirty(TxShear)
{
-
}
/*!
@@ -314,7 +314,7 @@ QTransform QTransform::adjoint() const
return QTransform(h11, h12, h13,
h21, h22, h23,
- h31, h32, h33);
+ h31, h32, h33, true);
}
/*!
@@ -324,7 +324,7 @@ QTransform QTransform::transposed() const
{
QTransform t(affine._m11, affine._m21, affine._dx,
affine._m12, affine._m22, affine._dy,
- m_13, m_23, m_33);
+ m_13, m_23, m_33, true);
t.m_type = m_type;
t.m_dirty = m_dirty;
return t;
@@ -342,11 +342,10 @@ QTransform QTransform::transposed() const
*/
QTransform QTransform::inverted(bool *invertible) const
{
- QTransform invert;
+ QTransform invert(true);
bool inv = true;
- qreal det;
- switch(type()) {
+ switch(inline_type()) {
case TxNone:
break;
case TxTranslate:
@@ -354,11 +353,11 @@ QTransform QTransform::inverted(bool *invertible) const
invert.affine._dy = -affine._dy;
break;
case TxScale:
- inv = !qFuzzyCompare(affine._m11 + 1, 1);
- inv &= !qFuzzyCompare(affine._m22 + 1, 1);
+ inv = !qFuzzyIsNull(affine._m11);
+ inv &= !qFuzzyIsNull(affine._m22);
if (inv) {
- invert.affine._m11 = 1 / affine._m11;
- invert.affine._m22 = 1 / affine._m22;
+ invert.affine._m11 = 1. / affine._m11;
+ invert.affine._m22 = 1. / affine._m22;
invert.affine._dx = -affine._dx * invert.affine._m11;
invert.affine._dy = -affine._dy * invert.affine._m22;
}
@@ -369,8 +368,8 @@ QTransform QTransform::inverted(bool *invertible) const
break;
default:
// general case
- det = determinant();
- inv = !qFuzzyCompare(det + 1, 1);
+ qreal det = determinant();
+ inv = !qFuzzyIsNull(det);
if (inv)
invert = adjoint() / det;
break;
@@ -394,12 +393,12 @@ QTransform QTransform::inverted(bool *invertible) const
\sa setMatrix()
*/
-QTransform & QTransform::translate(qreal dx, qreal dy)
+QTransform &QTransform::translate(qreal dx, qreal dy)
{
if (dx == 0 && dy == 0)
return *this;
- switch(type()) {
+ switch(inline_type()) {
case TxNone:
affine._dx = dx;
affine._dy = dy;
@@ -434,7 +433,7 @@ QTransform & QTransform::translate(qreal dx, qreal dy)
*/
QTransform QTransform::fromTranslate(qreal dx, qreal dy)
{
- QTransform transform(1, 0, 0, 1, dx, dy);
+ QTransform transform(1, 0, 0, 0, 1, 0, dx, dy, 1, true);
if (dx == 0 && dy == 0)
transform.m_dirty = TxNone;
else
@@ -453,7 +452,7 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
if (sx == 1 && sy == 1)
return *this;
- switch(type()) {
+ switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m11 = sx;
@@ -486,8 +485,8 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
*/
QTransform QTransform::fromScale(qreal sx, qreal sy)
{
- QTransform transform(sx, 0, 0, sy, 0, 0);
- if (sx == 1 && sy == 1)
+ QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1, true);
+ if (sx == 1. && sy == 1.)
transform.m_dirty = TxNone;
else
transform.m_dirty = TxScale;
@@ -502,7 +501,7 @@ QTransform QTransform::fromScale(qreal sx, qreal sy)
*/
QTransform & QTransform::shear(qreal sh, qreal sv)
{
- switch(type()) {
+ switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m12 = sv;
@@ -571,7 +570,7 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
}
if (axis == Qt::ZAxis) {
- switch(type()) {
+ switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m11 = cosa;
@@ -643,7 +642,7 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
qreal cosa = qCos(a);
if (axis == Qt::ZAxis) {
- switch(type()) {
+ switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m11 = cosa;
@@ -727,11 +726,11 @@ bool QTransform::operator!=(const QTransform &o) const
*/
QTransform & QTransform::operator*=(const QTransform &o)
{
- const TransformationType otherType = o.type();
+ const TransformationType otherType = o.inline_type();
if (otherType == TxNone)
return *this;
- const TransformationType thisType = type();
+ const TransformationType thisType = inline_type();
if (thisType == TxNone)
return operator=(o);
@@ -809,9 +808,77 @@ QTransform & QTransform::operator*=(const QTransform &o)
*/
QTransform QTransform::operator*(const QTransform &m) const
{
- QTransform result = *this;
- result *= m;
- return result;
+ const TransformationType otherType = m.inline_type();
+ if (otherType == TxNone)
+ return *this;
+
+ const TransformationType thisType = inline_type();
+ if (thisType == TxNone)
+ return m;
+
+ QTransform t(true);
+ TransformationType type = qMax(thisType, otherType);
+ switch(type) {
+ case TxNone:
+ break;
+ case TxTranslate:
+ t.affine._dx = affine._dx + m.affine._dx;
+ t.affine._dy += affine._dy + m.affine._dy;
+ break;
+ case TxScale:
+ {
+ qreal m11 = affine._m11*m.affine._m11;
+ qreal m22 = affine._m22*m.affine._m22;
+
+ qreal m31 = affine._dx*m.affine._m11 + m.affine._dx;
+ qreal m32 = affine._dy*m.affine._m22 + m.affine._dy;
+
+ t.affine._m11 = m11;
+ t.affine._m22 = m22;
+ t.affine._dx = m31; t.affine._dy = m32;
+ break;
+ }
+ case TxRotate:
+ case TxShear:
+ {
+ qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21;
+ qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22;
+
+ qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21;
+ qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22;
+
+ qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx;
+ qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy;
+
+ t.affine._m11 = m11; t.affine._m12 = m12;
+ t.affine._m21 = m21; t.affine._m22 = m22;
+ t.affine._dx = m31; t.affine._dy = m32;
+ break;
+ }
+ case TxProject:
+ {
+ qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx;
+ qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy;
+ qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33;
+
+ qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx;
+ qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy;
+ qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33;
+
+ qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx;
+ qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy;
+ qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33;
+
+ t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13;
+ t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23;
+ t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33;
+ }
+ }
+
+ t.m_dirty = type;
+ t.m_type = type;
+
+ return t;
}
/*!
@@ -973,7 +1040,7 @@ QPoint QTransform::map(const QPoint &p) const
qreal x = 0, y = 0;
- TransformationType t = type();
+ TransformationType t = inline_type();
switch(t) {
case TxNone:
x = fx;
@@ -1024,7 +1091,7 @@ QPointF QTransform::map(const QPointF &p) const
qreal x = 0, y = 0;
- TransformationType t = type();
+ TransformationType t = inline_type();
switch(t) {
case TxNone:
x = fx;
@@ -1095,7 +1162,7 @@ QLine QTransform::map(const QLine &l) const
qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- TransformationType t = type();
+ TransformationType t = inline_type();
switch(t) {
case TxNone:
x1 = fx1;
@@ -1154,7 +1221,7 @@ QLineF QTransform::map(const QLineF &l) const
qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- TransformationType t = type();
+ TransformationType t = inline_type();
switch(t) {
case TxNone:
x1 = fx1;
@@ -1242,7 +1309,7 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol
*/
QPolygonF QTransform::map(const QPolygonF &a) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
if (t <= TxTranslate)
return a.translated(affine._dx, affine._dy);
@@ -1272,7 +1339,7 @@ QPolygonF QTransform::map(const QPolygonF &a) const
*/
QPolygon QTransform::map(const QPolygon &a) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
if (t <= TxTranslate)
return a.translated(qRound(affine._dx), qRound(affine._dy));
@@ -1317,7 +1384,7 @@ extern QPainterPath qt_regionToPath(const QRegion &region);
*/
QRegion QTransform::map(const QRegion &r) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
if (t == TxNone)
return r;
if (t == TxTranslate) {
@@ -1340,7 +1407,7 @@ struct QHomogeneousCoordinate
QHomogeneousCoordinate(qreal x_, qreal y_, qreal w_) : x(x_), y(y_), w(w_) {}
const QPointF toPoint() const {
- qreal iw = 1 / w;
+ qreal iw = 1. / w;
return QPointF(x * iw, y * iw);
}
};
@@ -1478,7 +1545,7 @@ static QPainterPath mapProjective(const QTransform &transform, const QPainterPat
*/
QPainterPath QTransform::map(const QPainterPath &path) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
if (t == TxNone || path.isEmpty())
return path;
@@ -1523,7 +1590,7 @@ QPainterPath QTransform::map(const QPainterPath &path) const
*/
QPolygon QTransform::mapToPolygon(const QRect &rect) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
QPolygon a(4);
qreal x[4] = { 0, 0, 0, 0 }, y[4] = { 0, 0, 0, 0 };
@@ -1697,7 +1764,7 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13,
QRect QTransform::mapRect(const QRect &rect) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
if (t <= TxTranslate)
return rect.translated(qRound(affine._dx), qRound(affine._dy));
@@ -1717,13 +1784,12 @@ QRect QTransform::mapRect(const QRect &rect) const
return QRect(x, y, w, h);
} else if (t < TxProject) {
// see mapToPolygon for explanations of the algorithm.
- qreal x0 = 0, y0 = 0;
- qreal x, y;
- MAP(rect.left(), rect.top(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
+ qreal x = 0, y = 0;
+ MAP(rect.left(), rect.top(), x, y);
+ qreal xmin = x;
+ qreal ymin = y;
+ qreal xmax = x;
+ qreal ymax = y;
MAP(rect.right() + 1, rect.top(), x, y);
xmin = qMin(xmin, x);
ymin = qMin(ymin, y);
@@ -1768,7 +1834,7 @@ QRect QTransform::mapRect(const QRect &rect) const
*/
QRectF QTransform::mapRect(const QRectF &rect) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
if (t <= TxTranslate)
return rect.translated(affine._dx, affine._dy);
@@ -1787,13 +1853,12 @@ QRectF QTransform::mapRect(const QRectF &rect) const
}
return QRectF(x, y, w, h);
} else if (t < TxProject) {
- qreal x0 = 0, y0 = 0;
- qreal x, y;
- MAP(rect.x(), rect.y(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
+ qreal x = 0, y = 0;
+ MAP(rect.x(), rect.y(), x, y);
+ qreal xmin = x;
+ qreal ymin = y;
+ qreal xmax = x;
+ qreal ymax = y;
MAP(rect.x() + rect.width(), rect.y(), x, y);
xmin = qMin(xmin, x);
ymin = qMin(ymin, y);
@@ -1843,7 +1908,7 @@ QRectF QTransform::mapRect(const QRectF &rect) const
*/
void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
MAP(x, y, *tx, *ty);
}
@@ -1857,7 +1922,7 @@ void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const
*/
void QTransform::map(int x, int y, int *tx, int *ty) const
{
- TransformationType t = type();
+ TransformationType t = inline_type();
qreal fx = 0, fy = 0;
MAP(x, y, fx, fy);
*tx = qRound(fx);
@@ -1886,25 +1951,41 @@ const QMatrix &QTransform::toAffine() const
*/
QTransform::TransformationType QTransform::type() const
{
- if (m_dirty >= m_type) {
- if (m_dirty > TxShear && (!qFuzzyCompare(m_13 + 1, 1) || !qFuzzyCompare(m_23 + 1, 1)))
+ if(m_dirty == TxNone || m_dirty < m_type)
+ return static_cast<TransformationType>(m_type);
+
+ switch (static_cast<TransformationType>(m_dirty)) {
+ case TxProject:
+ if (!qFuzzyIsNull(m_13) || !qFuzzyIsNull(m_23) || !qFuzzyIsNull(m_33 - 1)) {
m_type = TxProject;
- else if (m_dirty > TxScale && (!qFuzzyCompare(affine._m12 + 1, 1) || !qFuzzyCompare(affine._m21 + 1, 1))) {
+ break;
+ }
+ case TxShear:
+ case TxRotate:
+ if (!qFuzzyIsNull(affine._m12) || !qFuzzyIsNull(affine._m21)) {
const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22;
- if (qFuzzyCompare(dot + 1, 1))
+ if (qFuzzyIsNull(dot))
m_type = TxRotate;
else
m_type = TxShear;
- } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1) || !qFuzzyCompare(m_33, 1)))
+ break;
+ }
+ case TxScale:
+ if (!qFuzzyIsNull(affine._m11 - 1) || !qFuzzyIsNull(affine._m22 - 1)) {
m_type = TxScale;
- else if (m_dirty > TxNone && (!qFuzzyCompare(affine._dx + 1, 1) || !qFuzzyCompare(affine._dy + 1, 1)))
+ break;
+ }
+ case TxTranslate:
+ if (!qFuzzyIsNull(affine._dx) || !qFuzzyIsNull(affine._dy)) {
m_type = TxTranslate;
- else
- m_type = TxNone;
-
- m_dirty = TxNone;
+ break;
+ }
+ case TxNone:
+ m_type = TxNone;
+ break;
}
+ m_dirty = TxNone;
return static_cast<TransformationType>(m_type);
}
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index c76409b..aac7c31 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -159,6 +159,19 @@ public:
static QTransform fromScale(qreal dx, qreal dy);
private:
+ inline QTransform(qreal h11, qreal h12, qreal h13,
+ qreal h21, qreal h22, qreal h23,
+ qreal h31, qreal h32, qreal h33, bool)
+ : affine(h11, h12, h21, h22, h31, h32, true)
+ , m_13(h13), m_23(h23), m_33(h33)
+ , m_type(TxNone)
+ , m_dirty(TxProject) {}
+ inline QTransform(bool)
+ : affine(true)
+ , m_13(0), m_23(0), m_33(1)
+ , m_type(TxNone)
+ , m_dirty(TxNone) {}
+ inline TransformationType inline_type() const;
QMatrix affine;
qreal m_13;
qreal m_23;
@@ -173,18 +186,25 @@ private:
Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE);
/******* inlines *****/
+inline QTransform::TransformationType QTransform::inline_type() const
+{
+ if (m_dirty == TxNone)
+ return static_cast<TransformationType>(m_type);
+ return type();
+}
+
inline bool QTransform::isAffine() const
{
- return type() < TxProject;
+ return inline_type() < TxProject;
}
inline bool QTransform::isIdentity() const
{
- return type() == TxNone;
+ return inline_type() == TxNone;
}
inline bool QTransform::isInvertible() const
{
- return !qFuzzyCompare(determinant() + 1, 1);
+ return !qFuzzyIsNull(determinant());
}
inline bool QTransform::isScaling() const
@@ -193,12 +213,12 @@ inline bool QTransform::isScaling() const
}
inline bool QTransform::isRotating() const
{
- return type() >= TxRotate;
+ return inline_type() >= TxRotate;
}
inline bool QTransform::isTranslating() const
{
- return type() >= TxTranslate;
+ return inline_type() >= TxTranslate;
}
inline qreal QTransform::determinant() const
diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp
index bcb0380..d941a24 100644
--- a/src/gui/painting/qwindowsurface.cpp
+++ b/src/gui/painting/qwindowsurface.cpp
@@ -310,10 +310,13 @@ void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
int lineskip = img.bytesPerLine();
int depth = img.depth() >> 3;
-
- const QRect r = rect & QRect(0, 0, img.width(), img.height());
+ const QRect imageRect(0, 0, img.width(), img.height());
+ const QRect r = rect & imageRect & imageRect.translated(-offset);
const QPoint p = rect.topLeft() + offset;
+ if (r.isEmpty())
+ return;
+
const uchar *src;
uchar *dest;