Changeset 561 for trunk/src/gui/painting/qdrawutil.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
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/qdrawutil.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 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 have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 46 46 #include "qpainter.h" 47 47 #include "qpalette.h" 48 #include <private/qpaintengineex_p.h> 49 #include <qvarlengtharray.h> 50 #include <qmath.h> 48 51 49 52 QT_BEGIN_NAMESPACE 53 54 /*! 55 \headerfile <qdrawutil.h> 56 \title Drawing Utility Functions 57 58 \sa QPainter 59 */ 50 60 51 61 /*! … … 53 63 const QPalette &palette, bool sunken, 54 64 int lineWidth, int midLineWidth) 55 \relates QPainter65 \relates <qdrawutil.h> 56 66 57 67 Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2) … … 167 177 int lineWidth, int midLineWidth, 168 178 const QBrush *fill) 169 \relates QPainter179 \relates <qdrawutil.h> 170 180 171 181 Draws the shaded rectangle beginning at (\a x, \a y) with the … … 271 281 const QPalette &palette, bool sunken, 272 282 int lineWidth, const QBrush *fill) 273 \relates QPainter283 \relates <qdrawutil.h> 274 284 275 285 Draws the shaded panel beginning at (\a x, \a y) with the given \a … … 407 417 const QPalette &palette, bool sunken, 408 418 const QBrush *fill) 409 \relates QPainter419 \relates <qdrawutil.h> 410 420 411 421 Draws the Windows-style button specified by the given point (\a x, … … 445 455 const QPalette &palette, bool sunken, 446 456 const QBrush *fill) 447 \relates QPainter457 \relates <qdrawutil.h> 448 458 449 459 Draws the Windows-style panel specified by the given point(\a x, … … 484 494 \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor, 485 495 int lineWidth, const QBrush *fill) 486 \relates QPainter496 \relates <qdrawutil.h> 487 497 488 498 Draws the plain rectangle beginning at (\a x, \a y) with the given … … 533 543 \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2, 534 544 const QPalette &palette, bool sunken, int lineWidth, int midLineWidth) 535 \relates QPainter545 \relates <qdrawutil.h> 536 546 \overload 537 547 … … 573 583 \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette, 574 584 bool sunken, int lineWidth, int midLineWidth, const QBrush *fill) 575 \relates QPainter585 \relates <qdrawutil.h> 576 586 \overload 577 587 … … 613 623 \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette, 614 624 bool sunken, int lineWidth, const QBrush *fill) 615 \relates QPainter625 \relates <qdrawutil.h> 616 626 \overload 617 627 … … 649 659 \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette, 650 660 bool sunken, const QBrush *fill) 651 \relates QPainter661 \relates <qdrawutil.h> 652 662 \overload 653 663 … … 707 717 /*! 708 718 \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill) 709 \relates QPainter719 \relates <qdrawutil.h> 710 720 \overload 711 721 … … 1009 1019 #ifndef QT_NO_IMAGE_HEURISTIC_MASK 1010 1020 } else { // color pixmap, no mask 1011 QString k; 1012 k.sprintf("$qt-drawitem-%llx", pm.cacheKey()); 1021 QString k = QString::fromLatin1("$qt-drawitem-%1").arg(pm.cacheKey()); 1013 1022 if (!QPixmapCache::find(k, pm)) { 1014 1023 pm = pm.createHeuristicMask(); … … 1039 1048 #endif 1040 1049 1050 /*! 1051 \class QTileRules 1052 \since 4.6 1053 1054 Holds the rules used to draw a pixmap or image split into nine segments, 1055 similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}. 1056 1057 \sa Qt::TileRule, QMargins 1058 */ 1059 1060 /*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) 1061 Constructs a QTileRules with the given \a horizontalRule and 1062 \a verticalRule. 1063 */ 1064 1065 /*! \fn QTileRules::QTileRules(Qt::TileRule rule) 1066 Constructs a QTileRules with the given \a rule used for both 1067 the horizontal rule and the vertical rule. 1068 */ 1069 1070 /*! 1071 \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap) 1072 \relates <qdrawutil.h> 1073 \since 4.6 1074 \overload 1075 1076 \brief The qDrawBorderPixmap function is for drawing a pixmap into 1077 the margins of a rectangle. 1078 1079 Draws the given \a pixmap into the given \a target rectangle, using the 1080 given \a painter. The pixmap will be split into nine segments and drawn 1081 according to the \a margins structure. 1082 */ 1083 1084 typedef QVarLengthArray<QDrawPixmaps::Data, 16> QDrawPixmapsDataArray; 1085 1086 /*! 1087 \since 4.6 1088 1089 Draws the indicated \a sourceRect rectangle from the given \a pixmap into 1090 the given \a targetRect rectangle, using the given \a painter. The pixmap 1091 will be split into nine segments according to the given \a targetMargins 1092 and \a sourceMargins structures. Finally, the pixmap will be drawn 1093 according to the given \a rules. 1094 1095 This function is used to draw a scaled pixmap, similar to 1096 \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images} 1097 1098 \sa Qt::TileRule, QTileRules, QMargins 1099 */ 1100 1101 void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, 1102 const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, 1103 const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) 1104 { 1105 QDrawPixmaps::Data d; 1106 d.opacity = 1.0; 1107 d.rotation = 0.0; 1108 1109 QDrawPixmapsDataArray opaqueData; 1110 QDrawPixmapsDataArray translucentData; 1111 1112 // source center 1113 const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); 1114 const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); 1115 const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1; 1116 const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1; 1117 const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft; 1118 const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop; 1119 // target center 1120 const int targetCenterTop = targetRect.top() + targetMargins.top(); 1121 const int targetCenterLeft = targetRect.left() + targetMargins.left(); 1122 const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1; 1123 const int targetCenterRight = targetRect.right() - targetMargins.right() + 1; 1124 const int targetCenterWidth = targetCenterRight - targetCenterLeft; 1125 const int targetCenterHeight = targetCenterBottom - targetCenterTop; 1126 1127 QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles 1128 QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles 1129 1130 int columns = 3; 1131 int rows = 3; 1132 if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) 1133 columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); 1134 if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) 1135 rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); 1136 1137 xTarget.resize(columns + 1); 1138 yTarget.resize(rows + 1); 1139 1140 xTarget[0] = targetRect.left(); 1141 xTarget[1] = targetCenterLeft; 1142 xTarget[columns - 1] = targetCenterRight; 1143 xTarget[columns] = targetRect.left() + targetRect.width(); 1144 1145 yTarget[0] = targetRect.top(); 1146 yTarget[1] = targetCenterTop; 1147 yTarget[rows - 1] = targetCenterBottom; 1148 yTarget[rows] = targetRect.top() + targetRect.height(); 1149 1150 qreal dx = targetCenterWidth; 1151 qreal dy = targetCenterHeight; 1152 1153 switch (rules.horizontal) { 1154 case Qt::StretchTile: 1155 dx = targetCenterWidth; 1156 break; 1157 case Qt::RepeatTile: 1158 dx = sourceCenterWidth; 1159 break; 1160 case Qt::RoundTile: 1161 dx = targetCenterWidth / qreal(columns - 2); 1162 break; 1163 } 1164 1165 for (int i = 2; i < columns - 1; ++i) 1166 xTarget[i] = xTarget[i - 1] + dx; 1167 1168 switch (rules.vertical) { 1169 case Qt::StretchTile: 1170 dy = targetCenterHeight; 1171 break; 1172 case Qt::RepeatTile: 1173 dy = sourceCenterHeight; 1174 break; 1175 case Qt::RoundTile: 1176 dy = targetCenterHeight / qreal(rows - 2); 1177 break; 1178 } 1179 1180 for (int i = 2; i < rows - 1; ++i) 1181 yTarget[i] = yTarget[i - 1] + dy; 1182 1183 // corners 1184 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left 1185 d.point.setX(0.5 * (xTarget[1] + xTarget[0])); 1186 d.point.setY(0.5 * (yTarget[1] + yTarget[0])); 1187 d.source = QRectF(sourceRect.left(), sourceRect.top(), sourceMargins.left(), sourceMargins.top()); 1188 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); 1189 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); 1190 if (hints & QDrawBorderPixmap::OpaqueTopLeft) 1191 opaqueData.append(d); 1192 else 1193 translucentData.append(d); 1194 } 1195 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right 1196 d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); 1197 d.point.setY(0.5 * (yTarget[1] + yTarget[0])); 1198 d.source = QRectF(sourceCenterRight, sourceRect.top(), sourceMargins.right(), sourceMargins.top()); 1199 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); 1200 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); 1201 if (hints & QDrawBorderPixmap::OpaqueTopRight) 1202 opaqueData.append(d); 1203 else 1204 translucentData.append(d); 1205 } 1206 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left 1207 d.point.setX(0.5 * (xTarget[1] + xTarget[0])); 1208 d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1209 d.source = QRectF(sourceRect.left(), sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom()); 1210 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); 1211 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); 1212 if (hints & QDrawBorderPixmap::OpaqueBottomLeft) 1213 opaqueData.append(d); 1214 else 1215 translucentData.append(d); 1216 } 1217 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right 1218 d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); 1219 d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1220 d.source = QRectF(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom()); 1221 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); 1222 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); 1223 if (hints & QDrawBorderPixmap::OpaqueBottomRight) 1224 opaqueData.append(d); 1225 else 1226 translucentData.append(d); 1227 } 1228 1229 // horizontal edges 1230 if (targetCenterWidth > 0 && sourceCenterWidth > 0) { 1231 if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top 1232 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; 1233 d.source = QRectF(sourceCenterLeft, sourceRect.top(), sourceCenterWidth, sourceMargins.top()); 1234 d.point.setY(0.5 * (yTarget[1] + yTarget[0])); 1235 d.scaleX = dx / d.source.width(); 1236 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); 1237 for (int i = 1; i < columns - 1; ++i) { 1238 d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i])); 1239 data.append(d); 1240 } 1241 if (rules.horizontal == Qt::RepeatTile) 1242 data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); 1243 } 1244 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom 1245 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; 1246 d.source = QRectF(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());; 1247 d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1248 d.scaleX = dx / d.source.width(); 1249 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); 1250 for (int i = 1; i < columns - 1; ++i) { 1251 d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i])); 1252 data.append(d); 1253 } 1254 if (rules.horizontal == Qt::RepeatTile) 1255 data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); 1256 } 1257 } 1258 1259 // vertical edges 1260 if (targetCenterHeight > 0 && sourceCenterHeight > 0) { 1261 if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left 1262 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; 1263 d.source = QRectF(sourceRect.left(), sourceCenterTop, sourceMargins.left(), sourceCenterHeight); 1264 d.point.setX(0.5 * (xTarget[1] + xTarget[0])); 1265 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); 1266 d.scaleY = dy / d.source.height(); 1267 for (int i = 1; i < rows - 1; ++i) { 1268 d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i])); 1269 data.append(d); 1270 } 1271 if (rules.vertical == Qt::RepeatTile) 1272 data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); 1273 } 1274 if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right 1275 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; 1276 d.source = QRectF(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight); 1277 d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); 1278 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); 1279 d.scaleY = dy / d.source.height(); 1280 for (int i = 1; i < rows - 1; ++i) { 1281 d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i])); 1282 data.append(d); 1283 } 1284 if (rules.vertical == Qt::RepeatTile) 1285 data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); 1286 } 1287 } 1288 1289 // center 1290 if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { 1291 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; 1292 d.source = QRectF(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight); 1293 d.scaleX = dx / d.source.width(); 1294 d.scaleY = dy / d.source.height(); 1295 1296 qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; 1297 qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY; 1298 1299 for (int j = 1; j < rows - 1; ++j) { 1300 d.point.setY(0.5 * (yTarget[j + 1] + yTarget[j])); 1301 for (int i = 1; i < columns - 1; ++i) { 1302 d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i])); 1303 data.append(d); 1304 } 1305 if (rules.horizontal == Qt::RepeatTile) 1306 data[data.size() - 1].source.setWidth(repeatWidth); 1307 } 1308 if (rules.vertical == Qt::RepeatTile) { 1309 for (int i = 1; i < columns - 1; ++i) 1310 data[data.size() - i].source.setHeight(repeatHeight); 1311 } 1312 } 1313 1314 if (opaqueData.size()) 1315 qDrawPixmaps(painter, opaqueData.data(), opaqueData.size(), pixmap, QDrawPixmaps::OpaqueHint); 1316 if (translucentData.size()) 1317 qDrawPixmaps(painter, translucentData.data(), translucentData.size(), pixmap); 1318 } 1319 1320 /*! 1321 \class QDrawPixmaps::Data 1322 \since 4.6 1323 \internal 1324 1325 This structure is used with the qDrawPixmaps() function. 1326 1327 QPointF point: Specifies the center of the target rectangle. 1328 QRectF source: Specifies the source rectangle in the pixmap passed into the qDrawPixmaps() call. 1329 qreal scaleX: Specifies the horizontal scale of the target rectangle. 1330 qreal scaleY: Specifies the vertical scale of the target rectangle. 1331 qreal rotation: Specifies the rotation of the target rectangle in degrees. 1332 The target rectangle is rotated after scaling. 1333 qreal opacity: Specifies the opacity of the rectangle. 1334 */ 1335 1336 /*! 1337 \enum QDrawPixmaps::DrawingHint 1338 \internal 1339 */ 1340 1341 /*! 1342 \internal 1343 \since 4.6 1344 1345 This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, at multiple positions 1346 with different scale, rotation and opacity on \a painter. \a drawingData is an array of \a 1347 dataCount elements specifying the parameters used to draw each pixmap instance. 1348 This can be used for example to implement a particle system. 1349 */ 1350 void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) 1351 { 1352 QPaintEngine *engine = painter->paintEngine(); 1353 if (!engine) 1354 return; 1355 1356 if (engine->isExtended()) { 1357 static_cast<QPaintEngineEx *>(engine)->drawPixmaps(drawingData, dataCount, pixmap, hints); 1358 } else { 1359 qreal oldOpacity = painter->opacity(); 1360 QTransform oldTransform = painter->transform(); 1361 1362 for (int i = 0; i < dataCount; ++i) { 1363 QTransform transform = oldTransform; 1364 transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); 1365 transform.rotate(drawingData[i].rotation); 1366 painter->setOpacity(oldOpacity * drawingData[i].opacity); 1367 painter->setTransform(transform); 1368 1369 qreal w = drawingData[i].scaleX * drawingData[i].source.width(); 1370 qreal h = drawingData[i].scaleY * drawingData[i].source.height(); 1371 painter->drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); 1372 } 1373 1374 painter->setOpacity(oldOpacity); 1375 painter->setTransform(oldTransform); 1376 } 1377 } 1378 1041 1379 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.