~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/gui/painting/qblendfunctions_p.h

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtGui module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#ifndef QBLENDFUNCTIONS_P_H
 
43
#define QBLENDFUNCTIONS_P_H
 
44
 
 
45
#include <qmath.h>
 
46
#include "qdrawhelper_p.h"
 
47
 
 
48
QT_BEGIN_NAMESPACE
 
49
 
 
50
//
 
51
//  W A R N I N G
 
52
//  -------------
 
53
//
 
54
// This file is not part of the Qt API.  It exists purely as an
 
55
// implementation detail.  This header file may change from version to
 
56
// version without notice, or even be removed.
 
57
//
 
58
// We mean it.
 
59
//
 
60
 
 
61
template <typename SRC, typename T>
 
62
void qt_scale_image_16bit(uchar *destPixels, int dbpl,
 
63
                          const uchar *srcPixels, int sbpl,
 
64
                          const QRectF &targetRect,
 
65
                          const QRectF &srcRect,
 
66
                          const QRect &clip,
 
67
                          T blender)
 
68
{
 
69
    qreal sx = targetRect.width() / (qreal) srcRect.width();
 
70
    qreal sy = targetRect.height() / (qreal) srcRect.height();
 
71
 
 
72
    int ix = 0x00010000 / sx;
 
73
    int iy = 0x00010000 / sy;
 
74
 
 
75
//     qDebug() << "scale:" << endl
 
76
//              << " - target" << targetRect << endl
 
77
//              << " - source" << srcRect << endl
 
78
//              << " - clip" << clip << endl
 
79
//              << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy;
 
80
 
 
81
    int cx1 = clip.x();
 
82
    int cx2 = clip.x() + clip.width();
 
83
    int cy1 = clip.top();
 
84
    int cy2 = clip.y() + clip.height();
 
85
 
 
86
    int tx1 = qRound(targetRect.left());
 
87
    int tx2 = qRound(targetRect.right());
 
88
    int ty1 = qRound(targetRect.top());
 
89
    int ty2 = qRound(targetRect.bottom());
 
90
 
 
91
    if (tx2 < tx1)
 
92
        qSwap(tx2, tx1);
 
93
 
 
94
    if (ty2 < ty1)
 
95
        qSwap(ty2, ty1);
 
96
 
 
97
    if (tx1 < cx1)
 
98
        tx1 = cx1;
 
99
 
 
100
    if (tx2 >= cx2)
 
101
        tx2 = cx2;
 
102
 
 
103
    if (tx1 >= tx2)
 
104
        return;
 
105
 
 
106
    if (ty1 < cy1)
 
107
        ty1 = cy1;
 
108
 
 
109
    if (ty2 >= cy2)
 
110
       ty2 = cy2;
 
111
 
 
112
    if (ty1 >= ty2)
 
113
        return;
 
114
 
 
115
    int h = ty2 - ty1;
 
116
    int w = tx2 - tx1;
 
117
 
 
118
 
 
119
    quint32 basex;
 
120
    quint32 srcy;
 
121
 
 
122
    if (sx < 0) {
 
123
        int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;
 
124
        basex = quint32(srcRect.right() * 65536) + dstx;
 
125
    } else {
 
126
        int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;
 
127
        basex = quint32(srcRect.left() * 65536) + dstx;
 
128
    }
 
129
    if (sy < 0) {
 
130
        int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;
 
131
        srcy = quint32(srcRect.bottom() * 65536) + dsty;
 
132
    } else {
 
133
        int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;
 
134
        srcy = quint32(srcRect.top() * 65536) + dsty;
 
135
    }
 
136
 
 
137
    quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
 
138
 
 
139
    while (h--) {
 
140
        const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl);
 
141
        int srcx = basex;
 
142
        int x = 0;
 
143
        for (; x<w-7; x+=8) {
 
144
            blender.write(&dst[x], src[srcx >> 16]); srcx += ix;
 
145
            blender.write(&dst[x+1], src[srcx >> 16]); srcx += ix;
 
146
            blender.write(&dst[x+2], src[srcx >> 16]); srcx += ix;
 
147
            blender.write(&dst[x+3], src[srcx >> 16]); srcx += ix;
 
148
            blender.write(&dst[x+4], src[srcx >> 16]); srcx += ix;
 
149
            blender.write(&dst[x+5], src[srcx >> 16]); srcx += ix;
 
150
            blender.write(&dst[x+6], src[srcx >> 16]); srcx += ix;
 
151
            blender.write(&dst[x+7], src[srcx >> 16]); srcx += ix;
 
152
        }
 
153
        for (; x<w; ++x) {
 
154
            blender.write(&dst[x], src[srcx >> 16]);
 
155
            srcx += ix;
 
156
        }
 
157
        blender.flush(&dst[x]);
 
158
        dst = (quint16 *)(((uchar *) dst) + dbpl);
 
159
        srcy += iy;
 
160
    }
 
