Changeset 561 for trunk/src/gui/painting/qpaintengineex.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/qpaintengineex.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 ** … … 43 43 #include "qpainter_p.h" 44 44 #include "qstroker_p.h" 45 #include "qbezier_p.h" 45 46 #include <private/qpainterpath_p.h> 46 47 … … 56 57 * 57 58 */ 58 59 const QRealRect &QVectorPath::controlPointRect() const 59 QVectorPath::~QVectorPath() 60 { 61 if (m_hints & ShouldUseCacheHint) { 62 CacheEntry *e = m_cache; 63 while (e) { 64 if (e->data) 65 e->cleanup(e->engine, e->data); 66 CacheEntry *n = e->next; 67 delete e; 68 e = n; 69 } 70 } 71 } 72 73 74 QRectF QVectorPath::controlPointRect() const 60 75 { 61 76 if (m_hints & ControlPointRect) 62 return m_cp_rect;77 return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); 63 78 64 79 if (m_count == 0) { 65 80 m_cp_rect.x1 = m_cp_rect.x2 = m_cp_rect.y1 = m_cp_rect.y2 = 0; 66 81 m_hints |= ControlPointRect; 67 return m_cp_rect;82 return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); 68 83 } 69 84 Q_ASSERT(m_points && m_count > 0); … … 89 104 90 105 m_hints |= ControlPointRect; 91 return m_cp_rect; 92 } 106 return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); 107 } 108 109 110 QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, 111 qvectorpath_cache_cleanup cleanup) const{ 112 Q_ASSERT(!lookupCacheData(engine)); 113 if ((m_hints & IsCachedHint) == 0) { 114 m_cache = 0; 115 m_hints |= IsCachedHint; 116 } 117 CacheEntry *e = new CacheEntry; 118 e->engine = engine; 119 e->data = data; 120 e->cleanup = cleanup; 121 e->next = m_cache; 122 m_cache = e; 123 return m_cache; 124 } 125 93 126 94 127 const QVectorPath &qtVectorPathForPath(const QPainterPath &path) … … 101 134 QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path) 102 135 { 103 QRealRect vectorPathBounds = path.controlPointRect(); 104 QRectF rf(vectorPathBounds.x1, vectorPathBounds.y1, 105 vectorPathBounds.x2 - vectorPathBounds.x1, vectorPathBounds.y2 - vectorPathBounds.y1); 136 QRectF rf = path.controlPointRect(); 106 137 s << "QVectorPath(size:" << path.elementCount() 107 138 << " hints:" << hex << path.hints() 108 << rf << ")";139 << rf << ')'; 109 140 return s; 110 141 } … … 139 170 140 171 172 void QPaintEngineExPrivate::replayClipOperations() 173 { 174 Q_Q(QPaintEngineEx); 175 176 QPainter *p = q->painter(); 177 if (!p || !p->d_ptr) 178 return; 179 180 QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo; 181 182 QTransform transform = q->state()->matrix; 183 184 for (int i = 0; i < clipInfo.size(); ++i) { 185 const QPainterClipInfo &info = clipInfo.at(i); 186 187 if (info.matrix != q->state()->matrix) { 188 q->state()->matrix = info.matrix; 189 q->transformChanged(); 190 } 191 192 switch (info.clipType) { 193 case QPainterClipInfo::RegionClip: 194 q->clip(info.region, info.operation); 195 break; 196 case QPainterClipInfo::PathClip: 197 q->clip(info.path, info.operation); 198 break; 199 case QPainterClipInfo::RectClip: 200 q->clip(info.rect, info.operation); 201 break; 202 case QPainterClipInfo::RectFClip: { 203 qreal right = info.rectf.x() + info.rectf.width(); 204 qreal bottom = info.rectf.y() + info.rectf.height(); 205 qreal pts[] = { info.rectf.x(), info.rectf.y(), 206 right, info.rectf.y(), 207 right, bottom, 208 info.rectf.x(), bottom }; 209 QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint); 210 q->clip(vp, info.operation); 211 break; 212 } 213 } 214 } 215 216 if (transform != q->state()->matrix) { 217 q->state()->matrix = transform; 218 q->transformChanged(); 219 } 220 } 221 222 223 bool QPaintEngineExPrivate::hasClipOperations() const 224 { 225 Q_Q(const QPaintEngineEx); 226 227 QPainter *p = q->painter(); 228 if (!p || !p->d_ptr) 229 return false; 230 231 QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo; 232 233 return !clipInfo.isEmpty(); 234 } 141 235 142 236 /******************************************************************************* … … 219 313 }; 220 314 315 316 static QPainterPath::ElementType qpaintengineex_roundedrect_types[] = { 317 QPainterPath::MoveToElement, 318 QPainterPath::LineToElement, 319 QPainterPath::CurveToElement, 320 QPainterPath::CurveToDataElement, 321 QPainterPath::CurveToDataElement, 322 QPainterPath::LineToElement, 323 QPainterPath::CurveToElement, 324 QPainterPath::CurveToDataElement, 325 QPainterPath::CurveToDataElement, 326 QPainterPath::LineToElement, 327 QPainterPath::CurveToElement, 328 QPainterPath::CurveToDataElement, 329 QPainterPath::CurveToDataElement, 330 QPainterPath::LineToElement, 331 QPainterPath::CurveToElement, 332 QPainterPath::CurveToDataElement, 333 QPainterPath::CurveToDataElement 334 }; 335 336 337 221 338 static void qpaintengineex_moveTo(qreal x, qreal y, void *data) { 222 339 ((StrokeHandler *) data)->pts.add(x); … … 245 362 } 246 363 364 QPaintEngineEx::QPaintEngineEx() 365 : QPaintEngine(*new QPaintEngineExPrivate, AllFeatures) 366 { 367 extended = true; 368 } 369 247 370 QPaintEngineEx::QPaintEngineEx(QPaintEngineExPrivate &data) 248 371 : QPaintEngine(data, AllFeatures) … … 250 373 extended = true; 251 374 } 252 253 375 254 376 QPainterState *QPaintEngineEx::createState(QPainterState *orig) const … … 297 419 } else { 298 420 // ### re-enable... 299 //if (pen.isCosmetic()) {300 // d->dashStroker->setClipRect(d->deviceRect);301 //} else {302 // QRectF clipRect = s->matrix.inverted().mapRect(QRectF(d->deviceRect));303 // d->dashStroker->setClipRect(clipRect);304 //}421 if (pen.isCosmetic()) { 422 d->dasher.setClipRect(d->exDeviceRect); 423 } else { 424 QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect)); 425 d->dasher.setClipRect(clipRect); 426 } 305 427 d->dasher.setDashPattern(pen.dashPattern()); 306 428 d->dasher.setDashOffset(pen.dashOffset()); … … 319 441 const qreal *lastPoint = points + (pointCount<<1); 320 442 321 d->activeStroker->begin(d->strokeHandler);322 443 d->strokeHandler->types.reset(); 323 444 d->strokeHandler->pts.reset(); … … 325 446 // Some engines might decide to optimize for the non-shape hint later on... 326 447 uint flags = QVectorPath::WindingFill; 448 449 if (path.elementCount() > 2) 450 flags |= QVectorPath::NonConvexShapeMask; 451 327 452 if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin) 328 flags |= QVectorPath::CurvedShape Hint;453 flags |= QVectorPath::CurvedShapeMask; 329 454 330 455 // ### Perspective Xforms are currently not supported... 331 qreal txscale = 1; 332 if (!(pen.isCosmetic() || (qt_scaleForTransform(state()->matrix, &txscale) && txscale != 1))) { 456 if (!pen.isCosmetic()) { 333 457 // We include cosmetic pens in this case to avoid having to 334 458 // change the current transform. Normal transformed, 335 459 // non-cosmetic pens will be transformed as part of fill 336 460 // later, so they are also covered here.. 461 d->activeStroker->begin(d->strokeHandler); 337 462 if (types) { 338 463 while (points < lastPoint) { … … 354 479 points += 6; 355 480 types += 3; 356 flags |= QVectorPath::CurvedShape Hint;481 flags |= QVectorPath::CurvedShapeMask; 357 482 break; 358 483 default: … … 383 508 d->strokeHandler->types.size(), 384 509 d->strokeHandler->types.data(), 385 QVectorPath::WindingFill);510 flags); 386 511 fill(strokePath, pen.brush()); 387 512 } else { 388 const qreal strokeWidth = d->stroker.strokeWidth();389 d->stroker.setStrokeWidth(strokeWidth * txscale);390 513 // For cosmetic pens we need a bit of trickery... We to process xform the input points 391 if (types) { 392 while (points < lastPoint) { 393 switch (*types) { 394 case QPainterPath::MoveToElement: { 395 QPointF pt = (*(QPointF *) points) * state()->matrix; 396 d->activeStroker->moveTo(pt.x(), pt.y()); 514 if (state()->matrix.type() >= QTransform::TxProject) { 515 QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); 516 d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); 517 } else { 518 d->activeStroker->begin(d->strokeHandler); 519 if (types) { 520 while (points < lastPoint) { 521 switch (*types) { 522 case QPainterPath::MoveToElement: { 523 QPointF pt = (*(QPointF *) points) * state()->matrix; 524 d->activeStroker->moveTo(pt.x(), pt.y()); 525 points += 2; 526 ++types; 527 break; 528 } 529 case QPainterPath::LineToElement: { 530 QPointF pt = (*(QPointF *) points) * state()->matrix; 531 d->activeStroker->lineTo(pt.x(), pt.y()); 532 points += 2; 533 ++types; 534 break; 535 } 536 case QPainterPath::CurveToElement: { 537 QPointF c1 = ((QPointF *) points)[0] * state()->matrix; 538 QPointF c2 = ((QPointF *) points)[1] * state()->matrix; 539 QPointF e = ((QPointF *) points)[2] * state()->matrix; 540 d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); 541 points += 6; 542 types += 3; 543 flags |= QVectorPath::CurvedShapeMask; 544 break; 545 } 546 default: 547 break; 548 } 549 } 550 if (path.hasImplicitClose()) { 551 QPointF pt = * ((QPointF *) path.points()) * state()->matrix; 552 d->activeStroker->lineTo(pt.x(), pt.y()); 553 } 554 555 } else { 556 QPointF p = ((QPointF *)points)[0] * state()->matrix; 557 d->activeStroker->moveTo(p.x(), p.y()); 558 points += 2; 559 ++types; 560 while (points < lastPoint) { 561 QPointF p = ((QPointF *)points)[0] * state()->matrix; 562 d->activeStroker->lineTo(p.x(), p.y()); 397 563 points += 2; 398 564 ++types; 399 break;400 565 } 401 case QPainterPath::LineToElement: { 402 QPointF pt = (*(QPointF *) points) * state()->matrix; 403 d->activeStroker->lineTo(pt.x(), pt.y()); 404 points += 2; 405 ++types; 406 break; 407 } 408 case QPainterPath::CurveToElement: { 409 QPointF c1 = ((QPointF *) points)[0] * state()->matrix; 410 QPointF c2 = ((QPointF *) points)[1] * state()->matrix; 411 QPointF e = ((QPointF *) points)[2] * state()->matrix; 412 d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); 413 points += 6; 414 types += 3; 415 flags |= QVectorPath::CurvedShapeHint; 416 break; 417 } 418 default: 419 break; 420 } 566 if (path.hasImplicitClose()) 567 d->activeStroker->lineTo(p.x(), p.y()); 421 568 } 422 if (path.hasImplicitClose()) { 423 QPointF pt = * ((QPointF *) path.points()) * state()->matrix; 424 d->activeStroker->lineTo(pt.x(), pt.y()); 425 } 426 427 } else { 428 QPointF p = ((QPointF *)points)[0] * state()->matrix; 429 d->activeStroker->moveTo(p.x(), p.y()); 430 points += 2; 431 ++types; 432 while (points < lastPoint) { 433 QPointF p = ((QPointF *)points)[0] * state()->matrix; 434 d->activeStroker->lineTo(p.x(), p.y()); 435 points += 2; 436 ++types; 437 } 438 if (path.hasImplicitClose()) 439 d->activeStroker->lineTo(p.x(), p.y()); 440 } 441 442 d->activeStroker->end(); 443 d->stroker.setStrokeWidth(strokeWidth); 569 d->activeStroker->end(); 570 } 571 444 572 QVectorPath strokePath(d->strokeHandler->pts.data(), 445 573 d->strokeHandler->types.size(), 446 574 d->strokeHandler->types.data(), 447 QVectorPath::WindingFill);575 flags); 448 576 449 577 QTransform xform = state()->matrix; … … 464 592 void QPaintEngineEx::draw(const QVectorPath &path) 465 593 { 466 fill(path, state()->brush); 467 stroke(path, state()->pen); 594 const QBrush &brush = state()->brush; 595 if (qbrush_style(brush) != Qt::NoBrush) 596 fill(path, brush); 597 598 const QPen &pen = state()->pen; 599 if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) 600 stroke(path, pen); 468 601 } 469 602 … … 484 617 void QPaintEngineEx::clip(const QRegion ®ion, Qt::ClipOperation op) 485 618 { 619 if (region.rectCount() == 1) 620 clip(region.boundingRect(), op); 621 486 622 QVector<QRect> rects = region.rects(); 487 623 if (rects.size() <= 32) { … … 600 736 } 601 737 738 739 void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, 740 Qt::SizeMode mode) 741 { 742 qreal x1 = rect.left(); 743 qreal x2 = rect.right(); 744 qreal y1 = rect.top(); 745 qreal y2 = rect.bottom(); 746 747 if (mode == Qt::RelativeSize) { 748 xRadius = xRadius * rect.width() / 200.; 749 yRadius = yRadius * rect.height() / 200.; 750 } 751 752 xRadius = qMin(xRadius, rect.width() / 2); 753 yRadius = qMin(yRadius, rect.height() / 2); 754 755 qreal pts[] = { 756 x1 + xRadius, y1, // MoveTo 757 x2 - xRadius, y1, // LineTo 758 x2 - (1 - KAPPA) * xRadius, y1, // CurveTo 759 x2, y1 + (1 - KAPPA) * yRadius, 760 x2, y1 + yRadius, 761 x2, y2 - yRadius, // LineTo 762 x2, y2 - (1 - KAPPA) * yRadius, // CurveTo 763 x2 - (1 - KAPPA) * xRadius, y2, 764 x2 - xRadius, y2, 765 x1 + xRadius, y2, // LineTo 766 x1 + (1 - KAPPA) * xRadius, y2, // CurveTo 767 x1, y2 - (1 - KAPPA) * yRadius, 768 x1, y2 - yRadius, 769 x1, y1 + yRadius, // LineTo 770 x1, y1 + KAPPA * yRadius, // CurveTo 771 x1 + (1 - KAPPA) * xRadius, y1, 772 x1 + xRadius, y1 773 }; 774 775 QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint); 776 draw(path); 777 } 778 779 780 602 781 void QPaintEngineEx::drawLines(const QLine *lines, int lineCount) 603 782 { … … 685 864 pts[++oset] = points[i].y(); 686 865 } 687 QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath:: NonCurvedShapeHint);866 QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); 688 867 stroke(path, pen); 689 868 pointCount -= 16; … … 716 895 pts[++oset] = points[i].y(); 717 896 } 718 QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath:: NonCurvedShapeHint);897 QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); 719 898 stroke(path, pen); 720 899 pointCount -= 16; … … 778 957 { 779 958 QBrush brush(state()->pen.color(), pixmap); 780 QTransform xform; 781 xform.translate(-s.x(), -s.y()); 959 QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y()); 782 960 brush.setTransform(xform); 783 961 … … 791 969 } 792 970 971 void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/) 972 { 973 qreal oldOpacity = state()->opacity; 974 QTransform oldTransform = state()->matrix; 975 976 for (int i = 0; i < dataCount; ++i) { 977 QTransform transform = oldTransform; 978 transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); 979 transform.rotate(drawingData[i].rotation); 980 state()->opacity = oldOpacity * drawingData[i].opacity; 981 state()->matrix = transform; 982 opacityChanged(); 983 transformChanged(); 984 985 qreal w = drawingData[i].scaleX * drawingData[i].source.width(); 986 qreal h = drawingData[i].scaleY * drawingData[i].source.height(); 987 drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); 988 } 989 990 state()->opacity = oldOpacity; 991 state()->matrix = oldTransform; 992 opacityChanged(); 993 transformChanged(); 994 } 995 793 996 void QPaintEngineEx::setState(QPainterState *s) 794 997 {
Note:
See TracChangeset
for help on using the changeset viewer.