Changeset 561 for trunk/src/gui/painting/qblendfunctions.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/gui/painting/qblendfunctions.cpp (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/painting/qblendfunctions.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information ([email protected]) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation ([email protected]) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you 37 ** @nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 45 45 QT_BEGIN_NAMESPACE 46 47 48 // This ifdef is made with the best of intention. GCC fails to49 // optimzie the code properly so the bytemul approach is the fastest50 // it gets. Both on ARM and on MSVC the code is optimized to be better51 // than the bytemul approach... On the other hand... This code is52 // almost never run on i386 so it may be downright silly to have this53 // piece of code here...54 #if defined (Q_CC_GNU) && (defined (QT_ARCH_I386) || defined (QT_ARCH_X86_64))55 # define QT_BLEND_USE_BYTEMUL56 #endif57 58 // #define QT_DEBUG_DRAW59 60 static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;61 46 62 47 struct SourceOnlyAlpha … … 120 105 }; 121 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 122 138 struct Blend_ARGB32_on_RGB16_SourceAlpha { 123 139 inline void write(quint16 *dst, quint32 src) { … … 154 170 void qt_scale_image_16bit(uchar *destPixels, int dbpl, 155 171 const uchar *srcPixels, int sbpl, 156 const QRectF &target ,172 const QRectF &target, 157 173 const QRectF &srcRect, 158 174 const QRect &clip, 159 175 T blender) 160 176 { 161 const QRectF targetRect = target.translated(aliasedCoordinateDelta,162 aliasedCoordinateDelta);163 164 177 qreal sx = targetRect.width() / (qreal) srcRect.width(); 165 178 qreal sy = targetRect.height() / (qreal) srcRect.height(); … … 211 224 int w = tx2 - tx1; 212 225 213 const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix); 214 const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy); 215 216 quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx; 217 quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty; 226 227 quint32 basex; 228 quint32 srcy; 229 230 if (sx < 0) { 231 int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; 232 basex = quint32(srcRect.right() * 65536) + dstx; 233 } else { 234 int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; 235 basex = quint32(srcRect.left() * 65536) + dstx; 236 } 237 if (sy < 0) { 238 int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; 239 srcy = quint32(srcRect.bottom() * 65536) + dsty; 240 } else { 241 int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; 242 srcy = quint32(srcRect.top() * 65536) + dsty; 243 } 218 244 219 245 quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1; … … 256 282 } 257 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 258 310 void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl, 259 311 const uchar *srcPixels, int sbpl, … … 287 339 { 288 340 #ifdef QT_DEBUG_DRAW 289 printf("qt_blend_ argb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",341 printf("qt_blend_rgb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", 290 342 dst, dbpl, src, sbpl, w, h, const_alpha); 291 343 #endif … … 336 388 const uchar *srcEnd = src + srcOffset; 337 389 while (src < srcEnd) { 338 #if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_))339 // non-16-bit aligned memory access is not possible on PowerPC &340 // ARM <v6 (QT_ARCH_ARMV6) 390 #if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || )) 391 // non-16-bit aligned memory access is not possible on PowerPC 392 // ARM <v6 (QT_ARCH_ARMV6) 341 393 quint16 spix = (quint16(src[2])<<8) + src[1]; 342 394 #else … … 348 400 *dst = spix; 349 401 } else if (alpha != 0) { 350 #ifdef QT_BLEND_USE_BYTEMUL351 // truncate green channel to avoid overflow352 *dst = (alphaFunc.bytemul(spix) & 0xffdf)353 + (quint16) qrgb565(*dst).byte_mul(qrgb565::ialpha(alpha));354 #else355 402 quint16 dpix = *dst; 356 403 quint32 sia = 255 - alpha; … … 364 411 quint32 siab = db * sia; 365 412 366 quint32 rr = ((siar + (siar>>8) + (0x80 << 11)) >> 8) & 0xf800;367 quint32 rg = ((siag + (siag>>8) + (0x80 << 5)) >> 8) & 0x07e0;368 quint32 rb = ((siab + (siab>>8) + (0x80 >> 3)) >> 8) ;413 quint32 rr = ((siar + (siar>>8) + (0x80 << )) >> 8) & 0xf800; 414 quint32 rg = ((siag + (siag>>8) + (0x80 << )) >> 8) & 0x07e0; 415 quint32 rb = ((siab + (siab>>8) + (0x80 >> 3)) >> 8); 369 416 370 417 *dst = alphaFunc.bytemul(spix) + rr + rg + rb; 371 #endif372 418 } 373 419 … … 436 482 437 483 quint16 *dst = (quint16 *) destPixels; 438 int dstExtraStride = dbpl / 2 - w; 439 440 const quint32 *src = (const quint32 *) srcPixels; 441 int srcExtraStride = sbpl / 4 - w; 484 quint32 *src = (quint32 *) srcPixels; 442 485 443 486 for (int y=0; y<h; ++y) { 444 int length = w; 445 const int dstAlign = ((quintptr)dst) & 0x3; 446 if (dstAlign) { 447 const quint8 alpha = qAlpha(*src); 448 if (alpha) { 449 quint16 s = convert_argb32_to_rgb16(*src); 450 if (alpha < 255) 451 s += BYTE_MUL_RGB16(*dst, 255 - alpha); 452 *dst = s; 453 } 454 ++dst; 455 ++src; 456 --length; 457 } 458 459 const int length32 = length >> 1; 460 const int srcAlign = ((quintptr)src) & 0x3; 461 if (length32) { 462 if (srcAlign) { 463 for (int i = 0; i < length32; ++i) { 464 quint32 *dest32 = reinterpret_cast<quint32*>(dst); 465 const quint8 a1 = qAlpha(src[0]); 466 const quint8 a2 = qAlpha(src[1]); 467 quint32 s; 468 469 if (!a1 && !a2) { 470 src += 2; 471 dst +=2; 472 continue; 473 } 474 475 s = convert_argb32_to_rgb16(src[0]) 476 | (convert_argb32_to_rgb16(src[1]) << 16); 477 478 if (a1 == a2) { 479 if (a1 < 255) { 480 const quint8 sa = ((255 - a1)+1) >> 3; 481 s += BYTE_MUL_RGB16_32(*dest32, sa); 482 } 483 } else { 484 if (a1 < 255) 485 s += BYTE_MUL_RGB16(dst[0], 255 - a1); 486 if (a2 < 255) 487 s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16; 488 } 489 490 *dest32 = s; 491 src += 2; 492 dst += 2; 493 } 494 } else { 495 for (int i = 0; i < length32; ++i) { 496 quint32 *dest32 = reinterpret_cast<quint32*>(dst); 497 const quint8 a1 = qAlpha(src[0]); 498 const quint8 a2 = qAlpha(src[1]); 499 quint32 s; 500 501 if (!a1 && !a2) { 502 src += 2; 503 dst +=2; 504 continue; 505 } 506 507 const quint64 *src64 = 508 reinterpret_cast<const quint64*>(src); 509 s = qConvertRgb32To16x2(*src64); 510 511 if (a1 == a2) { 512 if (a1 < 255) { 513 const quint8 sa = ((255 - a1)+1) >> 3; 514 s += BYTE_MUL_RGB16_32(*dest32, sa); 515 } 516 } else { 517 if (a1 < 255) 518 s += BYTE_MUL_RGB16(dst[0], 255 - a1); 519 if (a2 < 255) 520 s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16; 521 } 522 523 *dest32 = s; 524 src += 2; 525 dst += 2; 526 } 487 for (int x=0; x<w; ++x) { 488 489 quint32 spix = src[x]; 490 quint32 alpha = spix >> 24; 491 492 if (alpha == 255) { 493 dst[x] = convert_argb32_to_rgb16(spix); 494 } else if (alpha != 0) { 495 quint32 dpix = dst[x]; 496 497 quint32 sia = 255 - alpha; 498 499 quint32 sr = (spix >> 8) & 0xf800; 500 quint32 sg = (spix >> 5) & 0x07e0; 501 quint32 sb = (spix >> 3) & 0x001f; 502 503 quint32 dr = (dpix & 0x0000f800); 504 quint32 dg = (dpix & 0x000007e0); 505 quint32 db = (dpix & 0x0000001f); 506 507 quint32 siar = dr * sia; 508 quint32 siag = dg * sia; 509 quint32 siab = db * sia; 510 511 quint32 rr = sr + ((siar + (siar>>8) + (0x80 << 8)) >> 8); 512 quint32 rg = sg + ((siag + (siag>>8) + (0x80 << 3)) >> 8); 513 quint32 rb = sb + ((siab + (siab>>8) + (0x80 >> 3)) >> 8); 514 515 dst[x] = (rr & 0xf800) 516 | (rg & 0x07e0) 517 | (rb); 527 518 } 528 519 } 529 const int tail = length & 0x1; 530 if (tail) { 531 const quint8 alpha = qAlpha(*src); 532 if (alpha) { 533 quint16 s = convert_argb32_to_rgb16(*src); 534 if (alpha < 255) 535 s += BYTE_MUL_RGB16(*dst, 255 - alpha); 536 *dst = s; 537 } 538 ++dst; 539 ++src; 540 } 541 dst += dstExtraStride; 542 src += srcExtraStride; 543 } 544 520 dst = (quint16 *) (((uchar *) dst) + dbpl); 521 src = (quint32 *) (((uchar *) src) + sbpl); 522 } 545 523 } 546 524 … … 606 584 for (int x=0; x<w; ++x) { 607 585 uint s = src[x]; 608 if ( (s & 0xff000000) == 0xff000000)586 if (= 0xff000000) 609 587 dst[x] = s; 610 else {588 else 611 589 dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); 612 }613 590 } 614 591 dst = (quint32 *)(((uchar *) dst) + dbpl); … … 629 606 630 607 631 staticvoid qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,608 void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, 632 609 const uchar *srcPixels, int sbpl, 633 610 int w, int h, … … 706 683 template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl, 707 684 const uchar *srcPixels, int sbpl, 708 const QRectF &target ,685 const QRectF &target, 709 686 const QRectF &srcRect, 710 687 const QRect &clip, 711 688 T blender) 712 689 { 713 const QRectF targetRect = target.translated(aliasedCoordinateDelta,714 aliasedCoordinateDelta);715 716 690 qreal sx = targetRect.width() / (qreal) srcRect.width(); 717 691 qreal sy = targetRect.height() / (qreal) srcRect.height(); … … 763 737 int w = tx2 - tx1; 764 738 765 const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix); 766 const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy); 767 768 quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx; 769 quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty; 739 quint32 basex; 740 quint32 srcy; 741 742 if (sx < 0) { 743 int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; 744 basex = quint32(srcRect.right() * 65536) + dstx; 745 } else { 746 int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; 747 basex = quint32(srcRect.left() * 65536) + dstx; 748 } 749 if (sy < 0) { 750 int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; 751 srcy = quint32(srcRect.bottom() * 65536) + dsty; 752 } else { 753 int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; 754 srcy = quint32(srcRect.top() * 65536) + dsty; 755 } 770 756 771 757 quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1; … … 833 819 } 834 820 835 821 struct QTransformImageVertex 822 { 823 qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v) 824 }; 825 826 template <class SrcT, class DestT, class Blender> 827 void qt_transform_image_rasterize(DestT *destPixels, int dbpl, 828 const SrcT *srcPixels, int sbpl, 829 const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft, 830 const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight, 831 const QRect &sourceRect, 832 const QRect &clip, 833 qreal topY, qreal bottomY, 834 int dudx, int dvdx, int dudy, int dvdy, int u0, int v0, 835 Blender blender) 836 { 837 int fromY = qMax(qRound(topY), clip.top()); 838 int toY = qMin(qRound(bottomY), clip.top() + clip.height()); 839 if (fromY >= toY) 840 return; 841 842 qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y); 843 qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y); 844 int dx_l = int(leftSlope * 0x10000); 845 int dx_r = int(rightSlope * 0x10000); 846 int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000); 847 int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000); 848 849 int fromX, toX, x1, x2, u, v, i, ii; 850 DestT *line; 851 for (int y = fromY; y < toY; ++y) { 852 line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl); 853 854 fromX = qMax(x_l >> 16, clip.left()); 855 toX = qMin(x_r >> 16, clip.left() + clip.width()); 856 if (fromX < toX) { 857 // Because of rounding, we can get source coordinates outside the source image. 858 // Clamp these coordinates to the source rect to avoid segmentation fault and 859 // garbage on the screen. 860 861 // Find the first pixel on the current scan line where the source coordinates are within the source rect. 862 x1 = fromX; 863 u = x1 * dudx + y * dudy + u0; 864 v = x1 * dvdx + y * dvdy + v0; 865 for (; x1 < toX; ++x1) { 866 int uu = u >> 16; 867 int vv = v >> 16; 868 if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() 869 && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { 870 break; 871 } 872 u += dudx; 873 v += dvdx; 874 } 875 876 // Find the last pixel on the current scan line where the source coordinates are within the source rect. 877 x2 = toX; 878 u = (x2 - 1) * dudx + y * dudy + u0; 879 v = (x2 - 1) * dvdx + y * dvdy + v0; 880 for (; x2 > x1; --x2) { 881 int uu = u >> 16; 882 int vv = v >> 16; 883 if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() 884 && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { 885 break; 886 } 887 u -= dudx; 888 v -= dvdx; 889 } 890 891 // Set up values at the beginning of the scan line. 892 u = fromX * dudx + y * dudy + u0; 893 v = fromX * dvdx + y * dvdy + v0; 894 line += fromX; 895 896 // Beginning of the scan line, with per-pixel checks. 897 i = x1 - fromX; 898 while (i) { 899 int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); 900 int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); 901 blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]); 902 u += dudx; 903 v += dvdx; 904 ++line; 905 --i; 906 } 907 908 // Middle of the scan line, without checks. 909 // Manual loop unrolling. 910 i = x2 - x1; 911 ii = i >> 3; 912 while (ii) { 913 blender.write(&line[0], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 914 blender.write(&line[1], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 915 blender.write(&line[2], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 916 blender.write(&line[3], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 917 blender.write(&line[4], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 918 blender.write(&line[5], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 919 blender.write(&line[6], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 920 blender.write(&line[7], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; 921 line += 8; 922 --ii; 923 } 924 switch (i & 7) { 925 case 7: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 926 case 6: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 927 case 5: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 928 case 4: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 929 case 3: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 930 case 2: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 931 case 1: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; 932 } 933 934 // End of the scan line, with per-pixel checks. 935 i = toX - x2; 936 while (i) { 937 int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); 938 int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); 939 blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]); 940 u += dudx; 941 v += dvdx; 942 ++line; 943 --i; 944 } 945 } 946 x_l += dx_l; 947 x_r += dx_r; 948 } 949 } 950 951 template <class SrcT, class DestT, class Blender> 952 void qt_transform_image(DestT *destPixels, int dbpl, 953 const SrcT *srcPixels, int sbpl, 954 const QRectF &targetRect, 955 const QRectF &sourceRect, 956 const QRect &clip, 957 const QTransform &targetRectTransform, 958 Blender blender) 959 { 960 enum Corner 961 { 962 TopLeft, 963 TopRight, 964 BottomRight, 965 BottomLeft 966 }; 967 968 // map source rectangle to destination. 969 QTransformImageVertex v[4]; 970 v[TopLeft].u = v[BottomLeft].u = sourceRect.left(); 971 v[TopLeft].v = v[TopRight].v = sourceRect.top(); 972 v[TopRight].u = v[BottomRight].u = sourceRect.right(); 973 v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom(); 974 targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y); 975 targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y); 976 targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y); 977 targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y); 978 979 // find topmost vertex. 980 int topmost = 0; 981 for (int i = 1; i < 4; ++i) { 982 if (v[i].y < v[topmost].y) 983 topmost = i; 984 } 985 // rearrange array such that topmost vertex is at index 0. 986 switch (topmost) { 987 case 1: 988 { 989 QTransformImageVertex t = v[0]; 990 for (int i = 0; i < 3; ++i) 991 v[i] = v[i+1]; 992 v[3] = t; 993 } 994 break; 995 case 2: 996 qSwap(v[0], v[2]); 997 qSwap(v[1], v[3]); 998 break; 999 case 3: 1000 { 1001 QTransformImageVertex t = v[3]; 1002 for (int i = 3; i > 0; --i) 1003 v[i] = v[i-1]; 1004 v[0] = t; 1005 } 1006 break; 1007 } 1008 1009 // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3. 1010 qreal dx1 = v[1].x - v[0].x; 1011 qreal dy1 = v[1].y - v[0].y; 1012 qreal dx2 = v[3].x - v[0].x; 1013 qreal dy2 = v[3].y - v[0].y; 1014 if (dx1 * dy2 - dx2 * dy1 > 0) 1015 qSwap(v[1], v[3]); 1016 1017 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}; 1018 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}; 1019 1020 qreal det = u.x * w.y - u.y * w.x; 1021 if (det == 0) 1022 return; 1023 1024 qreal invDet = 1.0 / det; 1025 qreal m11, m12, m21, m22, mdx, mdy; 1026 1027 m11 = (u.u * w.y - u.y * w.u) * invDet; 1028 m12 = (u.x * w.u - u.u * w.x) * invDet; 1029 m21 = (u.v * w.y - u.y * w.v) * invDet; 1030 m22 = (u.x * w.v - u.v * w.x) * invDet; 1031 mdx = v[0].u - m11 * v[0].x - m12 * v[0].y; 1032 mdy = v[0].v - m21 * v[0].x - m22 * v[0].y; 1033 1034 int dudx = int(m11 * 0x10000); 1035 int dvdx = int(m21 * 0x10000); 1036 int dudy = int(m12 * 0x10000); 1037 int dvdy = int(m22 * 0x10000); 1038 int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1; 1039 int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1; 1040 1041 int x1 = qFloor(sourceRect.left()); 1042 int y1 = qFloor(sourceRect.top()); 1043 int x2 = qCeil(sourceRect.right()); 1044 int y2 = qCeil(sourceRect.bottom()); 1045 QRect sourceRectI(x1, y1, x2 - x1, y2 - y1); 1046 1047 // rasterize trapezoids. 1048 if (v[1].y < v[3].y) { 1049 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); 1050 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); 1051 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); 1052 } else { 1053 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); 1054 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); 1055 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); 1056 } 1057 } 1058 1059 void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, 1060 const uchar *srcPixels, int sbpl, 1061 const QRectF &targetRect, 1062 const QRectF &sourceRect, 1063 const QRect &clip, 1064 const QTransform &targetRectTransform, 1065 int const_alpha) 1066 { 1067 if (const_alpha == 256) { 1068 Blend_RGB16_on_RGB16_NoAlpha noAlpha; 1069 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 1070 reinterpret_cast<const quint16 *>(srcPixels), sbpl, 1071 targetRect, sourceRect, clip, targetRectTransform, noAlpha); 1072 } else { 1073 Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha); 1074 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 1075 reinterpret_cast<const quint16 *>(srcPixels), sbpl, 1076 targetRect, sourceRect, clip, targetRectTransform, constAlpha); 1077 } 1078 } 1079 1080 void qt_transform_image_argb24_on_rgb16(uchar *destPixels, int dbpl, 1081 const uchar *srcPixels, int sbpl, 1082 const QRectF &targetRect, 1083 const QRectF &sourceRect, 1084 const QRect &clip, 1085 const QTransform &targetRectTransform, 1086 int const_alpha) 1087 { 1088 if (const_alpha == 256) { 1089 Blend_ARGB24_on_RGB16_SourceAlpha noAlpha; 1090 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 1091 reinterpret_cast<const qargb8565 *>(srcPixels), sbpl, 1092 targetRect, sourceRect, clip, targetRectTransform, noAlpha); 1093 } else { 1094 Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha); 1095 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 1096 reinterpret_cast<const qargb8565 *>(srcPixels), sbpl, 1097 targetRect, sourceRect, clip, targetRectTransform, constAlpha); 1098 } 1099 } 1100 1101 1102 void qt_transform_image_argb32_on_rgb16(uchar *destPixels, int dbpl, 1103 const uchar *srcPixels, int sbpl, 1104 const QRectF &targetRect, 1105 const QRectF &sourceRect, 1106 const QRect &clip, 1107 const QTransform &targetRectTransform, 1108 int const_alpha) 1109 { 1110 if (const_alpha == 256) { 1111 Blend_ARGB32_on_RGB16_SourceAlpha noAlpha; 1112 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 1113 reinterpret_cast<const quint32 *>(srcPixels), sbpl, 1114 targetRect, sourceRect, clip, targetRectTransform, noAlpha); 1115 } else { 1116 Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha); 1117 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 1118 reinterpret_cast<const quint32 *>(srcPixels), sbpl, 1119 targetRect, sourceRect, clip, targetRectTransform, constAlpha); 1120 } 1121 } 1122 1123 1124 void qt_transform_image_rgb32_on_rgb32(uchar *destPixels, int dbpl, 1125 const uchar *srcPixels, int sbpl, 1126 const QRectF &targetRect, 1127 const QRectF &sourceRect, 1128 const QRect &clip, 1129 const QTransform &targetRectTransform, 1130 int const_alpha) 1131 { 1132 if (const_alpha == 256) { 1133 Blend_RGB32_on_RGB32_NoAlpha noAlpha; 1134 qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl, 1135 reinterpret_cast<const quint32 *>(srcPixels), sbpl, 1136 targetRect, sourceRect, clip, targetRectTransform, noAlpha); 1137 } else { 1138 Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha); 1139 qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl, 1140 reinterpret_cast<const quint32 *>(srcPixels), sbpl, 1141 targetRect, sourceRect, clip, targetRectTransform, constAlpha); 1142 } 1143 } 1144 1145 void qt_transform_image_argb32_on_argb32(uchar *destPixels, int dbpl, 1146 const uchar *srcPixels, int sbpl, 1147 const QRectF &targetRect, 1148 const QRectF &sourceRect, 1149 const QRect &clip, 1150 const QTransform &targetRectTransform, 1151 int const_alpha) 1152 { 1153 if (const_alpha == 256) { 1154 Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha; 1155 qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl, 1156 reinterpret_cast<const quint32 *>(srcPixels), sbpl, 1157 targetRect, sourceRect, clip, targetRectTransform, sourceAlpha); 1158 } else { 1159 Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha); 1160 qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl, 1161 reinterpret_cast<const quint32 *>(srcPixels), sbpl, 1162 targetRect, sourceRect, clip, targetRectTransform, constAlpha); 1163 } 1164 } 836 1165 837 1166 SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = { … … 971 1300 qt_scale_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied, 972 1301 qt_scale_image_rgb16_on_rgb16, // Format_RGB16, 973 0,// Format_ARGB8565_Premultiplied,1302 // Format_ARGB8565_Premultiplied, 974 1303 0, // Format_RGB666, 975 1304 0, // Format_ARGB6666_Premultiplied, … … 1418 1747 }; 1419 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 1420 2039 1421 2040 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.