161
}
 
162
 
 
163
template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
 
164
                                                const uchar *srcPixels, int sbpl,
 
165
                                                const QRectF &targetRect,
 
166
                                                const QRectF &srcRect,
 
167
                                                const QRect &clip,
 
168
                                                T blender)
 
169
{
 
170
    qreal sx = targetRect.width() / (qreal) srcRect.width();
 
171
    qreal sy = targetRect.height() / (qreal) srcRect.height();
 
172
 
 
173
    int ix = 0x00010000 / sx;
 
174
    int iy = 0x00010000 / sy;
 
175
 
 
176
//     qDebug() << "scale:" << endl
 
177
//              << " - target" << targetRect << endl
 
178
//              << " - source" << srcRect << endl
 
179
//              << " - clip" << clip << endl
 
180
//              << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy;
 
181
 
 
182
    int cx1 = clip.x();
 
183
    int cx2 = clip.x() + clip.width();
 
184
    int cy1 = clip.top();
 
185
    int cy2 = clip.y() + clip.height();
 
186
 
 
187
    int tx1 = qRound(targetRect.left());
 
188
    int tx2 = qRound(targetRect.right());
 
189
    int ty1 = qRound(targetRect.top());
 
190
    int ty2 = qRound(targetRect.bottom());
 
191
 
 
192
    if (tx2 < tx1)
 
193
        qSwap(tx2, tx1);
 
194
 
 
195
    if (ty2 < ty1)
 
196
        qSwap(ty2, ty1);
 
197
 
 
198
    if (tx1 < cx1)
 
199
        tx1 = cx1;
 
200
 
 
201
    if (tx2 >= cx2)
 
202
        tx2 = cx2;
 
203
 
 
204
    if (tx1 >= tx2)
 
205
        return;
 
206
 
 
207
    if (ty1 < cy1)
 
208
        ty1 = cy1;
 
209
 
 
210
    if (ty2 >= cy2)
 
211
       ty2 = cy2;
 
212
 
 
213
    if (ty1 >= ty2)
 
214
        return;
 
215
 
 
216
    int h = ty2 - ty1;
 
217
    int w = tx2 - tx1;
 
218
 
 
219
    quint32 basex;
 
220
    quint32 srcy;
 
221
 
 
222
    if (sx < 0) {
 
223
        int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;
 
224
        basex = quint32(srcRect.right() * 65536) + dstx;
 
225
    } else {
 
226
        int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;
 
227
        basex = quint32(srcRect.left() * 65536) + dstx;
 
228
    }
 
229
    if (sy < 0) {
 
230
        int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;
 
231
        srcy = quint32(srcRect.bottom() * 65536) + dsty;
 
232
    } else {
 
233
        int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;
 
234
        srcy = quint32(srcRect.top() * 65536) + dsty;
 
235
    }
 
236
 
 
237
    quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
 
238
 
 
239
    while (h--) {
 
240
        const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl);
 
241
        int srcx = basex;
 
242
        int x = 0;
 
243
        for (; x<w; ++x) {
 
244
            blender.write(&dst[x], src[srcx >> 16]);
 
245
            srcx += ix;
 
246
        }
 
247
        blender.flush(&dst[x]);
 
248
        dst = (quint32 *)(((uchar *) dst) + dbpl);
 
249
        srcy += iy;
 
250
    }
 
251
}
 
252
 
 
253
struct QTransformImageVertex
 
254
{
 
255
    qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v)
 
256
};
 
257
 
 
258
template <class SrcT, class DestT, class Blender>
 
259
void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
 
260
                                  const SrcT *srcPixels, int sbpl,
 
261
                                  const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft,
 
262
                                  const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight,
 
263
                                  const QRect &sourceRect,
 
264
                                  const QRect &clip,
 
265
                                  qreal topY, qreal bottomY,
 
266
                                  int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
 
267
                                  Blender blender)
 
