From 47d455dd55be855e4cc691c32f687f723d9247ee Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegraphics@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- .../patches/checkerboard-faster-render.diff | 141 +++++ kolourpaint/patches/color_eraser_speedup.diff | 264 +++++++++ kolourpaint/patches/doc_resize_no_flicker.diff | 614 +++++++++++++++++++++ 3 files changed, 1019 insertions(+) create mode 100644 kolourpaint/patches/checkerboard-faster-render.diff create mode 100644 kolourpaint/patches/color_eraser_speedup.diff create mode 100644 kolourpaint/patches/doc_resize_no_flicker.diff (limited to 'kolourpaint/patches') diff --git a/kolourpaint/patches/checkerboard-faster-render.diff b/kolourpaint/patches/checkerboard-faster-render.diff new file mode 100644 index 00000000..8c9c6402 --- /dev/null +++ b/kolourpaint/patches/checkerboard-faster-render.diff @@ -0,0 +1,141 @@ +At 100% zoom: kpMainWindow::drawTransparentBackground() accounts for +about 75% of kpView::paintEvent()'s time. Bottleneck is +QPainter::fillRect(). QPainter::drawPixmap() seems much faster. For +800x600, renderer goes from 10ms to 1ms. + +--- kpmainwindow.cpp 2004-08-05 02:10:38.000000000 +1000 ++++ kpmainwindow.cpp 2004-09-29 11:24:45.000000000 +1000 +@@ -838,12 +838,116 @@ + } + + ++#if 1 ++// (indexed by [isPreview][parity]) ++static QPixmap *checkerBoardCache [2][2] = {{0, 0}, {0, 0}}; ++ ++ ++static int checkerBoardCellSize (bool isPreview) ++{ ++ return !isPreview ? 16 : 10; ++} ++ ++ ++// public ++static QPixmap *createCheckerBoardCache (bool isPreview, bool parity) ++{ ++ int cellSize = checkerBoardCellSize (isPreview); ++ const int rep = 2; // must be multiple of 2 ++ ++ QPixmap *newPixmap = new QPixmap (cellSize * rep, cellSize * rep); ++ QPainter painter (newPixmap); ++ ++ int parityAsInt = parity ? 1 : 0; ++ for (int y = 0; y < rep; y++) ++ { ++ for (int x = 0; x < rep; x++) ++ { ++ QColor col; ++ ++ if ((parityAsInt + x + y) % 2) ++ { ++ if (!isPreview) ++ col = QColor (213, 213, 213); ++ else ++ col = QColor (224, 224, 224); ++ } ++ else ++ col = Qt::white; ++ ++ painter.fillRect (x * cellSize, y * cellSize, ++ cellSize, cellSize, ++ col); ++ } ++ } ++ ++ painter.end (); ++ return newPixmap; ++} ++ ++void kpMainWindow::drawTransparentBackground (QPainter *painter, ++ int /*viewWidth*/, int /*viewHeight*/, ++ const QRect &rect, ++ bool isPreview) ++{ ++#if DEBUG_KP_MAIN_WINDOW && 1 || 1 ++ kdDebug () << "\tkpMainWindow::drawTransparentBackground(rect=" ++ << rect << ")" << endl; ++ QTime totalTimer; totalTimer.start (); ++#endif ++ ++ int cellSize = checkerBoardCellSize (isPreview); ++ ++ ++ int starty = rect.y (); ++ if (starty % cellSize) ++ starty -= (starty % cellSize); ++ ++ int startx = rect.x (); ++ if (startx % cellSize) ++ startx -= (startx % cellSize); ++ ++ ++ int parity = ((startx / cellSize + starty / cellSize) % 2) ? 1 : 0; ++ ++ if (!checkerBoardCache [isPreview][parity]) ++ { ++ checkerBoardCache [isPreview][parity] = createCheckerBoardCache (isPreview, parity); ++ } ++ ++ QPixmap *tilePixmap = checkerBoardCache [isPreview][parity]; ++ for (int y = starty; y <= rect.bottom (); y += tilePixmap->height ()) ++ { ++ for (int x = startx; x <= rect.right (); x += tilePixmap->width ()) ++ { ++ painter->drawPixmap (x - rect.x (), y - rect.y (), *tilePixmap); ++ } ++ } ++ ++#if DEBUG_KP_MAIN_WINDOW && 1 || 1 ++{ ++ const int totalTimerElapsed = totalTimer.elapsed (); ++ kdDebug () << "\t\ttotal=" << totalTimerElapsed << endl; ++} ++#endif ++} ++ ++ ++#else ++ + // public + void kpMainWindow::drawTransparentBackground (QPainter *painter, + int /*viewWidth*/, int /*viewHeight*/, + const QRect &rect, + bool isPreview) + { ++#if DEBUG_KP_MAIN_WINDOW && 1 ++ kdDebug () << "\tkpMainWindow::drawTransparentBackground(rect=" ++ << rect << ")" << endl; ++ QTime totalTimer; totalTimer.start (); ++#endif ++ ++ + const int cellSize = !isPreview ? 16 : 10; + + int starty = rect.y (); +@@ -877,8 +982,15 @@ + } + } + painter->restore (); +-} + ++#if DEBUG_KP_MAIN_WINDOW && 1 || 1 ++{ ++ const int totalTimerElapsed = totalTimer.elapsed (); ++ kdDebug () << "\t\ttotal=" << totalTimerElapsed << endl; ++} ++#endif ++} ++#endif + + // private slot + void kpMainWindow::slotUpdateCaption () diff --git a/kolourpaint/patches/color_eraser_speedup.diff b/kolourpaint/patches/color_eraser_speedup.diff new file mode 100644 index 00000000..5e1ff7b7 --- /dev/null +++ b/kolourpaint/patches/color_eraser_speedup.diff @@ -0,0 +1,264 @@ +[probably no longer applies without modification] + +Attempts to improve the performance of the Color Eraser & Eraser +by drawing only _unique_ rectangles across interpolation lines +and by not drawing pixmaps when the user has a solid rectangular +brush. + +- appears to decrease the performance of the Eraser (QRegion + overhead?). +- reduces code clarity +- unsure of whether it increases performance of Color Eraser + (sometimes it seems faster, sometimes not) + +Index: tools/kptoolpen.cpp +=================================================================== +RCS file: /home/kde/kdenonbeta/kolourpaint/tools/kptoolpen.cpp,v +retrieving revision 1.9 +diff -u -p -r1.9 kptoolpen.cpp +--- tools/kptoolpen.cpp 6 Dec 2003 06:53:36 -0000 1.9 ++++ tools/kptoolpen.cpp 6 Dec 2003 06:55:46 -0000 +@@ -34,12 +34,13 @@ + #include + #include + #include +-#include +-#include +-#include + #if DEBUG_KP_TOOL_PEN + #include + #endif ++#include ++#include ++#include ++#include + + #include + #include +@@ -416,31 +417,28 @@ void kpToolPen::draw (const QPoint &this + rect = neededRect (rect, m_brushPixmap [m_mouseButton].width ()); + + #if DEBUG_KP_TOOL_PEN +- if (m_mode & WashesPixmaps) +- { +- kdDebug () << "Washing pixmap (w=" << rect.width () +- << ",h=" << rect.height () << ")" << endl; +- } ++ kdDebug () << "kpToolPen::draw() interpolate: area (w=" << rect.width () ++ << ",h=" << rect.height () << ")" << endl; + QTime timer; + int convAndWashTime; + #endif + +- QPixmap pixmap = document ()->getPixmapAt (rect); +- QPainter painter (&pixmap); ++ // optimsation - only render intersections of rectangles once ++ bool delayedDraw = ((m_mode & SquareBrushes) && ++ ((m_mode & WashesPixmaps) || ++ (m_mode == Eraser)/*solid rectangular brush*/)); ++ ++ ++ QPixmap pixmap; ++ QPainter painter; ++ pixmap = document ()->getPixmapAt (rect); ++ painter.begin (&pixmap); + painter.setPen (color (m_mouseButton)); + +- QImage image; +- if (m_mode & WashesPixmaps) +- { + #if DEBUG_KP_TOOL_PEN ++ if (m_mode & WashesPixmaps) + timer.start (); + #endif +- image = pixmap.convertToImage (); +- #if DEBUG_KP_TOOL_PEN +- convAndWashTime = timer.restart (); +- kdDebug () << "\tconvert to image: " << convAndWashTime << " ms" << endl; +- #endif +- } + + bool didSomething = false; + +@@ -453,10 +451,21 @@ void kpToolPen::draw (const QPoint &this + else if (m_mode & (DrawsPixmaps | WashesPixmaps)) + { + QRgb colorToReplace; ++ QImage image; ++ QRegion region; + + if (m_mode & WashesPixmaps) ++ { + colorToReplace = color (1 - m_mouseButton).rgb (); + ++ image = pixmap.convertToImage (); ++ ++ #if DEBUG_KP_TOOL_PEN ++ convAndWashTime = timer.restart (); ++ kdDebug () << "\tconvert to image: " << convAndWashTime << " ms" << endl; ++ #endif ++ } ++ + // Sweeps a pixmap along a line (modified Bresenham's line algorithm, + // see MODIFIED comment below). + // +@@ -485,19 +494,27 @@ void kpToolPen::draw (const QPoint &this + int x = 0; + int y = 0; + +- if (m_mode & WashesPixmaps) ++ if (delayedDraw) + { +- if (wash (&painter, image, +- colorToReplace, +- rect, plotx + rect.left (), ploty + rect.top ())) +- { +- didSomething = true; +- } ++ region = region.unite (hotRect (plotx + rect.left (), ploty + rect.top ())); + } + else + { +- painter.drawPixmap (hotPoint (plotx, ploty), m_brushPixmap [m_mouseButton]); +- didSomething = true; ++ if (m_mode & WashesPixmaps) ++ { ++ if (wash (&painter, image, ++ colorToReplace, ++ rect, plotx + rect.left (), ploty + rect.top ())) ++ { ++ didSomething = true; ++ } ++ } ++ else ++ { ++ painter.drawPixmap (hotPoint (plotx, ploty), ++ m_brushPixmap [m_mouseButton]); ++ didSomething = true; ++ } + } + + for (int i = 0; i <= inc; i++) +@@ -541,39 +558,115 @@ void kpToolPen::draw (const QPoint &this + // is more than 1 point, of course). This is in contrast to the + // ordinary line algorithm which can create diagonal adjacencies. + ++ if (delayedDraw) ++ { ++ region = region.unite (hotRect (plotx + rect.left (), oldploty + rect.top ())); ++ } ++ else ++ { ++ if (m_mode & WashesPixmaps) ++ { ++ if (wash (&painter, image, ++ colorToReplace, ++ rect, plotx + rect.left (), oldploty + rect.top ())) ++ { ++ didSomething = true; ++ } ++ } ++ else ++ { ++ painter.drawPixmap (hotPoint (plotx, oldploty), ++ m_brushPixmap [m_mouseButton]); ++ didSomething = true; ++ } ++ } ++ } ++ ++ if (delayedDraw) ++ { ++ region = region.unite (hotRect (plotx + rect.left (), ploty + rect.top ())); ++ } ++ else ++ { + if (m_mode & WashesPixmaps) + { + if (wash (&painter, image, + colorToReplace, +- rect, plotx + rect.left (), oldploty + rect.top ())) ++ rect, plotx + rect.left (), ploty + rect.top ())) + { + didSomething = true; + } + } + else + { +- painter.drawPixmap (hotPoint (plotx, oldploty), m_brushPixmap [m_mouseButton]); ++ painter.drawPixmap (hotPoint (plotx, ploty), ++ m_brushPixmap [m_mouseButton]); + didSomething = true; + } + } +- ++ } ++ } ++ ++ if (delayedDraw) ++ { ++ QMemArray rects = region.rects (); ++ ++ int numRects = rects.count (); ++ #if DEBUG_KP_TOOL_PEN ++ kdDebug () << "\tdelayed draw now happening: numRects=" ++ << numRects << endl; ++ int convImageMS = 0; ++ int washMS = 0; ++ int setDocMS = 0; ++ QTime timer; ++ #endif ++ for (int i = 0; i < numRects; i++) ++ { ++ QRect r = rects [i]; ++ QPixmap pm = document ()->getPixmapAt (r); ++ #if DEBUG_KP_TOOL_PEN && 0 ++ kdDebug () << "\tr=" << r << endl; ++ #endif ++ ++ bool drew = false; ++ + if (m_mode & WashesPixmaps) + { ++ timer.start (); ++ + if (wash (&painter, image, + colorToReplace, +- rect, plotx + rect.left (), ploty + rect.top ())) ++ rect, r)) + { +- didSomething = true; ++ drew = true; + } ++ washMS += timer.restart (); + } + else + { +- painter.drawPixmap (hotPoint (plotx, ploty), m_brushPixmap [m_mouseButton]); ++ painter.setBrush (color (m_mouseButton)); ++ painter.drawRect (r.x () - rect.x (), ++ r.y () - rect.y (), ++ r.width (), ++ r.height ()); ++ drew = true; ++ } ++ ++ if (drew) ++ { ++ m_currentCommand->updateBoundingRect (r); + didSomething = true; ++ setDocMS += timer.restart (); + } + } ++ ++ #if DEBUG_KP_TOOL_PEN ++ kdDebug () << "convImageMS=" << convImageMS ++ << " washMS=" << washMS ++ << " setDocMS=" << setDocMS ++ << endl; ++ #endif + } +- + } + + painter.end (); diff --git a/kolourpaint/patches/doc_resize_no_flicker.diff b/kolourpaint/patches/doc_resize_no_flicker.diff new file mode 100644 index 00000000..ae5f9aba --- /dev/null +++ b/kolourpaint/patches/doc_resize_no_flicker.diff @@ -0,0 +1,614 @@ +Eliminates flicker when moving document resize lines / dragging resize +handles by: + +1. Not erasing areas that will be subsequently painted over with resize + lines. +2. Erasing the old areas and painting the new ones atomicly by using + clever NOT'ing of pixels. + +Additionally, recover the resize lines after a window pops up momentarily +over KolourPaint (kpViewScrollableContainer::windowActivationChange()). + +Critical bugs with this code and scrollbars: + +1. Drag scrolling leaves trails of resize lines. +2. Moving the mouse cursor above the start of the document does not result + in a resize line at document y = 1. + +Because I'm still debugging, there are a few hacks in the code such as +"m_resizeLinesDontPaintClever". + +Index: kpviewscrollablecontainer.cpp +=================================================================== +RCS file: /home/kde/kdegraphics/kolourpaint/kpviewscrollablecontainer.cpp,v +retrieving revision 1.7 +diff -u -p -r1.7 kpviewscrollablecontainer.cpp +--- kpviewscrollablecontainer.cpp 29 Jul 2004 12:47:15 -0000 1.7 ++++ kpviewscrollablecontainer.cpp 30 Jul 2004 11:37:20 -0000 +@@ -1,4 +1,4 @@ +- ++static bool inScroll = false; + /* + Copyright (c) 2003-2004 Clarence Dang + All rights reserved. +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -240,7 +241,7 @@ void kpGrip::mousePressEvent (QMouseEven + m_startPoint = e->pos (); + m_currentPoint = e->pos (); + emit beganDraw (); +- grabKeyboard (); ++ //grabKeyboard (); HACK + + setUserMessage (i18n ("Resize Image: Right click to cancel.")); + setCursor (cursorForType (m_type)); +@@ -387,6 +388,7 @@ kpViewScrollableContainer::kpViewScrolla + m_scrollTimerRunOnce (false), + m_resizeRoundedLastViewX (-1), m_resizeRoundedLastViewY (-1), + m_resizeRoundedLastViewDX (0), m_resizeRoundedLastViewDY (0), ++ m_resizeLinesDontPaintClever (0), + m_haveMovedFromOriginalDocSize (false) + + { +@@ -561,6 +563,18 @@ QRect kpViewScrollableContainer::bottomR + m_resizeRoundedLastViewY + bottomResizeLineWidth () - 1)); + } + ++// protected ++QRegion kpViewScrollableContainer::resizeLinesRegion () const ++{ ++ QRegion ret; ++ ++ ret += rightResizeLineRect (); ++ ret += bottomResizeLineRect (); ++ ret += bottomRightResizeLineRect (); ++ ++ return ret; ++} ++ + + // TODO: are these 2 correct? Remember that viewport()->x() == 1, viewport()->y() == 1 + +@@ -581,6 +595,17 @@ QRect kpViewScrollableContainer::mapView + return ret; + } + ++// protected ++QRegion kpViewScrollableContainer::mapViewToViewport (const QRegion &viewRegion) ++{ ++ if (viewRegion.isEmpty ()) ++ return viewRegion; ++ ++ QRegion ret = viewRegion; ++ ret.translate (-contentsX (), -contentsY ()); ++ return ret; ++} ++ + + // protected + QRect kpViewScrollableContainer::mapViewportToGlobal (const QRect &viewportRect) +@@ -589,89 +614,108 @@ QRect kpViewScrollableContainer::mapView + } + + // protected ++QRegion kpViewScrollableContainer::mapViewportToGlobal (const QRegion &viewportRegion) ++{ ++ return kpWidgetMapper::toGlobal (viewport (), viewportRegion); ++} ++ ++ ++// protected + QRect kpViewScrollableContainer::mapViewToGlobal (const QRect &viewRect) + { + return mapViewportToGlobal (mapViewToViewport (viewRect)); + } + ++// protected ++QRegion kpViewScrollableContainer::mapViewToGlobal (const QRegion &viewRegion) ++{ ++ return mapViewportToGlobal (mapViewToViewport (viewRegion)); ++} ++ + + // protected +-void kpViewScrollableContainer::repaintWidgetAtResizeLineViewRect ( +- QWidget *widget, const QRect &resizeLineViewRect) ++void kpViewScrollableContainer::repaintWidgetRegion ( ++ QWidget *widget, ++ const QRegion &viewRegion) + { +- const QRect resizeLineGlobalRect = mapViewToGlobal (resizeLineViewRect); ++ const QRegion globalRegion = mapViewToGlobal (viewRegion); ++ + const QRect widgetGlobalRect = kpWidgetMapper::toGlobal (widget, + widget->rect ()); + +- const QRect redrawGlobalRect = +- resizeLineGlobalRect.intersect (widgetGlobalRect); + +- const QRect redrawWidgetRect = +- kpWidgetMapper::fromGlobal (widget, redrawGlobalRect); ++ const QRegion redrawGlobalRegion = ++ globalRegion.intersect (widgetGlobalRect); + ++ const QRegion redrawWidgetRegion = ++ kpWidgetMapper::fromGlobal (widget, redrawGlobalRegion); + +- if (redrawWidgetRect.isValid ()) ++ ++ if (!redrawWidgetRegion.isEmpty ()) + { + // TODO: should be "!widget->testWFlags (Qt::WRepaintNoErase)" + // but for some reason, doesn't work for viewport(). + const bool erase = !dynamic_cast (widget); +- widget->repaint (redrawWidgetRect, erase); ++ widget->repaint (redrawWidgetRegion, erase); + } + } + + // protected +-void kpViewScrollableContainer::repaintWidgetAtResizeLines (QWidget *widget) ++void kpViewScrollableContainer::eraseResizeLines (const QRegion &viewRegion) + { +- repaintWidgetAtResizeLineViewRect (widget, rightResizeLineRect ()); +- repaintWidgetAtResizeLineViewRect (widget, bottomResizeLineRect ()); +- repaintWidgetAtResizeLineViewRect (widget, bottomRightResizeLineRect ()); +-} ++ if (viewRegion.isEmpty ()) ++ return; + +-// protected +-void kpViewScrollableContainer::eraseResizeLines () +-{ +- if (m_resizeRoundedLastViewX >= 0 && m_resizeRoundedLastViewY >= 0) +- { +- repaintWidgetAtResizeLines (viewport ()); +- repaintWidgetAtResizeLines (m_view); + +- repaintWidgetAtResizeLines (m_bottomGrip); +- repaintWidgetAtResizeLines (m_rightGrip); +- repaintWidgetAtResizeLines (m_bottomRightGrip); +- } ++ repaintWidgetRegion (viewport (), viewRegion); ++ repaintWidgetRegion (m_view, viewRegion); ++ ++ repaintWidgetRegion (m_bottomGrip, viewRegion); ++ repaintWidgetRegion (m_rightGrip, viewRegion); ++ repaintWidgetRegion (m_bottomRightGrip, viewRegion); + } + + + // protected +-void kpViewScrollableContainer::drawResizeLines () ++void kpViewScrollableContainer::drawResizeLines (const QRegion &viewRegion) + { + #if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER +- kdDebug () << "kpViewScrollableContainer::drawResizeLines()" ++ kdDebug () << "kpViewScrollableContainer::drawResizeLines(" ++ << viewRegion <<")" + << " lastViewX=" << m_resizeRoundedLastViewX + << " lastViewY=" << m_resizeRoundedLastViewY + << endl; + #endif + ++ if (viewRegion.isEmpty ()) ++ return; ++ + + QPainter p (viewport (), true/*unclipped*/); + p.setRasterOp (Qt::NotROP); + +- const QRect rightRect = rightResizeLineRect (); +- if (rightRect.isValid ()) +- p.fillRect (mapViewToViewport (rightRect), Qt::white); +- +- const QRect bottomRect = bottomResizeLineRect (); +- if (bottomRect.isValid ()) +- p.fillRect (mapViewToViewport (bottomRect), Qt::white); +- +- const QRect bottomRightRect = bottomRightResizeLineRect (); +- if (bottomRightRect.isValid ()) +- p.fillRect (mapViewToViewport (bottomRightRect), Qt::white); ++ const QMemArray rects = mapViewToViewport (viewRegion).rects (); ++ for (QMemArray ::ConstIterator it = rects.begin (); ++ it != rects.end (); ++ it++) ++ { ++ p.fillRect (*it, Qt::white); ++ } + + p.end (); + } + + ++template ++static inline void swap (T &a, T &b) ++{ ++ T temp = a; ++ ++ a = b; ++ b = temp; ++} ++ ++ + // protected + void kpViewScrollableContainer::updateResizeLines (int viewX, int viewY, + int viewDX, int viewDY) +@@ -686,36 +730,71 @@ void kpViewScrollableContainer::updateRe + << endl; + #endif + +- eraseResizeLines (); +- ++ int newResizeRoundedLastViewX = -1, ++ newResizeRoundedLastViewY = -1; ++ int newResizeRoundedLastViewDX = 0, ++ newResizeRoundedLastViewDY = 0; + + if (viewX >= 0 && viewY >= 0) + { +- m_resizeRoundedLastViewX = m_view->zoomDocToViewX (m_view->zoomViewToDocX (viewX)); +- m_resizeRoundedLastViewY = m_view->zoomDocToViewY (m_view->zoomViewToDocY (viewY)); ++ newResizeRoundedLastViewX = m_view->zoomDocToViewX (m_view->zoomViewToDocX (viewX)); ++ newResizeRoundedLastViewY = m_view->zoomDocToViewY (m_view->zoomViewToDocY (viewY)); + +- m_resizeRoundedLastViewDX = viewDX; +- m_resizeRoundedLastViewDY = viewDY; ++ newResizeRoundedLastViewDX = viewDX; ++ newResizeRoundedLastViewDY = viewDY; + } +- else +- { +- m_resizeRoundedLastViewX = -1; +- m_resizeRoundedLastViewY = -1; + +- m_resizeRoundedLastViewDX = 0; +- m_resizeRoundedLastViewDY = 0; +- } + +- // TODO: This is suboptimal since if another window pops up on top of +- // KolourPaint then disappears, the lines are not redrawn +- // (although this doesn't happen very frequently since we grab the +- // keyboard and mouse when resizing): +- // +- // e.g. sleep 5 && gedit & sleep 10 && killall gedit ++ QRegion oldLinesRegion = resizeLinesRegion (); ++#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER ++ kdDebug () << "\toldLinesRegion=" << oldLinesRegion << endl; ++#endif ++ ++ ++// (macro instead of writing out code to permit experimentation) ++#define SWAP_LAST_VIEW_STATS() \ ++{ \ ++ swap (m_resizeRoundedLastViewX, newResizeRoundedLastViewX); \ ++ swap (m_resizeRoundedLastViewY, newResizeRoundedLastViewY); \ ++ \ ++ swap (m_resizeRoundedLastViewDX, newResizeRoundedLastViewDX); \ ++ swap (m_resizeRoundedLastViewDY, newResizeRoundedLastViewDY); \ ++} ++ SWAP_LAST_VIEW_STATS (); ++#undef SWAP_LAST_VIEW_STATS ++ ++ ++ QRegion newLinesRegion = resizeLinesRegion (); ++#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER ++ kdDebug () << "\tnewLinesRegion=" << newLinesRegion << endl; ++#endif ++ ++ ++ // TODO: This is suboptimal - we will get redraw errors sooner or later. ++ // But I've tried hard to avoid them (e.g. windowActivationChange()). + // + // Should be done in the paintEvent's of every child of the + // scrollview. +- drawResizeLines (); ++ ++ if (m_resizeLinesDontPaintClever) ++ { ++ // (drawResizeLines() NOT's the pixels - so we can erase old and draw ++ // new at the same time) ++ drawResizeLines (newLinesRegion.eor (oldLinesRegion)); ++ #if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER ++ kdDebug () << "\tNOTRregion=" ++ << newLinesRegion.eor (oldLinesRegion) << endl; ++ #endif ++ } ++ else ++ { ++ eraseResizeLines (oldLinesRegion); ++ drawResizeLines (newLinesRegion); ++ #if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER ++ kdDebug () << "\tnot erasing old lines; NOTRregion=" ++ << newLinesRegion << endl; ++ #endif ++ } + } + + +@@ -729,6 +808,8 @@ void kpViewScrollableContainer::slotGrip + + m_haveMovedFromOriginalDocSize = false; + ++ m_resizeLinesDontPaintClever = true; ++ + updateResizeLines (m_view->width (), m_view->height (), + 0/*viewDX*/, 0/*viewDY*/); + +@@ -750,12 +831,28 @@ void kpViewScrollableContainer::slotGrip + + m_haveMovedFromOriginalDocSize = true; + ++#if 0 ++ if (inScroll != !m_resizeLinesNeedErase) ++ { ++ kdError () << "slotGripContDraw EXCEPTION 0: inScroll=" << inScroll << endl; ++ memset (0, 42, 1048576); ++ } ++#endif ++ + updateResizeLines (QMAX (1, QMAX (m_view->width () + viewDX, m_view->zoomDocToViewX (1))), + QMAX (1, QMAX (m_view->height () + viewDY, m_view->zoomDocToViewY (1))), + viewDX, viewDY); + + emit continuedDocResize (newDocSize ()); + ++#if 0 ++ if (!m_resizeLinesNeedErase) ++ { ++ kdError () << "slotGripContDraw EXCEPTION 1" << endl; ++ memset (0, 42, 1048576); ++ } ++#endif ++ + beginDragScroll (QPoint (), QPoint (), m_view->zoomLevelX ()); + } + +@@ -859,8 +956,19 @@ void kpViewScrollableContainer::slotCont + << x << "," << y << ")" << endl; + #endif + ++ m_resizeLinesDontPaintClever++; ++ ++ if (inScroll && 0) ++ { ++ kdError () << "slotContentsMovING EXCEPTION" << endl; ++ memset (0, 42, 1048576); ++ } ++ ++ inScroll = true; + // Reduce flicker - don't let QScrollView scroll to-be-erased lines +- eraseResizeLines (); ++ //eraseResizeLines (resizeLinesRegion ()); ++ //m_resizeLinesNeedErase = false; ++ + + QTimer::singleShot (0, this, SLOT (slotContentsMoved ())); + } +@@ -874,9 +982,27 @@ void kpViewScrollableContainer::slotCont + << " grip=" << grip << endl; + #endif + if (!grip) ++ { ++ inScroll = false; + return; ++ } + ++ if (!inScroll && 0) ++ { ++ kdError () << "slotContentsMoved EXCEPTION" << endl; ++ memset (0, 42, 1048576); ++ } + grip->mouseMovedTo (grip->mapFromGlobal (QCursor::pos ())); ++#if 0 ++ if (!m_resizeLinesNeedErase) ++ { ++ kdError () << "slotContentsMoved EXCEPTION 2" << endl; ++ memset (0, 42, 1048576); ++ } ++#endif ++ inScroll = false; ++ ++ m_resizeLinesDontPaintClever--; + } + + +@@ -1191,7 +1317,7 @@ bool kpViewScrollableContainer::eventFil + // protected virtual [base QScrollView] + void kpViewScrollableContainer::viewportPaintEvent (QPaintEvent *e) + { +-#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER ++#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 0 + kdDebug () << "kpViewScrollableContainer::viewportPaintEvent(" + << e->rect () + << ")" << endl; +@@ -1213,4 +1339,42 @@ void kpViewScrollableContainer::paintEve + } + + ++// protected slot ++void kpViewScrollableContainer::windowActivationChanged () ++{ ++ if (isActiveWindow () && ++ m_resizeRoundedLastViewX >= 0 && m_resizeRoundedLastViewY >= 0) ++ { ++ // We were obscured by a window that popped up monmentarily and ++ // this clobbered the resize lines (since the scrollView's child ++ // widgets don't draw them). This doesn't happen very frequently ++ // since we grab the keyboard and mouse when resizing but: ++ // ++ // e.g. sleep 5 && gedit & sleep 10 && killall gedit ++ // ++ ++ // Repaint child widgets at the resize lines to make sure any ++ // remains of the resize lines are gone. ++ eraseResizeLines (resizeLinesRegion ()); ++ ++ // Draw the resize lines by NOT-ing the child widget pixels. ++ drawResizeLines (resizeLinesRegion ()); ++ } ++} ++ ++// protected virtual [base QWidget] ++void kpViewScrollableContainer::windowActivationChange (bool wasActive) ++{ ++#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 1 ++ kdDebug () << "kpViewScrollableContainer::windowActivationChange(" ++ << wasActive << ")" << endl; ++#endif ++ ++ QScrollView::windowActivationChange (wasActive); ++ ++ // Wait for m_view to update ++ QTimer::singleShot (0, this, SLOT (windowActivationChanged ())); ++} ++ ++ + #include +Index: kpviewscrollablecontainer.h +=================================================================== +RCS file: /home/kde/kdegraphics/kolourpaint/kpviewscrollablecontainer.h,v +retrieving revision 1.3 +diff -u -p -r1.3 kpviewscrollablecontainer.h +--- kpviewscrollablecontainer.h 19 Jul 2004 05:00:47 -0000 1.3 ++++ kpviewscrollablecontainer.h 30 Jul 2004 11:37:21 -0000 +@@ -31,6 +31,7 @@ + + + #include ++#include + #include + #include + +@@ -147,19 +148,23 @@ protected: + QRect bottomResizeLineRect () const; + QRect rightResizeLineRect () const; + QRect bottomRightResizeLineRect () const; ++ QRegion resizeLinesRegion () const; + + QPoint mapViewToViewport (const QPoint &viewPoint); + QRect mapViewToViewport (const QRect &viewRect); ++ QRegion mapViewToViewport (const QRegion &viewRegion); + + QRect mapViewportToGlobal (const QRect &viewportRect); ++ QRegion mapViewportToGlobal (const QRegion &viewportRegion); ++ + QRect mapViewToGlobal (const QRect &viewRect); ++ QRegion mapViewToGlobal (const QRegion &viewRegion); + +- void repaintWidgetAtResizeLineViewRect (QWidget *widget, +- const QRect &resizeLineViewRect); +- void repaintWidgetAtResizeLines (QWidget *widget); +- void eraseResizeLines (); ++ void repaintWidgetRegion (QWidget *widget, ++ const QRegion &viewRegion); ++ void eraseResizeLines (const QRegion &viewRegion); + +- void drawResizeLines (); ++ void drawResizeLines (const QRegion &viewRegion); + + void updateResizeLines (int viewX, int viewY, + int viewDX, int viewDY); +@@ -213,6 +218,12 @@ protected: + virtual void viewportPaintEvent (QPaintEvent *e); + virtual void paintEvent (QPaintEvent *e); + ++protected slots: ++ void windowActivationChanged (); ++protected: ++ virtual void windowActivationChange (bool wasActive); ++ ++ + protected: + kpMainWindow *m_mainWindow; + kpView *m_view; +@@ -223,6 +234,7 @@ protected: + bool m_scrollTimerRunOnce; + int m_resizeRoundedLastViewX, m_resizeRoundedLastViewY; + int m_resizeRoundedLastViewDX, m_resizeRoundedLastViewDY; ++ int m_resizeLinesDontPaintClever; + bool m_haveMovedFromOriginalDocSize; + QString m_gripStatusMessage; + }; +Index: kpwidgetmapper.cpp +=================================================================== +RCS file: /home/kde/kdegraphics/kolourpaint/kpwidgetmapper.cpp,v +retrieving revision 1.1 +diff -u -p -r1.1 kpwidgetmapper.cpp +--- kpwidgetmapper.cpp 10 Jul 2004 11:38:09 -0000 1.1 ++++ kpwidgetmapper.cpp 30 Jul 2004 11:37:21 -0000 +@@ -30,6 +30,7 @@ + + #include + #include ++#include + #include + + +@@ -54,6 +55,17 @@ QRect fromGlobal (const QWidget *widget, + return QRect (topLeft.x (), topLeft.y (), rect.width (), rect.height ()); + } + ++QRegion fromGlobal (const QWidget *widget, const QRegion ®ion) ++{ ++ if (!widget || region.isEmpty ()) ++ return region; ++ ++ const QPoint widgetGlobalTopLeft = toGlobal (widget, QPoint (0, 0)); ++ QRegion ret = region; ++ ret.translate (-widgetGlobalTopLeft.x (), -widgetGlobalTopLeft.y ()); ++ return ret; ++} ++ + + QPoint toGlobal (const QWidget *widget, const QPoint &point) + { +@@ -72,5 +84,16 @@ QRect toGlobal (const QWidget *widget, c + return QRect (topLeft.x (), topLeft.y (), rect.width (), rect.height ()); + } + ++QRegion toGlobal (const QWidget *widget, const QRegion ®ion) ++{ ++ if (!widget || region.isEmpty ()) ++ return region; ++ ++ const QPoint widgetGlobalTopLeft = toGlobal (widget, QPoint (0, 0)); ++ QRegion ret = region; ++ ret.translate (widgetGlobalTopLeft.x (), widgetGlobalTopLeft.y ()); ++ return ret; ++} ++ + + } // namespace kpWidgetMapper { +Index: kpwidgetmapper.h +=================================================================== +RCS file: /home/kde/kdegraphics/kolourpaint/kpwidgetmapper.h,v +retrieving revision 1.1 +diff -u -p -r1.1 kpwidgetmapper.h +--- kpwidgetmapper.h 10 Jul 2004 11:38:09 -0000 1.1 ++++ kpwidgetmapper.h 30 Jul 2004 11:37:21 -0000 +@@ -32,15 +32,18 @@ + class QWidget; + class QPoint; + class QRect; ++class QRegion; + + + namespace kpWidgetMapper + { + QPoint fromGlobal (const QWidget *widget, const QPoint &point); + QRect fromGlobal (const QWidget *widget, const QRect &rect); ++ QRegion fromGlobal (const QWidget *widget, const QRegion ®ion); + + QPoint toGlobal (const QWidget *widget, const QPoint &point); + QRect toGlobal (const QWidget *widget, const QRect &rect); ++ QRegion toGlobal (const QWidget *widget, const QRegion ®ion); + } + + -- cgit v1.2.1