File indexing completed on 2024-05-05 04:21:20
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #define DEBUG_KP_VIEW 0 0030 #define DEBUG_KP_VIEW_RENDERER ((DEBUG_KP_VIEW && 1) || 0) 0031 0032 0033 #include "views/kpView.h" 0034 #include "kpViewPrivate.h" 0035 0036 #include <QPainter> 0037 #include <QPaintEvent> 0038 #include <QTime> 0039 #include <QScrollBar> 0040 0041 #include "kpLogCategories.h" 0042 0043 #include "layers/selections/kpAbstractSelection.h" 0044 #include "imagelib/kpColor.h" 0045 #include "document/kpDocument.h" 0046 #include "layers/tempImage/kpTempImage.h" 0047 #include "layers/selections/text/kpTextSelection.h" 0048 #include "views/manager/kpViewManager.h" 0049 #include "kpViewScrollableContainer.h" 0050 0051 //--------------------------------------------------------------------- 0052 0053 // protected 0054 QRect kpView::paintEventGetDocRect (const QRect &viewRect) const 0055 { 0056 #if DEBUG_KP_VIEW_RENDERER && 1 0057 qCDebug(kpLogViews) << "kpView::paintEventGetDocRect(" << viewRect << ")"; 0058 #endif 0059 0060 QRect docRect; 0061 0062 // From the "we aren't sure whether to round up or round down" department: 0063 0064 if (zoomLevelX () < 100 || zoomLevelY () < 100) { 0065 docRect = transformViewToDoc (viewRect); 0066 } 0067 else 0068 { 0069 // think of a grid - you need to fully cover the zoomed-in pixels 0070 // when docRect is zoomed back to the view later 0071 docRect = QRect (transformViewToDoc (viewRect.topLeft ()), // round down 0072 transformViewToDoc (viewRect.bottomRight ())); // round down 0073 } 0074 0075 if (zoomLevelX () % 100 || zoomLevelY () % 100) 0076 { 0077 // at least round up the bottom-right point and deal with matrix weirdness: 0078 // - helpful because it ensures we at least cover the required area 0079 // at e.g. 67% or 573% 0080 docRect.setBottomRight (docRect.bottomRight () + QPoint (2, 2)); 0081 } 0082 0083 #if DEBUG_KP_VIEW_RENDERER && 1 0084 qCDebug(kpLogViews) << "\tdocRect=" << docRect; 0085 #endif 0086 kpDocument *doc = document (); 0087 if (doc) 0088 { 0089 docRect = docRect.intersected (doc->rect ()); 0090 #if DEBUG_KP_VIEW_RENDERER && 1 0091 qCDebug(kpLogViews) << "\tintersected with doc=" << docRect; 0092 #endif 0093 } 0094 0095 return docRect; 0096 } 0097 0098 //--------------------------------------------------------------------- 0099 0100 // public static 0101 void kpView::drawTransparentBackground (QPainter *painter, 0102 const QPoint &patternOrigin, 0103 const QRect &viewRect, 0104 bool isPreview) 0105 { 0106 #if DEBUG_KP_VIEW_RENDERER && 1 0107 qCDebug(kpLogViews) << "kpView::drawTransparentBackground() patternOrigin=" 0108 << patternOrigin 0109 << " viewRect=" << viewRect 0110 << " isPreview=" << isPreview 0111 << endl; 0112 #endif 0113 0114 const int cellSize = !isPreview ? 16 : 10; 0115 0116 // TODO: % is unpredictable with negatives. 0117 0118 int starty = viewRect.y (); 0119 if ((starty - patternOrigin.y ()) % cellSize) { 0120 starty -= ((starty - patternOrigin.y ()) % cellSize); 0121 } 0122 0123 int startx = viewRect.x (); 0124 if ((startx - patternOrigin.x ()) % cellSize) { 0125 startx -= ((startx - patternOrigin.x ()) % cellSize); 0126 } 0127 0128 #if DEBUG_KP_VIEW_RENDERER && 1 0129 qCDebug(kpLogViews) << "\tstartXY=" << QPoint (startx, starty); 0130 #endif 0131 0132 painter->save (); 0133 0134 // Clip to <viewRect> as we may draw outside it on all sides. 0135 painter->setClipRect (viewRect, Qt::IntersectClip/*honor existing clip*/); 0136 0137 for (int y = starty; y <= viewRect.bottom (); y += cellSize) 0138 { 0139 for (int x = startx; x <= viewRect.right (); x += cellSize) 0140 { 0141 bool parity = ((x - patternOrigin.x ()) / cellSize + 0142 (y - patternOrigin.y ()) / cellSize) % 2; 0143 QColor col; 0144 0145 if (parity) 0146 { 0147 if (!isPreview) { 0148 col = QColor (213, 213, 213); 0149 } 0150 else { 0151 col = QColor (224, 224, 224); 0152 } 0153 } 0154 else { 0155 col = Qt::white; 0156 } 0157 0158 painter->fillRect (x, y, cellSize, cellSize, col); 0159 } 0160 } 0161 0162 painter->restore (); 0163 } 0164 0165 //--------------------------------------------------------------------- 0166 0167 // protected 0168 void kpView::paintEventDrawCheckerBoard (QPainter *painter, const QRect &viewRect) 0169 { 0170 #if DEBUG_KP_VIEW_RENDERER && 1 0171 qCDebug(kpLogViews) << "kpView(" << objectName () 0172 << ")::paintEventDrawCheckerBoard(viewRect=" << viewRect 0173 << ") origin=" << origin (); 0174 #endif 0175 0176 kpDocument *doc = document (); 0177 if (!doc) { 0178 return; 0179 } 0180 0181 QPoint patternOrigin = origin (); 0182 0183 if (scrollableContainer ()) 0184 { 0185 #if DEBUG_KP_VIEW_RENDERER && 1 0186 qCDebug(kpLogViews) << "\tscrollableContainer: contents[XY]=" 0187 << QPoint (scrollableContainer ()->horizontalScrollBar()->value (), 0188 scrollableContainer ()->verticalScrollBar()->value ()) 0189 << endl; 0190 #endif 0191 // Make checkerboard appear static relative to the scroll view. 0192 // This makes it more obvious that any visible bits of the 0193 // checkboard represent transparent pixels and not gray and white 0194 // squares. 0195 patternOrigin = QPoint (scrollableContainer ()->horizontalScrollBar()->value(), 0196 scrollableContainer ()->verticalScrollBar()->value()); 0197 #if DEBUG_KP_VIEW_RENDERER && 1 0198 qCDebug(kpLogViews) << "\t\tpatternOrigin=" << patternOrigin; 0199 #endif 0200 } 0201 0202 // TODO: this static business doesn't work yet 0203 patternOrigin = QPoint (0, 0); 0204 0205 drawTransparentBackground (painter, patternOrigin, viewRect); 0206 } 0207 0208 //--------------------------------------------------------------------- 0209 0210 // protected 0211 void kpView::paintEventDrawSelection (QImage *destPixmap, const QRect &docRect) 0212 { 0213 #if DEBUG_KP_VIEW_RENDERER && 1 || 0 0214 qCDebug(kpLogViews) << "kpView::paintEventDrawSelection() docRect=" << docRect; 0215 #endif 0216 0217 kpDocument *doc = document (); 0218 if (!doc) 0219 { 0220 #if DEBUG_KP_VIEW_RENDERER && 1 || 0 0221 qCDebug(kpLogViews) << "\tno doc - abort"; 0222 #endif 0223 return; 0224 } 0225 0226 kpAbstractSelection *sel = doc->selection (); 0227 if (!sel) 0228 { 0229 #if DEBUG_KP_VIEW_RENDERER && 1 || 0 0230 qCDebug(kpLogViews) << "\tno sel - abort"; 0231 #endif 0232 return; 0233 } 0234 0235 0236 // 0237 // Draw selection pixmap (if there is one) 0238 // 0239 #if DEBUG_KP_VIEW_RENDERER && 1 || 0 0240 qCDebug(kpLogViews) << "\tdraw sel pixmap @ " << sel->topLeft (); 0241 #endif 0242 sel->paint (destPixmap, docRect); 0243 0244 0245 // 0246 // Draw selection border 0247 // 0248 0249 kpViewManager *vm = viewManager (); 0250 #if DEBUG_KP_VIEW_RENDERER && 1 || 0 0251 qCDebug(kpLogViews) << "\tsel border visible=" 0252 << vm->selectionBorderVisible (); 0253 #endif 0254 if (vm->selectionBorderVisible ()) 0255 { 0256 sel->paintBorder (destPixmap, docRect, vm->selectionBorderFinished ()); 0257 } 0258 0259 0260 // 0261 // Draw text cursor 0262 // 0263 0264 // TODO: It would be nice to display the text cursor even if it's not 0265 // within the text box (this can happen if the text box is too 0266 // small for the text it contains). 0267 // 0268 // However, too much selection repaint code assumes that it 0269 // only paints inside its kpAbstractSelection::boundingRect(). 0270 auto *textSel = dynamic_cast <kpTextSelection *> (sel); 0271 if (textSel && 0272 vm->textCursorEnabled () && 0273 (vm->textCursorBlinkState () || 0274 // For the current main window: 0275 // As long as _any_ view has focus, blink _all_ views not just the 0276 // one with focus. 0277 !vm->hasAViewWithFocus ())) // sync: call will break when vm is not held by 1 mainWindow 0278 { 0279 QRect rect = vm->textCursorRect (); 0280 rect = rect.intersected (textSel->textAreaRect ()); 0281 if (!rect.isEmpty ()) 0282 { 0283 kpPixmapFX::fillRect(destPixmap, 0284 rect.x () - docRect.x (), rect.y () - docRect.y (), 0285 rect.width (), rect.height (), 0286 kpColor::LightGray, kpColor::DarkGray); 0287 } 0288 } 0289 } 0290 0291 //--------------------------------------------------------------------- 0292 0293 // protected 0294 void kpView::paintEventDrawSelectionResizeHandles (const QRect &clipRect) 0295 { 0296 #if DEBUG_KP_VIEW_RENDERER && 1 0297 qCDebug(kpLogViews) << "kpView::paintEventDrawSelectionResizeHandles(" 0298 << clipRect << ")"; 0299 #endif 0300 0301 if (!selectionLargeEnoughToHaveResizeHandles ()) 0302 { 0303 #if DEBUG_KP_VIEW_RENDERER && 1 0304 qCDebug(kpLogViews) << "\tsel not large enough to have resize handles"; 0305 #endif 0306 return; 0307 } 0308 0309 kpViewManager *vm = viewManager (); 0310 if (!vm || !vm->selectionBorderVisible () || !vm->selectionBorderFinished ()) 0311 { 0312 #if DEBUG_KP_VIEW_RENDERER && 1 0313 qCDebug(kpLogViews) << "\tsel border not visible or not finished"; 0314 #endif 0315 0316 return; 0317 } 0318 0319 const QRect selViewRect = selectionViewRect (); 0320 #if DEBUG_KP_VIEW_RENDERER && 1 0321 qCDebug(kpLogViews) << "\tselViewRect=" << selViewRect; 0322 #endif 0323 if (!selViewRect.intersects (clipRect)) 0324 { 0325 #if DEBUG_KP_VIEW_RENDERER && 1 0326 qCDebug(kpLogViews) << "\tdoesn't intersect viewRect"; 0327 #endif 0328 return; 0329 } 0330 0331 QRegion selResizeHandlesRegion = selectionResizeHandlesViewRegion (true/*for renderer*/); 0332 #if DEBUG_KP_VIEW_RENDERER && 1 0333 qCDebug(kpLogViews) << "\tsel resize handles view region=" 0334 << selResizeHandlesRegion << endl; 0335 #endif 0336 0337 QPainter painter(this); 0338 painter.setPen(Qt::black); 0339 painter.setBrush(Qt::cyan); 0340 0341 for (const QRect &r : selResizeHandlesRegion) 0342 painter.drawRect(r); 0343 } 0344 0345 //--------------------------------------------------------------------- 0346 0347 // protected 0348 void kpView::paintEventDrawTempImage (QImage *destPixmap, const QRect &docRect) 0349 { 0350 kpViewManager *vm = viewManager (); 0351 if (!vm) { 0352 return; 0353 } 0354 0355 const kpTempImage *tpi = vm->tempImage (); 0356 #if DEBUG_KP_VIEW_RENDERER && 1 0357 qCDebug(kpLogViews) << "kpView::paintEventDrawTempImage() tempImage=" 0358 << tpi 0359 << " isVisible=" 0360 << (tpi ? tpi->isVisible (vm) : false) 0361 << endl; 0362 #endif 0363 0364 if (!tpi || !tpi->isVisible (vm)) { 0365 return; 0366 } 0367 0368 tpi->paint (destPixmap, docRect); 0369 } 0370 0371 //--------------------------------------------------------------------- 0372 0373 // protected 0374 void kpView::paintEventDrawGridLines (QPainter *painter, const QRect &viewRect) 0375 { 0376 int hzoomMultiple = zoomLevelX () / 100; 0377 int vzoomMultiple = zoomLevelY () / 100; 0378 0379 painter->setPen(Qt::gray); 0380 0381 // horizontal lines 0382 int starty = viewRect.top(); 0383 if (starty % vzoomMultiple) { 0384 starty = (starty + vzoomMultiple) / vzoomMultiple * vzoomMultiple; 0385 } 0386 0387 for (int y = starty; y <= viewRect.bottom(); y += vzoomMultiple) { 0388 painter->drawLine(viewRect.left(), y, viewRect.right(), y); 0389 } 0390 0391 // vertical lines 0392 int startx = viewRect.left(); 0393 if (startx % hzoomMultiple) { 0394 startx = (startx + hzoomMultiple) / hzoomMultiple * hzoomMultiple; 0395 } 0396 0397 for (int x = startx; x <= viewRect.right(); x += hzoomMultiple) { 0398 painter->drawLine(x, viewRect.top (), x, viewRect.bottom()); 0399 } 0400 } 0401 0402 //--------------------------------------------------------------------- 0403 0404 // This is called "_Unclipped" because it may draw outside of 0405 // <viewRect>. 0406 // 0407 // There are 2 reasons for doing so: 0408 // 0409 // A. If, for instance: 0410 // 0411 // 1. <viewRect> = QRect (0, 0, 2, 3) [top-left of the view] 0412 // 2. zoomLevelX() == 800 0413 // 3. zoomLevelY() == 800 0414 // 0415 // Then, the local variable <docRect> will be QRect (0, 0, 1, 1). 0416 // When the part of the document corresponding to <docRect> 0417 // (a single document pixel) is drawn with QPainter::scale(), the 0418 // view rectangle QRect (0, 0, 7, 7) will be overwritten due to the 0419 // 8x zoom. This view rectangle is bigger than <viewRect>. 0420 // 0421 // We can't use QPainter::setClipRect() since it is buggy in Qt 4.3.1 0422 // and clips too many pixels when used in combination with scale() 0423 // [qt-bugs@trolltech.com issue N181038]. ==> MK 10.2.2011 - fixed since Qt-4.4.4 0424 // 0425 // B. paintEventGetDocRect() may, by design, return a larger document 0426 // rectangle than what <viewRect> corresponds to, if the zoom levels 0427 // are not perfectly divisible by 100. 0428 // 0429 // This over-drawing is dangerous -- see the comments in paintEvent(). 0430 // This over-drawing is only safe from Qt's perspective since Qt 0431 // automatically clips all drawing in paintEvent() (which calls us) to 0432 // QPaintEvent::region(). 0433 void kpView::paintEventDrawDoc_Unclipped (const QRect &viewRect) 0434 { 0435 #if DEBUG_KP_VIEW_RENDERER 0436 QTime timer; 0437 timer.start (); 0438 qCDebug(kpLogViews) << "\tviewRect=" << viewRect; 0439 #endif 0440 0441 kpViewManager *vm = viewManager (); 0442 const kpDocument *doc = document (); 0443 0444 Q_ASSERT (vm); 0445 Q_ASSERT (doc); 0446 0447 if (viewRect.isEmpty ()) { 0448 return; 0449 } 0450 0451 QRect docRect = paintEventGetDocRect (viewRect); 0452 0453 #if DEBUG_KP_VIEW_RENDERER && 1 0454 qCDebug(kpLogViews) << "\tdocRect=" << docRect; 0455 #endif 0456 0457 QPainter painter (this); 0458 //painter.setCompositionMode(QPainter::CompositionMode_Source); 0459 0460 QImage docPixmap; 0461 bool tempImageWillBeRendered = false; 0462 0463 // LOTODO: I think <docRect> being empty would be a bug. 0464 if (!docRect.isEmpty ()) 0465 { 0466 docPixmap = doc->getImageAt (docRect); 0467 0468 #if DEBUG_KP_VIEW_RENDERER && 1 0469 qCDebug(kpLogViews) << "\tdocPixmap.hasAlphaChannel()=" 0470 << docPixmap.hasAlphaChannel (); 0471 #endif 0472 0473 tempImageWillBeRendered = 0474 (!doc->selection () && 0475 vm->tempImage () && 0476 vm->tempImage ()->isVisible (vm) && 0477 docRect.intersects (vm->tempImage ()->rect ())); 0478 0479 #if DEBUG_KP_VIEW_RENDERER && 1 0480 qCDebug(kpLogViews) << "\ttempImageWillBeRendered=" << tempImageWillBeRendered 0481 << " (sel=" << doc->selection () 0482 << " tempImage=" << vm->tempImage () 0483 << " tempImage.isVisible=" << (vm->tempImage () ? vm->tempImage ()->isVisible (vm) : false) 0484 << " docRect.intersects(tempImage.rect)=" << (vm->tempImage () ? docRect.intersects (vm->tempImage ()->rect ()) : false) 0485 << ")" 0486 << endl; 0487 #endif 0488 } 0489 0490 0491 // 0492 // Draw checkboard for transparent images and/or views with borders 0493 // 0494 0495 if (docPixmap.hasAlphaChannel() || 0496 (tempImageWillBeRendered && vm->tempImage ()->paintMayAddMask ())) 0497 { 0498 paintEventDrawCheckerBoard (&painter, viewRect); 0499 } 0500 0501 if (!docRect.isEmpty ()) 0502 { 0503 // 0504 // Draw docPixmap + tempImage 0505 // 0506 0507 if (doc->selection ()) 0508 { 0509 paintEventDrawSelection (&docPixmap, docRect); 0510 } 0511 else if (tempImageWillBeRendered) 0512 { 0513 paintEventDrawTempImage (&docPixmap, docRect); 0514 } 0515 0516 #if DEBUG_KP_VIEW_RENDERER && 1 0517 qCDebug(kpLogViews) << "\torigin=" << origin (); 0518 #endif 0519 // Blit scaled version of docPixmap + tempImage. 0520 #if DEBUG_KP_VIEW_RENDERER && 1 0521 QTime scaleTimer; scaleTimer.start (); 0522 #endif 0523 // This is the only troublesome part of the method that draws unclipped. 0524 painter.translate (origin ().x (), origin ().y ()); 0525 painter.scale (double (zoomLevelX ()) / 100.0, 0526 double (zoomLevelY ()) / 100.0); 0527 painter.drawImage (docRect, docPixmap); 0528 //painter.resetMatrix (); // back to 1-1 scaling 0529 #if DEBUG_KP_VIEW_RENDERER && 1 0530 qCDebug(kpLogViews) << "\tscale time=" << scaleTimer.elapsed (); 0531 #endif 0532 0533 } // if (!docRect.isEmpty ()) { 0534 0535 #if DEBUG_KP_VIEW_RENDERER && 1 0536 qCDebug(kpLogViews) << "\tdrawDocRect done in: " << timer.restart () << "ms"; 0537 #endif 0538 } 0539 0540 //--------------------------------------------------------------------- 0541 0542 // protected virtual [base QWidget] 0543 void kpView::paintEvent (QPaintEvent *e) 0544 { 0545 // sync: kpViewPrivate 0546 // WARNING: document(), viewManager() and friends might be 0 in this method. 0547 // TODO: I'm not 100% convinced that we always check if their friends are 0. 0548 0549 #if DEBUG_KP_VIEW_RENDERER && 1 0550 QTime timer; 0551 timer.start (); 0552 #endif 0553 0554 kpViewManager *vm = viewManager (); 0555 0556 #if DEBUG_KP_VIEW_RENDERER && 1 0557 qCDebug(kpLogViews) << "kpView(" << objectName () << ")::paintEvent() vm=" << (bool) vm 0558 << " queueUpdates=" << (vm && vm->queueUpdates ()) 0559 << " fastUpdates=" << (vm && vm->fastUpdates ()) 0560 << " viewRect=" << e->rect () 0561 << " topLeft=" << QPoint (x (), y ()) 0562 << endl; 0563 #endif 0564 0565 if (!vm) { 0566 return; 0567 } 0568 0569 if (vm->queueUpdates ()) 0570 { 0571 // OPT: if this update was due to the document, 0572 // use document coordinates (in case of a zoom change in 0573 // which view coordinates become out of date) 0574 addToQueuedArea (e->region ()); 0575 return; 0576 } 0577 0578 kpDocument *doc = document (); 0579 if (!doc) { 0580 return; 0581 } 0582 0583 0584 // It seems that e->region() is already clipped by Qt to the visible 0585 // part of the view (which could be quite small inside a scrollview). 0586 const QRegion viewRegion = e->region (); 0587 0588 // Draw all of the requested regions of the document _before_ drawing 0589 // the grid lines, buddy rectangle and selection resize handles. 0590 // This ordering is important since paintEventDrawDoc_Unclipped() 0591 // may draw outside of the view rectangle passed to it. 0592 // 0593 // To illustrate this, suppose we changed each iteration of the loop 0594 // to call paintEventDrawDoc_Unclipped() _and_ then, 0595 // paintEventDrawGridLines(). If there are 2 or more iterations of this 0596 // loop, paintEventDrawDoc_Unclipped() in one iteration may draw over 0597 // parts of nearby grid lines (which were drawn in a previous iteration) 0598 // with document pixels. Those grid line parts are probably not going to 0599 // be redrawn, so will appear to be missing. 0600 for (const QRect &r : viewRegion) 0601 paintEventDrawDoc_Unclipped (r); 0602 0603 // 0604 // Draw Grid Lines 0605 // 0606 0607 if ( isGridShown() ) 0608 { 0609 QPainter painter(this); 0610 for (const QRect &r : viewRegion) 0611 paintEventDrawGridLines(&painter, r); 0612 } 0613 0614 const QRect r = buddyViewScrollableContainerRectangle(); 0615 if ( !r.isEmpty() ) 0616 { 0617 QPainter painter(this); 0618 0619 painter.setPen(QPen(Qt::lightGray, 1/*width*/, Qt::DotLine)); 0620 painter.setBackground(Qt::darkGray); 0621 painter.setBackgroundMode(Qt::OpaqueMode); 0622 0623 painter.drawRect(r.x(), r.y(), r.width() - 1, r.height() - 1); 0624 } 0625 0626 if (doc->selection ()) 0627 { 0628 // Draw resize handles on top of possible grid lines 0629 paintEventDrawSelectionResizeHandles (e->rect ()); 0630 } 0631 0632 #if DEBUG_KP_VIEW_RENDERER && 1 0633 qCDebug(kpLogViews) << "\tall done in: " << timer.restart () << "ms"; 0634 #endif 0635 } 0636 0637 //---------------------------------------------------------------------