268
{
 
269
    int fromY = qMax(qRound(topY), clip.top());
 
270
    int toY = qMin(qRound(bottomY), clip.top() + clip.height());
 
271
    if (fromY >= toY)
 
272
        return;
 
273
 
 
274
    qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
 
275
    qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
 
276
    int dx_l = int(leftSlope * 0x10000);
 
277
    int dx_r = int(rightSlope * 0x10000);
 
278
    int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
 
279
    int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
 
280
 
 
281
    int fromX, toX, x1, x2, u, v, i, ii;
 
282
    DestT *line;
 
283
    for (int y = fromY; y < toY; ++y) {
 
284
        line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
 
285
 
 
286
        fromX = qMax(x_l >> 16, clip.left());
 
287
        toX = qMin(x_r >> 16, clip.left() + clip.width());
 
288
        if (fromX < toX) {
 
289
            // Because of rounding, we can get source coordinates outside the source image.
 
290
            // Clamp these coordinates to the source rect to avoid segmentation fault and
 
291
            // garbage on the screen.
 
292
 
 
293
            // Find the first pixel on the current scan line where the source coordinates are within the source rect.
 
294
            x1 = fromX;
 
295
            u = x1 * dudx + y * dudy + u0;
 
296
            v = x1 * dvdx + y * dvdy + v0;
 
297
            for (; x1 < toX; ++x1) {
 
298
                int uu = u >> 16;
 
299
                int vv = v >> 16;
 
300
                if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
 
301
                    && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
 
302
                    break;
 
303
                }
 
304
                u += dudx;
 
305
                v += dvdx;
 
306
            }
 
307
 
 
308
            // Find the last pixel on the current scan line where the source coordinates are within the source rect.
 
309
            x2 = toX;
 
310
            u = (x2 - 1) * dudx + y * dudy + u0;
 
311
            v = (x2 - 1) * dvdx + y * dvdy + v0;
 
312
            for (; x2 > x1; --x2) {
 
313
                int uu = u >> 16;
 
314
                int vv = v >> 16;
 
315
                if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
 
316
                    && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
 
317
                    break;
 
318
                }
 
319
                u -= dudx;
 
320
                v -= dvdx;
 
321
            }
 
322
 
 
323
            // Set up values at the beginning of the scan line.
 
324
            u = fromX * dudx + y * dudy + u0;
 
325
            v = fromX * dvdx + y * dvdy + v0;
 
326
            line += fromX;
 
327
 
 
328
            // Beginning of the scan line, with per-pixel checks.
 
329
            i = x1 - fromX;
 
330
            while (i) {
 
331
                int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
 
332
                int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
 
333
                blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
 
334
                u += dudx;
 
335
                v += dvdx;
 
336
                ++line;
 
337
                --i;
 
338
            }
 
339
 
 
340
            // Middle of the scan line, without checks.
 
341
            // Manual loop unrolling.
 
342
            i = x2 - x1;
 
343
            ii = i >> 3;
 
344
            while (ii) {
 
345
                blender.write(&line[0], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
346
                blender.write(&line[1], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
347
                blender.write(&line[2], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
348
                blender.write(&line[3], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
349
                blender.write(&line[4], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
350
                blender.write(&line[5], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
351
                blender.write(&line[6], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
352
                blender.write(&line[7], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
 
353
 
 
354
                line += 8;
 
355
 
 
356
                --ii;
 
357
            }
 
358
            switch (i & 7) {
 
359
                case 7: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
360
                case 6: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
361
                case 5: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
362
                case 4: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
363
                case 3: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
364
                case 2: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
365
                case 1: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
 
366
            }
 
367
 
 
368
            // End of the scan line, with per-pixel checks.
 
369
            i = toX - x2;
 
370
            while (i) {
 
371
                int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
 
372
                int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
 
373
                blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
 
374
                u += dudx;
 
375
                v += dvdx;
 
376
                ++line;
 
377
                --i;
 
378
            }
 
379
 
 
380
            blender.flush(line);
 
381
        }
 
382
        x_l += dx_l;
 
383
        x_r += dx_r;
 
384
    }
 
385
}
 
386
 
 
387
template <class SrcT, class DestT, class Blender>
 
388
void qt_transform_image(DestT *destPixels, int dbpl,
 
389
                        const SrcT *srcPixels, int sbpl,
 
390
                        const QRectF &targetRect,
 
391
                        const QRectF &sourceRect,
 
392
                        const QRect &clip,
 
393
                        const QTransform &targetRectTransform,
 
394
                        Blender blender)
 
395
{
 
396
    enum Corner
 
397
    {
 
398
        TopLeft,
 
399
        TopRight,
 
400
        BottomRight,
 
401
        BottomLeft
 
402
    };
 
403
 
 
404
    // map source rectangle to destination.
 
405
    QTransformImageVertex v[4];
 
406
    v[TopLeft].u = v[BottomLeft].u = sourceRect.left();
 
407
    v[TopLeft].v = v[TopRight].v = sourceRect.top();
 
408
    v[TopRight].u = v[BottomRight].u = sourceRect.right();
 
409
    v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom();
 
410
    targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y);
 
411
    targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y);
 
412
    targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y);
 
413
    targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y);
 
414
 
 
415
    // find topmost vertex.
 
416
    int topmost = 0;
 
417
    for (int i = 1; i < 4; ++i) {
 
418
        if (v[i].y < v[topmost].y)
 
419
            topmost = i;
 
420
    }
 
421
    // rearrange array such that topmost vertex is at index 0.
 
422
    switch (topmost) {
 
423
    case 1:
 
424
        {
 
425
            QTransformImageVertex t = v[0];
 
426
            for (int i = 0; i < 3; ++i)
 
427
                v[i] = v[i+1];
 
428
            v[3] = t;
 
429
        }
 
430
        break;
 
431
    case 2:
 
432
        qSwap(v[0], v[2]);
 
433
        qSwap(v[1], v[3]);
 
434
        break;
 
435
    case 3:
 
436
        {
 
437
            QTransformImageVertex t = v[3];
 
438
            for (int i = 3; i > 0; --i)
 
439
                v[i] = v[i-1];
 
440
            v[0] = t;
 
441
        }
 
442
        break;
 
443
    }
 
444
 
 
445
    // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3.
 
446
    qreal dx1 = v[1].x - v[0].x;
 
447
    qreal dy1 = v[1].y - v[0].y;
 
448
    qreal dx2 = v[3].x - v[0].x;
 
449
    qreal dy2 = v[3].y - v[0].y;
 
450
    if (dx1 * dy2 - dx2 * dy1 > 0)
 
451
        qSwap(v[1], v[3]);
 
452
 
 
453
    QTransformImageVertex u = {v[1].x - v[0].x, v[1].y - v[0].y, v[1].u - v[0].u, v[1].v - v[0].v};
 
454
    QTransformImageVertex w = {v[2].x - v[0].x, v[2].y - v[0].y, v[2].u - v[0].u, v[2].v - v[0].v};
 
455
 
 
456
    qreal det = u.x * w.y - u.y * w.x;
 
457
    if (det == 0)
 
458
        return;
 
459
 
 
460
    qreal invDet = 1.0 / det;
 
461
    qreal m11, m12, m21, m22, mdx, mdy;
 
462
 
 
463
    m11 = (u.u * w.y - u.y * w.u) * invDet;
 
464
    m12 = (u.x * w.u - u.u * w.x) * invDet;
 
465
    m21 = (u.v * w.y - u.y * w.v) * invDet;
 
466
    m22 = (u.x * w.v - u.v * w.x) * invDet;
 
467
    mdx = v[0].u - m11 * v[0].x - m12 * v[0].y;
 
468
    mdy = v[0].v - m21 * v[0].x - m22 * v[0].y;
 
469
 
 
470
    int dudx = int(m11 * 0x10000);
 
471
    int dvdx = int(m21 * 0x10000);
 
472
    int dudy = int(m12 * 0x10000);
 
473
    int dvdy = int(m22 * 0x10000);
 
474
    int u0 = qCeil((qreal(0.5) * m11 + qreal(0.5) * m12 + mdx) * 0x10000) - 1;
 
475
    int v0 = qCeil((qreal(0.5) * m21 + qreal(0.5) * m22 + mdy) * 0x10000) - 1;
 
476
 
 
477
    int x1 = qFloor(sourceRect.left());
 
478
    int y1 = qFloor(sourceRect.top());
 
479
    int x2 = qCeil(sourceRect.right());
 
480
    int y2 = qCeil(sourceRect.bottom());
 
481
    QRect sourceRectI(x1, y1, x2 - x1, y2 - y1);
 
482
 
 
483
    // rasterize trapezoids.
 
484
    if (v[1].y < v[3].y) {
 
485
        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
 
486
        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[0], v[3], sourceRectI, clip, v[1].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
 
487
        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[3].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
 
488
    } else {
 
489
        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
 
490
        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[3], v[2], sourceRectI, clip, v[3].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
 
491
        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[1].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
 
492
    }
 
493
}
 
494
 
 
495
QT_END_NAMESPACE
 
496
 
 
497
#endif // QBLENDFUNCTIONS_P_H