summaryrefslogtreecommitdiffstats
path: root/kolourpaint/patches
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit47d455dd55be855e4cc691c32f687f723d9247ee (patch)
tree52e236aaa2576bdb3840ebede26619692fed6d7d /kolourpaint/patches
downloadtdegraphics-47d455dd55be855e4cc691c32f687f723d9247ee.tar.gz
tdegraphics-47d455dd55be855e4cc691c32f687f723d9247ee.zip
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
Diffstat (limited to 'kolourpaint/patches')
-rw-r--r--kolourpaint/patches/checkerboard-faster-render.diff141
-rw-r--r--kolourpaint/patches/color_eraser_speedup.diff264
-rw-r--r--kolourpaint/patches/doc_resize_no_flicker.diff614
3 files changed, 1019 insertions, 0 deletions
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 <qapplication.h>
+ #include <qbitmap.h>
+ #include <qcursor.h>
+-#include <qimage.h>
+-#include <qpainter.h>
+-#include <qpixmap.h>
+ #if DEBUG_KP_TOOL_PEN
+ #include <qdatetime.h>
+ #endif
++#include <qimage.h>
++#include <qpainter.h>
++#include <qpixmap.h>
++#include <qregion.h>
+
+ #include <kdebug.h>
+ #include <klocale.h>
+@@ -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 <QRect> 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 <dang@kde.org>
+ All rights reserved.
+@@ -33,6 +33,7 @@
+ #include <qpainter.h>
+ #include <qpen.h>
+ #include <qpixmap.h>
++#include <qregion.h>
+ #include <qtimer.h>
+
+ #include <kdebug.h>
+@@ -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 <kpView *> (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 <QRect> rects = mapViewToViewport (viewRegion).rects ();
++ for (QMemArray <QRect>::ConstIterator it = rects.begin ();
++ it != rects.end ();
++ it++)
++ {
++ p.fillRect (*it, Qt::white);
++ }
+
+ p.end ();
+ }
+
+
++template <typename T>
++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 <kpviewscrollablecontainer.moc>
+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 <qpoint.h>
++#include <qregion.h>
+ #include <qscrollview.h>
+ #include <qsize.h>
+
+@@ -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 <qpoint.h>
+ #include <qrect.h>
++#include <qregion.h>
+ #include <qwidget.h>
+
+
+@@ -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 &region)
++{
++ 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 &region)
++{
++ 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 &region);
+
+ QPoint toGlobal (const QWidget *widget, const QPoint &point);
+ QRect toGlobal (const QWidget *widget, const QRect &rect);
++ QRegion toGlobal (const QWidget *widget, const QRegion &region);
+ }
+
+