/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt3Support module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "q3canvas.h"
#include "qapplication.h"
#include "qbitmap.h"
#include "qdesktopwidget.h"
#include "qimage.h"
#include "q3ptrdict.h"
#include "qpainter.h"
#include "q3polygonscanner.h"
#include "qtimer.h"
#include "q3tl.h"

#include <stdlib.h>

QT_BEGIN_NAMESPACE

using namespace Qt;

class Q3CanvasData {
public:
    Q3CanvasData() :
	itemDict(1013), animDict(503)
    {
    }

    Q3PtrList<Q3CanvasView> viewList;
    Q3PtrDict<void> itemDict;
    Q3PtrDict<void> animDict;
};

class Q3CanvasViewData {
public:
    Q3CanvasViewData() {}
#ifndef QT_NO_TRANSFORMATIONS
    QMatrix xform;
    QMatrix ixform;
#endif
    QRegion eraseRegion;
};

// clusterizer

class Q3CanvasClusterizer {
public:
    Q3CanvasClusterizer(int maxclusters);
    ~Q3CanvasClusterizer();

    void add(int x, int y); // 1x1 rectangle (point)
    void add(int x, int y, int w, int h);
    void add(const QRect& rect);

    void clear();
    int clusters() const { return count; }
    const QRect& operator[](int i) const;

private:
    QRect* cluster;
    int count;
    const int maxcl;
};

static
void include(QRect& r, const QRect& rect)
{
    if (rect.left()<r.left()) {
	    r.setLeft(rect.left());
    }
    if (rect.right()>r.right()) {
	    r.setRight(rect.right());
    }
    if (rect.top()<r.top()) {
	    r.setTop(rect.top());
    }
    if (rect.bottom()>r.bottom()) {
	    r.setBottom(rect.bottom());
    }
}

/*
A Q3CanvasClusterizer groups rectangles (QRects) into non-overlapping rectangles
by a merging heuristic.
*/
Q3CanvasClusterizer::Q3CanvasClusterizer(int maxclusters) :
    cluster(new QRect[maxclusters]),
    count(0),
    maxcl(maxclusters)
{ }

Q3CanvasClusterizer::~Q3CanvasClusterizer()
{
    delete [] cluster;
}

void Q3CanvasClusterizer::clear()
{
    count=0;
}

void Q3CanvasClusterizer::add(int x, int y)
{
    add(QRect(x,y,1,1));
}

void Q3CanvasClusterizer::add(int x, int y, int w, int h)
{
    add(QRect(x,y,w,h));
}

void Q3CanvasClusterizer::add(const QRect& rect)
{
    QRect biggerrect(rect.x()-1,rect.y()-1,rect.width()+2,rect.height()+2);

    //Q_ASSERT(rect.width()>0 && rect.height()>0);

    int cursor;

    for (cursor=0; cursor<count; cursor++) {
	if (cluster[cursor].contains(rect)) {
	    // Wholly contained already.
	    return;
	}
    }

    int lowestcost=9999999;
    int cheapest=-1;
    cursor = 0;
    while(cursor<count) {
	if (cluster[cursor].intersects(biggerrect)) {
	    QRect larger=cluster[cursor];
	    include(larger,rect);
	    int cost = larger.width()*larger.height() -
		       cluster[cursor].width()*cluster[cursor].height();

	    if (cost < lowestcost) {
		bool bad=false;
		for (int c=0; c<count && !bad; c++) {
		    bad=cluster[c].intersects(larger) && c!=cursor;
		}
		if (!bad) {
		    cheapest=cursor;
		    lowestcost=cost;
		}
	    }
	}
	cursor++;
    }

    if (cheapest>=0) {
	include(cluster[cheapest],rect);
	return;
    }

    if (count < maxcl) {
	cluster[count++]=rect;
	return;
    }

    // Do cheapest of:
    //     add to closest cluster
    //     do cheapest cluster merge, add to new cluster

    lowestcost=9999999;
    cheapest=-1;
    cursor=0;
    while(cursor<count) {
	QRect larger=cluster[cursor];
	include(larger,rect);
	int cost=larger.width()*larger.height()
		- cluster[cursor].width()*cluster[cursor].height();
	if (cost < lowestcost) {
	    bool bad=false;
	    for (int c=0; c<count && !bad; c++) {
		bad=cluster[c].intersects(larger) && c!=cursor;
	    }
	    if (!bad) {
		cheapest=cursor;
		lowestcost=cost;
	    }
	}
	cursor++;
    }

    // ###
    // could make an heuristic guess as to whether we need to bother
    // looking for a cheap merge.

    int cheapestmerge1 = -1;
    int cheapestmerge2 = -1;

    int merge1 = 0;
    while(merge1 < count) {
	int merge2=0;
	while(merge2 < count) {
	    if(merge1!=merge2) {
		QRect larger=cluster[merge1];
		include(larger,cluster[merge2]);
		int cost=larger.width()*larger.height()
		    - cluster[merge1].width()*cluster[merge1].height()
		    - cluster[merge2].width()*cluster[merge2].height();
		if (cost < lowestcost) {
		    bool bad=false;
		    for (int c=0; c<count && !bad; c++) {
			bad=cluster[c].intersects(larger) && c!=cursor;
		    }
		    if (!bad) {
			cheapestmerge1=merge1;
			cheapestmerge2=merge2;
			lowestcost=cost;
		    }
		}
	    }
	    merge2++;
	}
	merge1++;
    }

    if (cheapestmerge1>=0) {
	include(cluster[cheapestmerge1],cluster[cheapestmerge2]);
	cluster[cheapestmerge2]=cluster[count--];
    } else {
	// if (!cheapest) debugRectangles(rect);
	include(cluster[cheapest],rect);
    }

    // NB: clusters do not intersect (or intersection will
    //     overwrite). This is a result of the above algorithm,
    //     given the assumption that (x,y) are ordered topleft
    //     to bottomright.

    // ###
    //
    // add explicit x/y ordering to that comment, move it to the top
    // and rephrase it as pre-/post-conditions.
}

const QRect& Q3CanvasClusterizer::operator[](int i) const
{
    return cluster[i];
}

// end of clusterizer

// there's no more device coordinate clipping done, so introduce these
// clip setting compat functions

static void qt_setclipregion(QPainter *p, const QRegion &r)
{
    QMatrix matrix = p->worldMatrix();
    p->setWorldMatrix(QMatrix());
    p->setClipRegion(r);
    p->setWorldMatrix(matrix);
}

static void qt_setcliprect(QPainter *p, const QRect &r)
{
    qt_setclipregion(p, QRegion(r));
}


class Q_COMPAT_EXPORT Q3CanvasItemPtr {
public:
    Q3CanvasItemPtr() : ptr(0) { }
    Q3CanvasItemPtr(Q3CanvasItem* p) : ptr(p) { }

    bool operator<=(const Q3CanvasItemPtr& that) const
    {
	// Order same-z objects by identity.
	if (that.ptr->z()==ptr->z())
	    return that.ptr <= ptr;
	return that.ptr->z() <= ptr->z();
    }
    bool operator<(const Q3CanvasItemPtr& that) const
    {
	// Order same-z objects by identity.
	if (that.ptr->z()==ptr->z())
	    return that.ptr < ptr;
	return that.ptr->z() < ptr->z();
    }
    bool operator>(const Q3CanvasItemPtr& that) const
    {
	// Order same-z objects by identity.
	if (that.ptr->z()==ptr->z())
	    return that.ptr > ptr;
	return that.ptr->z() > ptr->z();
    }
    bool operator==(const Q3CanvasItemPtr& that) const
    {
	    return that.ptr == ptr;
    }
    operator Q3CanvasItem*() const { return ptr; }

private:
    Q3CanvasItem* ptr;
};


/*!
    \class Q3CanvasItemList
    \compat
    \brief The Q3CanvasItemList class is a list of Q3CanvasItems.

    Q3CanvasItemList is a Q3ValueList of pointers to \l{Q3CanvasItem}s.
    This class is used by some methods in Q3Canvas that need to return
    a list of canvas items.

    The \l Q3ValueList documentation describes how to use this list.

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
  \internal
*/
void Q3CanvasItemList::sort()
{
    qHeapSort(*((Q3ValueList<Q3CanvasItemPtr>*)this));
}

/*!
  \internal
*/
void Q3CanvasItemList::drawUnique(QPainter& painter)
{
    Q3CanvasItem* prev=0;
    for (Iterator it=fromLast(); it!=end(); --it) {
	Q3CanvasItem *g=*it;
	if (g!=prev) {
	    g->draw(painter);
	    prev=g;
	}
    }
}

/*!
    Returns the concatenation of this list and list \a l.
*/
Q3CanvasItemList Q3CanvasItemList::operator+(const Q3CanvasItemList &l) const
{
    Q3CanvasItemList l2(*this);
    for(const_iterator it = l.begin(); it != l.end(); ++it)
       l2.append(*it);
    return l2;
}

class Q3CanvasChunk {
public:
    Q3CanvasChunk() : changed(true) { }
    // Other code assumes lists are not deleted. Assignment is also
    // done on ChunkRecs. So don't add that sort of thing here.

    void sort()
    {
	list.sort();
    }

    const Q3CanvasItemList* listPtr() const
    {
	return &list;
    }

    void add(Q3CanvasItem* item)
    {
	list.prepend(item);
	changed = true;
    }

    void remove(Q3CanvasItem* item)
    {
	list.remove(item);
	changed = true;
    }

    void change()
    {
	changed = true;
    }

    bool hasChanged() const
    {
	return changed;
    }

    bool takeChange()
    {
	bool y = changed;
	changed = false;
	return y;
    }

private:
    Q3CanvasItemList list;
    bool changed;
};


static int gcd(int a, int b)
{
    int r;
    while ((r = a%b)) {
	a=b;
	b=r;
    }
    return b;
}

static int scm(int a, int b)
{
    int g = gcd(a,b);
    return a/g*b;
}



/*!
    \class Q3Canvas
    \compat
    \brief The Q3Canvas class provides a 2D area that can contain Q3CanvasItem objects.

    The Q3Canvas class manages its 2D graphic area and all the canvas
    items the area contains. The canvas has no visual appearance of
    its own. Instead, it is displayed on screen using a Q3CanvasView.
    Multiple Q3CanvasView widgets may be associated with a canvas to
    provide multiple views of the same canvas.

    The canvas is optimized for large numbers of items, particularly
    where only a small percentage of the items change at any
    one time. If the entire display changes very frequently, you should
    consider using your own custom Q3ScrollView subclass.

    Qt provides a rich
    set of canvas item classes, e.g. Q3CanvasEllipse, Q3CanvasLine,
    Q3CanvasPolygon, Q3CanvasPolygonalItem, Q3CanvasRectangle, Q3CanvasSpline,
    Q3CanvasSprite and Q3CanvasText. You can subclass to create your own
    canvas items; Q3CanvasPolygonalItem is the most common base class used
    for this purpose.

    Items appear on the canvas after their \link Q3CanvasItem::show()
    show()\endlink function has been called (or \link
    Q3CanvasItem::setVisible() setVisible(true)\endlink), and \e after
    update() has been called. The canvas only shows items that are
    \link Q3CanvasItem::setVisible() visible\endlink, and then only if
    \l update() is called. (By default the canvas is white and so are
    canvas items, so if nothing appears try changing colors.)

    If you created the canvas without passing a width and height to
    the constructor you must also call resize().

    Although a canvas may appear to be similar to a widget with child
    widgets, there are several notable differences:

    \list
    \i Canvas items are usually much faster to manipulate and redraw than
    child widgets, with the speed advantage becoming especially great when
    there are \e many canvas items and non-rectangular items. In most
    situations canvas items are also a lot more memory efficient than child
    widgets.

    \i It's easy to detect overlapping items (collision detection).

    \i The canvas can be larger than a widget. A million-by-million canvas
    is perfectly possible. At such a size a widget might be very
    inefficient, and some window systems might not support it at all,
    whereas Q3Canvas scales well. Even with a billion pixels and a million
    items, finding a particular canvas item, detecting collisions, etc.,
    is still fast (though the memory consumption may be prohibitive
    at such extremes).

    \i Two or more Q3CanvasView objects can view the same canvas.

    \i An arbitrary transformation matrix can be set on each Q3CanvasView
    which makes it easy to zoom, rotate or shear the viewed canvas.

    \i Widgets provide a lot more functionality, such as input (QKeyEvent,
    QMouseEvent etc.) and layout management (QGridLayout etc.).

    \endlist

    A canvas consists of a background, a number of canvas items organized by
    x, y and z coordinates, and a foreground. A canvas item's z coordinate
    can be treated as a layer number -- canvas items with a higher z
    coordinate appear in front of canvas items with a lower z coordinate.

    The background is white by default, but can be set to a different color
    using setBackgroundColor(), or to a repeated pixmap using
    setBackgroundPixmap() or to a mosaic of smaller pixmaps using
    setTiles(). Individual tiles can be set with setTile(). There
    are corresponding get functions, e.g. backgroundColor() and
    backgroundPixmap().

    Note that Q3Canvas does not inherit from QWidget, even though it has some
    functions which provide the same functionality as those in QWidget. One
    of these is setBackgroundPixmap(); some others are resize(), size(),
    width() and height(). \l Q3CanvasView is the widget used to display a
    canvas on the screen.

    Canvas items are added to a canvas by constructing them and passing the
    canvas to the canvas item's constructor. An item can be moved to a
    different canvas using Q3CanvasItem::setCanvas().

    Canvas items are movable (and in the case of Q3CanvasSprites, animated)
    objects that inherit Q3CanvasItem. Each canvas item has a position on the
    canvas (x, y coordinates) and a height (z coordinate), all of which are
    held as floating-point numbers. Moving canvas items also have x and y
    velocities. It's possible for a canvas item to be outside the canvas
    (for example Q3CanvasItem::x() is greater than width()). When a canvas
    item is off the canvas, onCanvas() returns false and the canvas
    disregards the item. (Canvas items off the canvas do not slow down any
    of the common operations on the canvas.)

    Canvas items can be moved with Q3CanvasItem::move(). The advance()
    function moves all Q3CanvasItem::animated() canvas items and
    setAdvancePeriod() makes Q3Canvas move them automatically on a periodic
    basis. In the context of the Q3Canvas classes, to `animate' a canvas item
    is to set it in motion, i.e. using Q3CanvasItem::setVelocity(). Animation
    of a canvas item itself, i.e. items which change over time, is enabled
    by calling Q3CanvasSprite::setFrameAnimation(), or more generally by
    subclassing and reimplementing Q3CanvasItem::advance(). To detect collisions
    use one of the Q3CanvasItem::collisions() functions.

    The changed parts of the canvas are redrawn (if they are visible in a
    canvas view) whenever update() is called. You can either call update()
    manually after having changed the contents of the canvas, or force
    periodic updates using setUpdatePeriod(). If you have moving objects on
    the canvas, you must call advance() every time the objects should
    move one step further. Periodic calls to advance() can be forced using
    setAdvancePeriod(). The advance() function will call
    Q3CanvasItem::advance() on every item that is \link
    Q3CanvasItem::animated() animated\endlink and trigger an update of the
    affected areas afterwards. (A canvas item that is `animated' is simply
    a canvas item that is in motion.)

    Q3Canvas organizes its canvas items into \e chunks; these are areas on
    the canvas that are used to speed up most operations. Many operations
    start by eliminating most chunks (i.e. those which haven't changed)
    and then process only the canvas items that are in the few interesting
    (i.e. changed) chunks. A valid chunk, validChunk(), is one which is on
    the canvas.

    The chunk size is a key factor to Q3Canvas's speed: if there are too many
    chunks, the speed benefit of grouping canvas items into chunks is
    reduced. If the chunks are too large, it takes too long to process each
    one. The Q3Canvas constructor tries to pick a suitable size, but you
    can call retune() to change it at any time. The chunkSize() function
    returns the current chunk size. The canvas items always make sure
    they're in the right chunks; all you need to make sure of is that
    the canvas uses the right chunk size. A good rule of thumb is that
    the size should be a bit smaller than the average canvas item
    size. If you have moving objects, the chunk size should be a bit
    smaller than the average size of the moving items.

    The foreground is normally nothing, but if you reimplement
    drawForeground(), you can draw things in front of all the canvas
    items.

    Areas can be set as changed with setChanged() and set unchanged with
    setUnchanged(). The entire canvas can be set as changed with
    setAllChanged(). A list of all the items on the canvas is returned by
    allItems().

    An area can be copied (painted) to a QPainter with drawArea().

    If the canvas is resized it emits the resized() signal.

    The examples/canvas application and the 2D graphics page of the
    examples/demo application demonstrate many of Q3Canvas's facilities.

    \sa Q3CanvasView Q3CanvasItem, QtCanvas, {Porting to Graphics View}
*/
void Q3Canvas::init(int w, int h, int chunksze, int mxclusters)
{
    d = new Q3CanvasData;
    awidth=w;
    aheight=h;
    chunksize=chunksze;
    maxclusters=mxclusters;
    chwidth=(w+chunksize-1)/chunksize;
    chheight=(h+chunksize-1)/chunksize;
    chunks=new Q3CanvasChunk[chwidth*chheight];
    update_timer = 0;
    bgcolor = white;
    grid = 0;
    htiles = 0;
    vtiles = 0;
    dblbuf = false;
    debug_redraw_areas = false;
}

/*!
    Create a Q3Canvas with no size. \a parent and \a name are passed to
    the QObject superclass.

    \warning You \e must call resize() at some time after creation to
    be able to use the canvas.
*/
Q3Canvas::Q3Canvas(QObject* parent, const char* name)
    : QObject(parent, name)
{
    init(0,0);
}

/*!
    Constructs a Q3Canvas that is \a w pixels wide and \a h pixels high.
*/
Q3Canvas::Q3Canvas(int w, int h)
{
    init(w,h);
}

/*!
    Constructs a Q3Canvas which will be composed of \a h tiles
    horizontally and \a v tiles vertically. Each tile will be an image
    \a tilewidth by \a tileheight pixels taken from pixmap \a p.

    The pixmap \a p is a list of tiles, arranged left to right, (and
    in the case of pixmaps that have multiple rows of tiles, top to
    bottom), with tile 0 in the top-left corner, tile 1 next to the
    right, and so on, e.g.

    \table
    \row \i 0 \i 1 \i 2 \i 3
    \row \i 4 \i 5 \i 6 \i 7
    \endtable

    The Q3Canvas is initially sized to show exactly the given number of
    tiles horizontally and vertically. If it is resized to be larger,
    the entire matrix of tiles will be repeated as often as necessary
    to cover the area. If it is smaller, tiles to the right and bottom
    will not be visible.

    \sa setTiles()
*/
Q3Canvas::Q3Canvas(QPixmap p,
	int h, int v, int tilewidth, int tileheight)
{
    init(h*tilewidth, v*tileheight, scm(tilewidth,tileheight));
    setTiles(p, h, v, tilewidth, tileheight);
}

void qt_unview(Q3Canvas* c)
{
    for (Q3CanvasView* view=c->d->viewList.first(); view != 0; view=c->d->viewList.next()) {
	view->viewing = 0;
    }
}

/*!
    Destroys the canvas and all the canvas's canvas items.
*/
Q3Canvas::~Q3Canvas()
{
    qt_unview(this);
    Q3CanvasItemList all = allItems();
    for (Q3CanvasItemList::Iterator it=all.begin(); it!=all.end(); ++it)
	delete *it;
    delete [] chunks;
    delete [] grid;
    delete d;
}

/*!
\internal
Returns the chunk at a chunk position \a i, \a j.
*/
Q3CanvasChunk& Q3Canvas::chunk(int i, int j) const
{
    return chunks[i+chwidth*j];
}

/*!
\internal
Returns the chunk at a pixel position \a x, \a y.
*/
Q3CanvasChunk& Q3Canvas::chunkContaining(int x, int y) const
{
    return chunk(x/chunksize,y/chunksize);
}

/*!
    Returns a list of all the items in the canvas.
*/
Q3CanvasItemList Q3Canvas::allItems()
{
    Q3CanvasItemList list;
    for (Q3PtrDictIterator<void> it=d->itemDict; it.currentKey(); ++it) {
	list.prepend((Q3CanvasItem*)it.currentKey());
    }
    return list;
}


/*!
    Changes the size of the canvas to have a width of \a w and a
    height of \a h. This is a slow operation.
*/
void Q3Canvas::resize(int w, int h)
{
    if (awidth==w && aheight==h)
	return;

    Q3CanvasItem* item;
    Q3PtrList<Q3CanvasItem> hidden;
    for (Q3PtrDictIterator<void> it=d->itemDict; it.currentKey(); ++it) {
	if (((Q3CanvasItem*)it.currentKey())->isVisible()) {
	    ((Q3CanvasItem*)it.currentKey())->hide();
	    hidden.append(((Q3CanvasItem*)it.currentKey()));
	}
    }

    int nchwidth=(w+chunksize-1)/chunksize;
    int nchheight=(h+chunksize-1)/chunksize;

    Q3CanvasChunk* newchunks = new Q3CanvasChunk[nchwidth*nchheight];

    // Commit the new values.
    //
    awidth=w;
    aheight=h;
    chwidth=nchwidth;
    chheight=nchheight;
    delete [] chunks;
    chunks=newchunks;

    for (item=hidden.first(); item != 0; item=hidden.next()) {
	item->show();
    }

    setAllChanged();

    emit resized();
}

/*!
    \fn void Q3Canvas::resized()

    This signal is emitted whenever the canvas is resized. Each
    Q3CanvasView connects to this signal to keep the scrollview's size
    correct.
*/

/*!
    Change the efficiency tuning parameters to \a mxclusters clusters,
    each of size \a chunksze. This is a slow operation if there are
    many objects on the canvas.

    The canvas is divided into chunks which are rectangular areas \a
    chunksze wide by \a chunksze high. Use a chunk size which is about
    the average size of the canvas items. If you choose a chunk size
    which is too small it will increase the amount of calculation
    required when drawing since each change will affect many chunks.
    If you choose a chunk size which is too large the amount of
    drawing required will increase because for each change, a lot of
    drawing will be required since there will be many (unchanged)
    canvas items which are in the same chunk as the changed canvas
    items.

    Internally, a canvas uses a low-resolution "chunk matrix" to keep
    track of all the items in the canvas. A 64x64 chunk matrix is the
    default for a 1024x1024 pixel canvas, where each chunk collects
    canvas items in a 16x16 pixel square. This default is also
    affected by setTiles(). You can tune this default using this
    function. For example if you have a very large canvas and want to
    trade off speed for memory then you might set the chunk size to 32
    or 64.

    The \a mxclusters argument is the number of rectangular groups of
    chunks that will be separately drawn. If the canvas has a large
    number of small, dispersed items, this should be about that
    number. Our testing suggests that a large number of clusters is
    almost always best.

*/
void Q3Canvas::retune(int chunksze, int mxclusters)
{
    maxclusters=mxclusters;

    if (chunksize!=chunksze) {
	Q3PtrList<Q3CanvasItem> hidden;
	for (Q3PtrDictIterator<void> it=d->itemDict; it.currentKey(); ++it) {
	    if (((Q3CanvasItem*)it.currentKey())->isVisible()) {
		((Q3CanvasItem*)it.currentKey())->hide();
		hidden.append(((Q3CanvasItem*)it.currentKey()));
	    }
	}

	chunksize=chunksze;

	int nchwidth=(awidth+chunksize-1)/chunksize;
	int nchheight=(aheight+chunksize-1)/chunksize;

	Q3CanvasChunk* newchunks = new Q3CanvasChunk[nchwidth*nchheight];

	// Commit the new values.
	//
	chwidth=nchwidth;
	chheight=nchheight;
	delete [] chunks;
	chunks=newchunks;

	for (Q3CanvasItem* item=hidden.first(); item != 0; item=hidden.next()) {
	    item->show();
	}
    }
}

/*!
    \fn int Q3Canvas::width() const

    Returns the width of the canvas, in pixels.
*/

/*!
    \fn int Q3Canvas::height() const

    Returns the height of the canvas, in pixels.
*/

/*!
    \fn QSize Q3Canvas::size() const

    Returns the size of the canvas, in pixels.
*/

/*!
    \fn QRect Q3Canvas::rect() const

    Returns a rectangle the size of the canvas.
*/


/*!
    \fn bool Q3Canvas::onCanvas(int x, int y) const

    Returns true if the pixel position (\a x, \a y) is on the canvas;
    otherwise returns false.

    \sa validChunk()
*/

/*!
    \fn bool Q3Canvas::onCanvas(const QPoint& p) const
    \overload

    Returns true if the pixel position \a p is on the canvas;
    otherwise returns false.

    \sa validChunk()
*/

/*!
    \fn bool Q3Canvas::validChunk(int x, int y) const

    Returns true if the chunk position (\a x, \a y) is on the canvas;
    otherwise returns false.

    \sa onCanvas()
*/

/*!
  \fn bool Q3Canvas::validChunk(const QPoint& p) const
  \overload

  Returns true if the chunk position \a p is on the canvas; otherwise
  returns false.

  \sa onCanvas()
*/

/*!
    \fn int Q3Canvas::chunkSize() const

    Returns the chunk size of the canvas.

    \sa retune()
*/

/*!
\fn bool Q3Canvas::sameChunk(int x1, int y1, int x2, int y2) const
\internal
Tells if the points (\a x1, \a y1) and (\a x2, \a y2) are within the same chunk.
*/

/*!
\internal
This method adds an the item \a item to the list of Q3CanvasItem objects
in the Q3Canvas. The Q3CanvasItem class calls this.
*/
void Q3Canvas::addItem(Q3CanvasItem* item)
{
    d->itemDict.insert((void*)item,(void*)1);
}

/*!
\internal
This method adds the item \a item to the list of Q3CanvasItem objects
to be moved. The Q3CanvasItem class calls this.
*/
void Q3Canvas::addAnimation(Q3CanvasItem* item)
{
    d->animDict.insert((void*)item,(void*)1);
}

/*!
\internal
This method adds the item \a item  to the list of Q3CanvasItem objects
which are no longer to be moved. The Q3CanvasItem class calls this.
*/
void Q3Canvas::removeAnimation(Q3CanvasItem* item)
{
    d->animDict.remove((void*)item);
}

/*!
\internal
This method removes the item \a item from the list of Q3CanvasItem objects
in this Q3Canvas. The Q3CanvasItem class calls this.
*/
void Q3Canvas::removeItem(Q3CanvasItem* item)
{
    d->itemDict.remove((void*)item);
}

/*!
\internal
This method adds the view \a view to the list of Q3CanvasView objects
viewing this Q3Canvas. The Q3CanvasView class calls this.
*/
void Q3Canvas::addView(Q3CanvasView* view)
{
    d->viewList.append(view);
    if (htiles>1 || vtiles>1 || pm.isNull())
	view->viewport()->setBackgroundColor(backgroundColor());
}

/*!
\internal
This method removes the view \a view from the list of Q3CanvasView objects
viewing this Q3Canvas. The Q3CanvasView class calls this.
*/
void Q3Canvas::removeView(Q3CanvasView* view)
{
    d->viewList.removeRef(view);
}

/*!
    Sets the canvas to call advance() every \a ms milliseconds. Any
    previous setting by setAdvancePeriod() or setUpdatePeriod() is
    overridden.

    If \a ms is less than 0 advancing will be stopped.
*/
void Q3Canvas::setAdvancePeriod(int ms)
{
    if (ms<0) {
	if (update_timer)
	    update_timer->stop();
    } else {
	if (update_timer)
	    delete update_timer;
	update_timer = new QTimer(this);
	connect(update_timer,SIGNAL(timeout()),this,SLOT(advance()));
	update_timer->start(ms);
    }
}

/*!
    Sets the canvas to call update() every \a ms milliseconds. Any
    previous setting by setAdvancePeriod() or setUpdatePeriod() is
    overridden.

    If \a ms is less than 0 automatic updating will be stopped.
*/
void Q3Canvas::setUpdatePeriod(int ms)
{
    if (ms<0) {
	if (update_timer)
	    update_timer->stop();
    } else {
	if (update_timer)
	    delete update_timer;
	update_timer = new QTimer(this);
	connect(update_timer,SIGNAL(timeout()),this,SLOT(update()));
	update_timer->start(ms);
    }
}

/*!
    Moves all Q3CanvasItem::animated() canvas items on the canvas and
    refreshes all changes to all views of the canvas. (An `animated'
    item is an item that is in motion; see setVelocity().)

    The advance takes place in two phases. In phase 0, the
    Q3CanvasItem::advance() function of each Q3CanvasItem::animated()
    canvas item is called with parameter 0. Then all these canvas
    items are called again, with parameter 1. In phase 0, the canvas
    items should not change position, merely examine other items on
    the canvas for which special processing is required, such as
    collisions between items. In phase 1, all canvas items should
    change positions, ignoring any other items on the canvas. This
    two-phase approach allows for considerations of "fairness",
    although no Q3CanvasItem subclasses supplied with Qt do anything
    interesting in phase 0.

    The canvas can be configured to call this function periodically
    with setAdvancePeriod().

    \sa update()
*/
void Q3Canvas::advance()
{
    Q3PtrDictIterator<void> it=d->animDict;
    while (it.current()) {
	Q3CanvasItem* i = (Q3CanvasItem*)(void*)it.currentKey();
	++it;
	if (i)
	    i->advance(0);
    }
    // we expect the dict contains the exact same items as in the
    // first pass.
    it.toFirst();
    while (it.current()) {
	Q3CanvasItem* i = (Q3CanvasItem*)(void*)it.currentKey();
	++it;
	if (i)
	    i->advance(1);
    }
    update();
}

// Don't call this unless you know what you're doing.
// p is in the content's co-ordinate example.
/*!
  \internal
*/
void Q3Canvas::drawViewArea(Q3CanvasView* view, QPainter* p, const QRect& vr, bool)
{
    QPoint tl = view->contentsToViewport(QPoint(0,0));

#ifndef QT_NO_TRANSFORMATIONS
    QMatrix wm = view->worldMatrix();
    QMatrix iwm = wm.invert();
    // ivr = covers all chunks in vr
    QRect ivr = iwm.map(vr);
    QMatrix twm;
    twm.translate(tl.x(),tl.y());
#else
    QRect ivr = vr;
#endif

    QRect all(0,0,width(),height());

    if (!all.contains(ivr)) {
	// Need to clip with edge of canvas.

#ifndef QT_NO_TRANSFORMATIONS
	// For translation-only transformation, it is safe to include the right
	// and bottom edges, but otherwise, these must be excluded since they
	// are not precisely defined (different bresenham paths).
	Q3PointArray a;
	if (wm.m12()==0.0 && wm.m21()==0.0 && wm.m11() == 1.0 && wm.m22() == 1.0)
	    a = Q3PointArray(QRect(all.x(),all.y(),all.width()+1,all.height()+1));
	else
	    a = Q3PointArray(all);

	a = (wm*twm).map(a);
#else
	Q3PointArray a(QRect(all.x(),all.y(),all.width()+1,all.height()+1));
#endif
	if (view->viewport()->backgroundMode() == NoBackground) {
	    QRect cvr = vr; cvr.moveBy(tl.x(),tl.y());
	    qt_setclipregion(p, QRegion(cvr)-QRegion(a));
	    p->fillRect(vr,view->viewport()->palette()
                        .brush(QPalette::Active,QPalette::Window));
	}
	qt_setclipregion(p, a);
    }

    QRect r = vr; r.moveBy(tl.x(),tl.y()); // move to untransformed co-ords
    if (!all.contains(ivr)) {
        QRegion inside = p->clipRegion() & r;
        //QRegion outside = p->clipRegion() - r;
        //p->setClipRegion(outside);
        //p->fillRect(outside.boundingRect(),red);
        qt_setclipregion(p, inside);
    } else {
        qt_setcliprect(p, r);
    }
#ifndef QT_NO_TRANSFORMATIONS
    p->setWorldMatrix(wm*twm);
#else
#endif
    drawCanvasArea(ivr,p,false);
}

/*!
    Repaints changed areas in all views of the canvas.

    \sa advance()
*/
void Q3Canvas::update()
{
    // ##### fix QT_NO_TRANSFORMATIONS
#ifndef QT_NO_TRANSFORMATIONS
    Q3PtrList<QRect> doneareas;
    doneareas.setAutoDelete(true);
#endif

    Q3PtrListIterator<Q3CanvasView> it(d->viewList);
    Q3CanvasView* view;
    while((view=it.current()) != 0) {
	++it;
#ifndef QT_NO_TRANSFORMATIONS
	QMatrix wm = view->worldMatrix();
#endif
	QRect area(view->contentsX(),view->contentsY(),
		   view->visibleWidth(),view->visibleHeight());
	if (area.width()>0 && area.height()>0) {
#ifndef QT_NO_TRANSFORMATIONS
            // r = Visible area of the canvas where there are changes
            QRect r = changeBounds(view->inverseWorldMatrix().map(area));
            if (!r.isEmpty()) {
                QRect tr = wm.map(r);
                tr.moveBy(-view->contentsX(), -view->contentsY());
                view->viewport()->update(tr);
                doneareas.append(new QRect(r));
            }
#endif
	}
    }

#ifndef QT_NO_TRANSFORMATIONS
    for (QRect* r=doneareas.first(); r != 0; r=doneareas.next())
	setUnchanged(*r);
#endif
}


/*!
    Marks the whole canvas as changed.
    All views of the canvas will be entirely redrawn when
    update() is called next.
*/
void Q3Canvas::setAllChanged()
{
    setChanged(QRect(0,0,width(),height()));
}

/*!
    Marks \a area as changed. This \a area will be redrawn in all
    views that are showing it when update() is called next.
*/
void Q3Canvas::setChanged(const QRect& area)
{
    QRect thearea = area.intersected(QRect(0, 0, width(), height()));

    int mx = (thearea.x()+thearea.width()+chunksize)/chunksize;
    int my = (thearea.y()+thearea.height()+chunksize)/chunksize;
    if (mx>chwidth)
	mx=chwidth;
    if (my>chheight)
	my=chheight;

    int x=thearea.x()/chunksize;
    while(x<mx) {
	int y = thearea.y()/chunksize;
	while(y<my) {
	    chunk(x,y).change();
	    y++;
	}
	x++;
    }
}

/*!
    Marks \a area as \e unchanged. The area will \e not be redrawn in
    the views for the next update(), unless it is marked or changed
    again before the next call to update().
*/
void Q3Canvas::setUnchanged(const QRect& area)
{
    QRect thearea = area.intersected(QRect(0, 0, width(), height()));

    int mx = (thearea.x()+thearea.width()+chunksize)/chunksize;
    int my = (thearea.y()+thearea.height()+chunksize)/chunksize;
    if (mx>chwidth)
	mx=chwidth;
    if (my>chheight)
	my=chheight;

    int x=thearea.x()/chunksize;
    while(x<mx) {
	int y = thearea.y()/chunksize;
	while(y<my) {
	    chunk(x,y).takeChange();
	    y++;
	}
	x++;
    }
}


/*!
  \internal
*/
QRect Q3Canvas::changeBounds(const QRect& inarea)
{
    QRect area = inarea.intersected(QRect(0, 0, width(), height()));

    int mx = (area.x()+area.width()+chunksize)/chunksize;
    int my = (area.y()+area.height()+chunksize)/chunksize;
    if (mx > chwidth)
	mx=chwidth;
    if (my > chheight)
	my=chheight;

    QRect result;

    int x=area.x()/chunksize;
    while(x<mx) {
	int y=area.y()/chunksize;
	while(y<my) {
	    Q3CanvasChunk& ch=chunk(x,y);
	    if (ch.hasChanged())
		result |= QRect(x,y,1,1);
	    y++;
	}
	x++;
    }

    if (!result.isEmpty()) {
	result.rLeft() *= chunksize;
	result.rTop() *= chunksize;
	result.rRight() *= chunksize;
	result.rBottom() *= chunksize;
	result.rRight() += chunksize;
	result.rBottom() += chunksize;
    }

    return result;
}

void Q3Canvas::ensureOffScrSize(int osw, int osh)
{
    if (osw > offscr.width() || osh > offscr.height())
	offscr.resize(QMAX(osw,offscr.width()),
		      QMAX(osh,offscr.height()));
    else if (offscr.width() == 0 || offscr.height() == 0)
	offscr.resize(QMAX(offscr.width(), 1),
		       QMAX(offscr.height(), 1));
}

/*!
    Paints all canvas items that are in the area \a clip to \a
    painter, using double-buffering if \a dbuf is true.

    e.g. to print the canvas to a printer:
    \snippet doc/src/snippets/code/src_qt3support_canvas_q3canvas.cpp 0
*/
void Q3Canvas::drawArea(const QRect& clip, QPainter* painter, bool dbuf)
{
    if (painter)
	drawCanvasArea(clip, painter, dbuf);
}

QT_BEGIN_INCLUDE_NAMESPACE
#include <qdebug.h>
QT_END_INCLUDE_NAMESPACE

/*!
  \internal
*/
void Q3Canvas::drawCanvasArea(const QRect& inarea, QPainter* p, bool /*double_buffer*/)
{
    QRect area=inarea.intersected(QRect(0,0,width(),height()));

    if (!p) return; // Nothing to do.

    int lx=area.x()/chunksize;
    int ly=area.y()/chunksize;
    int mx=area.right()/chunksize;
    int my=area.bottom()/chunksize;
    if (mx>=chwidth)
	mx=chwidth-1;
    if (my>=chheight)
	my=chheight-1;

    Q3CanvasItemList allvisible;

    // Stores the region within area that need to be drawn. It is relative
    // to area.topLeft()  (so as to keep within bounds of 16-bit XRegions)
    QRegion rgn;

    for (int x=lx; x<=mx; x++) {
	for (int y=ly; y<=my; y++) {
	    // Only reset change if all views updating, and
	    // wholy within area. (conservative:  ignore entire boundary)
	    //
	    // Disable this to help debugging.
	    //
	    if (!p) {
		if (chunk(x,y).takeChange()) {
		    // ### should at least make bands
		    rgn |= QRegion(x*chunksize-area.x(),y*chunksize-area.y(),
                                   chunksize,chunksize);
		    allvisible += *chunk(x,y).listPtr();
		}
	    } else {
		allvisible += *chunk(x,y).listPtr();
	    }
	}
    }
    allvisible.sort();

    drawBackground(*p,area);
    allvisible.drawUnique(*p);
    drawForeground(*p,area);
}

/*!
\internal
This method to informs the Q3Canvas that a given chunk is
`dirty' and needs to be redrawn in the next Update.

(\a x,\a y) is a chunk location.

The sprite classes call this. Any new derived class of Q3CanvasItem
must do so too. SetChangedChunkContaining can be used instead.
*/
void Q3Canvas::setChangedChunk(int x, int y)
{
    if (validChunk(x,y)) {
	Q3CanvasChunk& ch=chunk(x,y);
	ch.change();
    }
}

/*!
\internal
This method to informs the Q3Canvas that the chunk containing a given
pixel is `dirty' and needs to be redrawn in the next Update.

(\a x,\a y) is a pixel location.

The item classes call this. Any new derived class of Q3CanvasItem must
do so too. SetChangedChunk can be used instead.
*/
void Q3Canvas::setChangedChunkContaining(int x, int y)
{
    if (x>=0 && x<width() && y>=0 && y<height()) {
	Q3CanvasChunk& chunk=chunkContaining(x,y);
	chunk.change();
    }
}

/*!
\internal
This method adds the Q3CanvasItem \a g to the list of those which need to be
drawn if the given chunk at location (\a x, \a y) is redrawn. Like
SetChangedChunk and SetChangedChunkContaining, this method marks the
chunk as `dirty'.
*/
void Q3Canvas::addItemToChunk(Q3CanvasItem* g, int x, int y)
{
    if (validChunk(x,y)) {
	chunk(x,y).add(g);
    }
}

/*!
\internal
This method removes the Q3CanvasItem \a g from the list of those which need to
be drawn if the given chunk at location (\a x, \a y) is redrawn. Like
SetChangedChunk and SetChangedChunkContaining, this method marks the chunk
as `dirty'.
*/
void Q3Canvas::removeItemFromChunk(Q3CanvasItem* g, int x, int y)
{
    if (validChunk(x,y)) {
	chunk(x,y).remove(g);
    }
}


/*!
\internal
This method adds the Q3CanvasItem \a g to the list of those which need to be
drawn if the chunk containing the given pixel (\a x, \a y) is redrawn. Like
SetChangedChunk and SetChangedChunkContaining, this method marks the
chunk as `dirty'.
*/
void Q3Canvas::addItemToChunkContaining(Q3CanvasItem* g, int x, int y)
{
    if (x>=0 && x<width() && y>=0 && y<height()) {
	chunkContaining(x,y).add(g);
    }
}

/*!
\internal
This method removes the Q3CanvasItem \a g from the list of those which need to
be drawn if the chunk containing the given pixel (\a x, \a y) is redrawn.
Like SetChangedChunk and SetChangedChunkContaining, this method
marks the chunk as `dirty'.
*/
void Q3Canvas::removeItemFromChunkContaining(Q3CanvasItem* g, int x, int y)
{
    if (x>=0 && x<width() && y>=0 && y<height()) {
	chunkContaining(x,y).remove(g);
    }
}

/*!
    Returns the color set by setBackgroundColor(). By default, this is
    white.

    This function is not a reimplementation of
    QWidget::backgroundColor() (Q3Canvas is not a subclass of QWidget),
    but all Q3CanvasViews that are viewing the canvas will set their
    backgrounds to this color.

    \sa setBackgroundColor(), backgroundPixmap()
*/
QColor Q3Canvas::backgroundColor() const
{
    return bgcolor;
}

/*!
    Sets the solid background to be the color \a c.

    \sa backgroundColor(), setBackgroundPixmap(), setTiles()
*/
void Q3Canvas::setBackgroundColor(const QColor& c)
{
    if (bgcolor != c) {
	bgcolor = c;
	Q3CanvasView* view=d->viewList.first();
	while (view != 0) {
	    /* XXX this doesn't look right. Shouldn't this
	       be more like setBackgroundPixmap? : Ian */
	    view->viewport()->setEraseColor(bgcolor);
	    view=d->viewList.next();
	}
	setAllChanged();
    }
}

/*!
    Returns the pixmap set by setBackgroundPixmap(). By default,
    this is a null pixmap.

    \sa setBackgroundPixmap(), backgroundColor()
*/
QPixmap Q3Canvas::backgroundPixmap() const
{
    return pm;
}

/*!
    Sets the solid background to be the pixmap \a p repeated as
    necessary to cover the entire canvas.

    \sa backgroundPixmap(), setBackgroundColor(), setTiles()
*/
void Q3Canvas::setBackgroundPixmap(const QPixmap& p)
{
    setTiles(p, 1, 1, p.width(), p.height());
    Q3CanvasView* view = d->viewList.first();
    while (view != 0) {
	view->updateContents();
	view = d->viewList.next();
    }
}

/*!
    This virtual function is called for all updates of the canvas. It
    renders any background graphics using the painter \a painter, in
    the area \a clip. If the canvas has a background pixmap or a tiled
    background, that graphic is used, otherwise the canvas is cleared
    using the background color.

    If the graphics for an area change, you must explicitly call
    setChanged(const QRect&) for the result to be visible when
    update() is next called.

    \sa setBackgroundColor(), setBackgroundPixmap(), setTiles()
*/
void Q3Canvas::drawBackground(QPainter& painter, const QRect& clip)
{
    if (pm.isNull()) {
	painter.fillRect(clip,bgcolor);
    } else if (!grid) {
	for (int x=clip.x()/pm.width();
	    x<(clip.x()+clip.width()+pm.width()-1)/pm.width(); x++)
	{
	    for (int y=clip.y()/pm.height();
		y<(clip.y()+clip.height()+pm.height()-1)/pm.height(); y++)
	    {
		painter.drawPixmap(x*pm.width(), y*pm.height(),pm);
	    }
	}
    } else {
	const int x1 = clip.left()/tilew;
	int x2 = clip.right()/tilew;
	const int y1 = clip.top()/tileh;
	int y2 = clip.bottom()/tileh;

	const int roww = pm.width()/tilew;

	for (int j=y1; j<=y2; j++) {
	    int jj = j%tilesVertically();
	    for (int i=x1; i<=x2; i++) {
		int t = tile(i%tilesHorizontally(), jj);
		int tx = t % roww;
		int ty = t / roww;
		painter.drawPixmap(i*tilew, j*tileh, pm,
				tx*tilew, ty*tileh, tilew, tileh);
	    }
	}
    }
}

/*!
    This virtual function is called for all updates of the canvas. It
    renders any foreground graphics using the painter \a painter, in
    the area \a clip.

    If the graphics for an area change, you must explicitly call
    setChanged(const QRect&) for the result to be visible when
    update() is next called.

    The default is to draw nothing.
*/
void Q3Canvas::drawForeground(QPainter& painter, const QRect& clip)
{
    if (debug_redraw_areas) {
	painter.setPen(red);
	painter.setBrush(NoBrush);
	painter.drawRect(clip);
    }
}

/*!
    If \a y is true (the default) double-buffering is switched on;
    otherwise double-buffering is switched off.

    Turning off double-buffering causes the redrawn areas to flicker a
    little and also gives a (usually small) performance improvement.
*/
void Q3Canvas::setDoubleBuffering(bool y)
{
    dblbuf = y;
}


/*!
    Sets the Q3Canvas to be composed of \a h tiles horizontally and \a
    v tiles vertically. Each tile will be an image \a tilewidth by \a
    tileheight pixels from pixmap \a p.

    The pixmap \a p is a list of tiles, arranged left to right, (and
    in the case of pixmaps that have multiple rows of tiles, top to
    bottom), with tile 0 in the top-left corner, tile 1 next to the
    right, and so on, e.g.

    \table
    \row \i 0 \i 1 \i 2 \i 3
    \row \i 4 \i 5 \i 6 \i 7
    \endtable

    If the canvas is larger than the matrix of tiles, the entire
    matrix is repeated as necessary to cover the whole canvas. If it
    is smaller, tiles to the right and bottom are not visible.

    The width and height of \a p must be a multiple of \a tilewidth
    and \a tileheight. If they are not the function will do nothing.

    If you want to unset any tiling set, then just pass in a null
    pixmap and 0 for \a h, \a v, \a tilewidth, and
    \a tileheight.
*/
void Q3Canvas::setTiles(QPixmap p,
			int h, int v, int tilewidth, int tileheight)
{
    if (!p.isNull() && (!tilewidth || !tileheight ||
	 p.width() % tilewidth != 0 || p.height() % tileheight != 0))
    	return;

    htiles = h;
    vtiles = v;
    delete[] grid;
    pm = p;
    if (h && v && !p.isNull()) {
	grid = new ushort[h*v];
	memset(grid, 0, h*v*sizeof(ushort));
	tilew = tilewidth;
	tileh = tileheight;
    } else {
	grid = 0;
    }
    if (h + v > 10) {
	int s = scm(tilewidth,tileheight);
	retune(s < 128 ? s : QMAX(tilewidth,tileheight));
    }
    setAllChanged();
}

/*!
    \fn int Q3Canvas::tile(int x, int y) const

    Returns the tile at position (\a x, \a y). Initially, all tiles
    are 0.

    The parameters must be within range, i.e.
	0 \< \a x \< tilesHorizontally() and
	0 \< \a y \< tilesVertically().

    \sa setTile()
*/

/*!
    \fn int Q3Canvas::tilesHorizontally() const

    Returns the number of tiles horizontally.
*/

/*!
    \fn int Q3Canvas::tilesVertically() const

    Returns the number of tiles vertically.
*/

/*!
    \fn int Q3Canvas::tileWidth() const

    Returns the width of each tile.
*/

/*!
    \fn int Q3Canvas::tileHeight() const

    Returns the height of each tile.
*/


/*!
    Sets the tile at (\a x, \a y) to use tile number \a tilenum, which
    is an index into the tile pixmaps. The canvas will update
    appropriately when update() is next called.

    The images are taken from the pixmap set by setTiles() and are
    arranged left to right, (and in the case of pixmaps that have
    multiple rows of tiles, top to bottom), with tile 0 in the
    top-left corner, tile 1 next to the right, and so on, e.g.

    \table
    \row \i 0 \i 1 \i 2 \i 3
    \row \i 4 \i 5 \i 6 \i 7
    \endtable

    \sa tile() setTiles()
*/
void Q3Canvas::setTile(int x, int y, int tilenum)
{
    ushort& t = grid[x+y*htiles];
    if (t != tilenum) {
	t = tilenum;
	if (tilew == tileh && tilew == chunksize)
	    setChangedChunk(x, y);	    // common case
	else
	    setChanged(QRect(x*tilew,y*tileh,tilew,tileh));
    }
}


// lesser-used data in canvas item, plus room for extension.
// Be careful adding to this - check all usages.
class Q3CanvasItemExtra {
    Q3CanvasItemExtra() : vx(0.0), vy(0.0) { }
    double vx,vy;
    friend class Q3CanvasItem;
};


/*!
    \class Q3CanvasItem
    \compat
    \brief The Q3CanvasItem class provides an abstract graphic object on a Q3Canvas.

    A variety of Q3CanvasItem subclasses provide immediately usable
    behaviour. This class is a pure abstract superclass providing the
    behaviour that is shared among all the concrete canvas item classes.
    Q3CanvasItem is not intended for direct subclassing. It is much easier
    to subclass one of its subclasses, e.g. Q3CanvasPolygonalItem (the
    commonest base class), Q3CanvasRectangle, Q3CanvasSprite, Q3CanvasEllipse
    or Q3CanvasText.

    Canvas items are added to a canvas by constructing them and passing the
    canvas to the canvas item's constructor. An item can be moved to a
    different canvas using setCanvas().

    Items appear on the canvas after their \link show() show()\endlink
    function has been called (or \link setVisible()
    setVisible(true)\endlink), and \e after update() has been called. The
    canvas only shows items that are \link setVisible() visible\endlink,
    and then only if \l update() is called. If you created the canvas
    without passing a width and height to the constructor you'll also need
    to call \link Q3Canvas::resize() resize()\endlink. Since the canvas
    background defaults to white and canvas items default to white,
    you may need to change colors to see your items.

    A Q3CanvasItem object can be moved in the x(), y() and z() dimensions
    using functions such as move(), moveBy(), setX(), setY() and setZ(). A
    canvas item can be set in motion, `animated', using setAnimated() and
    given a velocity in the x and y directions with setXVelocity() and
    setYVelocity() -- the same effect can be achieved by calling
    setVelocity(). Use the collidesWith() function to see if the canvas item
    will collide on the \e next advance(1) and use collisions() to see what
    collisions have occurred.

    Use Q3CanvasSprite or your own subclass of Q3CanvasSprite to create canvas
    items which are animated, i.e. which change over time.

    The size of a canvas item is given by boundingRect(). Use
    boundingRectAdvanced() to see what the size of the canvas item will be
    \e after the next advance(1) call.

    The rtti() function is used for identifying subclasses of Q3CanvasItem.
    The canvas() function returns a pointer to the canvas which contains the
    canvas item.

    Q3CanvasItem provides the show() and isVisible() functions like those in
    QWidget.

    Q3CanvasItem also provides the setEnabled(), setActive() and
    setSelected() functions; these functions set the relevant boolean and
    cause a repaint but the boolean values they set are not used in
    Q3CanvasItem itself. You can make use of these booleans in your subclasses.

    By default, canvas items have no velocity, no size, and are not in
    motion. The subclasses provided in Qt do not change these defaults
    except where noted.

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    \enum Q3CanvasItem::RttiValues

    This enum is used to name the different types of canvas item.

    \value Rtti_Item Canvas item abstract base class
    \value Rtti_Ellipse
    \value Rtti_Line
    \value Rtti_Polygon
    \value Rtti_PolygonalItem
    \value Rtti_Rectangle
    \value Rtti_Spline
    \value Rtti_Sprite
    \value Rtti_Text

*/

/*!
    \fn void Q3CanvasItem::update()

    Call this function to repaint the canvas's changed chunks.
*/

/*!
    Constructs a Q3CanvasItem on canvas \a canvas.

    \sa setCanvas()
*/
Q3CanvasItem::Q3CanvasItem(Q3Canvas* canvas) :
    cnv(canvas),
    myx(0),myy(0),myz(0)
{
    ani=0;
    vis=0;
    val=0;
    sel=0;
    ena=0;
    act=0;

    ext = 0;
    if (cnv) cnv->addItem(this);
}

/*!
    Destroys the Q3CanvasItem and removes it from its canvas.
*/
Q3CanvasItem::~Q3CanvasItem()
{
    if (cnv) {
	cnv->removeItem(this);
	cnv->removeAnimation(this);
    }
    delete ext;
}

Q3CanvasItemExtra& Q3CanvasItem::extra()
{
    if (!ext)
	ext = new Q3CanvasItemExtra;
    return *ext;
}

/*!
    \fn double Q3CanvasItem::x() const

    Returns the horizontal position of the canvas item. Note that
    subclasses often have an origin other than the top-left corner.
*/

/*!
    \fn double Q3CanvasItem::y() const

    Returns the vertical position of the canvas item. Note that
    subclasses often have an origin other than the top-left corner.
*/

/*!
    \fn double Q3CanvasItem::z() const

    Returns the z index of the canvas item, which is used for visual
    order: higher-z items obscure (are in front of) lower-z items.
*/

/*!
    \fn void Q3CanvasItem::setX(double x)

    Moves the canvas item so that its x-position is \a x.

    \sa x(), move()
*/

/*!
    \fn void Q3CanvasItem::setY(double y)

    Moves the canvas item so that its y-position is \a y.

    \sa y(), move()
*/

/*!
    \fn void Q3CanvasItem::setZ(double z)

    Sets the z index of the canvas item to \a z. Higher-z items
    obscure (are in front of) lower-z items.

    \sa z(), move()
*/


/*!
    Moves the canvas item relative to its current position by (\a dx,
    \a dy).
*/
void Q3CanvasItem::moveBy(double dx, double dy)
{
    if (dx || dy) {
	removeFromChunks();
	myx += dx;
	myy += dy;
	addToChunks();
    }
}


/*!
    Moves the canvas item to the absolute position (\a x, \a y).
*/
void Q3CanvasItem::move(double x, double y)
{
    moveBy(x-myx, y-myy);
}


/*!
    Returns true if the canvas item is in motion; otherwise returns
    false.

    \sa setVelocity(), setAnimated()
*/
bool Q3CanvasItem::animated() const
{
    return (bool)ani;
}

/*!
    Sets the canvas item to be in motion if \a y is true, or not if \a
    y is false. The speed and direction of the motion is set with
    setVelocity(), or with setXVelocity() and setYVelocity().

    \sa advance(), Q3Canvas::advance()
*/
void Q3CanvasItem::setAnimated(bool y)
{
    if (y != (bool)ani) {
	ani = (uint)y;
	if (y) {
	    cnv->addAnimation(this);
	} else {
	    cnv->removeAnimation(this);
	}
    }
}

/*!
    \fn void Q3CanvasItem::setXVelocity(double vx)

    Sets the horizontal component of the canvas item's velocity to \a vx.

    \sa setYVelocity() setVelocity()
*/

/*!
    \fn void Q3CanvasItem::setYVelocity(double vy)

    Sets the vertical component of the canvas item's velocity to \a vy.

    \sa setXVelocity() setVelocity()
*/

/*!
    Sets the canvas item to be in motion, moving by \a vx and \a vy
    pixels in the horizontal and vertical directions respectively.

    \sa advance() setXVelocity() setYVelocity()
*/
void Q3CanvasItem::setVelocity(double vx, double vy)
{
    if (ext || vx!=0.0 || vy!=0.0) {
	if (!ani)
	    setAnimated(true);
	extra().vx = vx;
	extra().vy = vy;
    }
}

/*!
    Returns the horizontal velocity component of the canvas item.
*/
double Q3CanvasItem::xVelocity() const
{
    return ext ? ext->vx : 0;
}

/*!
    Returns the vertical velocity component of the canvas item.
*/
double Q3CanvasItem::yVelocity() const
{
    return ext ? ext->vy : 0;
}

/*!
    The default implementation moves the canvas item, if it is
    animated(), by the preset velocity if \a phase is 1, and does
    nothing if \a phase is 0.

    Note that if you reimplement this function, the reimplementation
    must not change the canvas in any way, for example it must not add
    or remove items.

    \sa Q3Canvas::advance() setVelocity()
*/
void Q3CanvasItem::advance(int phase)
{
    if (ext && phase==1)
	moveBy(ext->vx,ext->vy);
}

/*!
    \fn void Q3CanvasItem::draw(QPainter& painter)

    This abstract virtual function draws the canvas item using \a painter.
*/

/*!
    Sets the Q3Canvas upon which the canvas item is to be drawn to \a c.

    \sa canvas()
*/
void Q3CanvasItem::setCanvas(Q3Canvas* c)
{
    bool v=isVisible();
    setVisible(false);
    if (cnv) {
	if (ext)
	    cnv->removeAnimation(this);
	cnv->removeItem(this);
    }
    cnv=c;
    if (cnv) {
	cnv->addItem(this);
	if (ext)
	    cnv->addAnimation(this);
    }
    setVisible(v);
}

/*!
    \fn Q3Canvas* Q3CanvasItem::canvas() const

    Returns the canvas containing the canvas item.
*/

/*! Shorthand for setVisible(true). */
void Q3CanvasItem::show()
{
    setVisible(true);
}

/*! Shorthand for setVisible(false). */
void Q3CanvasItem::hide()
{
    setVisible(false);
}

/*!
    Makes the canvas item visible if \a yes is true, or invisible if
    \a yes is false. The change takes effect when Q3Canvas::update() is
    next called.
*/
void Q3CanvasItem::setVisible(bool yes)
{
    if ((bool)vis!=yes) {
	if (yes) {
	    vis=(uint)yes;
	    addToChunks();
	} else {
	    removeFromChunks();
	    vis=(uint)yes;
	}
    }
}
/*!
    \obsolete
    \fn bool Q3CanvasItem::visible() const
    Use isVisible() instead.
*/

/*!
    \fn bool Q3CanvasItem::isVisible() const

    Returns true if the canvas item is visible; otherwise returns
    false.

    Note that in this context true does \e not mean that the canvas
    item is currently in a view, merely that if a view is showing the
    area where the canvas item is positioned, and the item is not
    obscured by items with higher z values, and the view is not
    obscured by overlaying windows, it would be visible.

    \sa setVisible(), z()
*/

/*!
    \obsolete
    \fn bool Q3CanvasItem::selected() const
    Use isSelected() instead.
*/

/*!
    \fn bool Q3CanvasItem::isSelected() const

    Returns true if the canvas item is selected; otherwise returns false.
*/

/*!
    Sets the selected flag of the item to \a yes. If this changes the
    item's selected state the item will be redrawn when
    Q3Canvas::update() is next called.

    The Q3Canvas, Q3CanvasItem and the Qt-supplied Q3CanvasItem
    subclasses do not make use of this value. The setSelected()
    function is supplied because many applications need it, but it is
    up to you how you use the isSelected() value.
*/
void Q3CanvasItem::setSelected(bool yes)
{
    if ((bool)sel!=yes) {
	sel=(uint)yes;
	changeChunks();
    }
}

/*!
    \obsolete
    \fn bool Q3CanvasItem::enabled() const
    Use isEnabled() instead.
*/

/*!
    \fn bool Q3CanvasItem::isEnabled() const

    Returns true if the Q3CanvasItem is enabled; otherwise returns false.
*/

/*!
    Sets the enabled flag of the item to \a yes. If this changes the
    item's enabled state the item will be redrawn when
    Q3Canvas::update() is next called.

    The Q3Canvas, Q3CanvasItem and the Qt-supplied Q3CanvasItem
    subclasses do not make use of this value. The setEnabled()
    function is supplied because many applications need it, but it is
    up to you how you use the isEnabled() value.
*/
void Q3CanvasItem::setEnabled(bool yes)
{
    if (ena!=(uint)yes) {
	ena=(uint)yes;
	changeChunks();
    }
}

/*!
    \obsolete
    \fn bool Q3CanvasItem::active() const
    Use isActive() instead.
*/

/*!
    \fn bool Q3CanvasItem::isActive() const

    Returns true if the Q3CanvasItem is active; otherwise returns false.
*/

/*!
    Sets the active flag of the item to \a yes. If this changes the
    item's active state the item will be redrawn when
    Q3Canvas::update() is next called.

    The Q3Canvas, Q3CanvasItem and the Qt-supplied Q3CanvasItem
    subclasses do not make use of this value. The setActive() function
    is supplied because many applications need it, but it is up to you
    how you use the isActive() value.
*/
void Q3CanvasItem::setActive(bool yes)
{
    if (act!=(uint)yes) {
	act=(uint)yes;
	changeChunks();
    }
}

bool qt_testCollision(const Q3CanvasSprite* s1, const Q3CanvasSprite* s2)
{
    const QImage* s2image = s2->imageAdvanced()->collision_mask;
    QRect s2area = s2->boundingRectAdvanced();

    QRect cyourarea(s2area.x(),s2area.y(),
	    s2area.width(),s2area.height());

    QImage* s1image=s1->imageAdvanced()->collision_mask;

    QRect s1area = s1->boundingRectAdvanced();

    QRect ourarea = s1area.intersected(cyourarea);

    if (ourarea.isEmpty())
	return false;

    int x2=ourarea.x()-cyourarea.x();
    int y2=ourarea.y()-cyourarea.y();
    int x1=ourarea.x()-s1area.x();
    int y1=ourarea.y()-s1area.y();
    int w=ourarea.width();
    int h=ourarea.height();

    if (!s2image) {
	if (!s1image)
	    return w>0 && h>0;
	// swap everything around
	int t;
	t=x1; x1=x2; x2=t;
	t=y1; x1=y2; y2=t;
	s2image = s1image;
	s1image = 0;
    }

    // s2image != 0

    // A non-linear search may be more efficient.
    // Perhaps spiralling out from the center, or a simpler
    // vertical expansion from the centreline.

    // We assume that sprite masks don't have
    // different bit orders.
    //
    // Q_ASSERT(s1image->bitOrder()==s2image->bitOrder());

    if (s1image) {
	if (s1image->bitOrder() == QImage::LittleEndian) {
	    for (int j=0; j<h; j++) {
		uchar* ml = s1image->scanLine(y1+j);
		const uchar* yl = s2image->scanLine(y2+j);
		for (int i=0; i<w; i++) {
		    if (*(yl + ((x2+i) >> 3)) & (1 << ((x2+i) & 7))
		    && *(ml + ((x1+i) >> 3)) & (1 << ((x1+i) & 7)))
		    {
			return true;
		    }
		}
	    }
	} else {
	    for (int j=0; j<h; j++) {
		uchar* ml = s1image->scanLine(y1+j);
		const uchar* yl = s2image->scanLine(y2+j);
		for (int i=0; i<w; i++) {
		    if (*(yl + ((x2+i) >> 3)) & (1 << (7-((x2+i) & 7)))
		    && *(ml + ((x1+i) >> 3)) & (1 << (7-((x1+i) & 7))))
		    {
			return true;
		    }
		}
	    }
	}
    } else {
	if (s2image->bitOrder() == QImage::LittleEndian) {
	    for (int j=0; j<h; j++) {
		const uchar* yl = s2image->scanLine(y2+j);
		for (int i=0; i<w; i++) {
		    if (*(yl + ((x2+i) >> 3)) & (1 << ((x2+i) & 7)))
		    {
			return true;
		    }
		}
	    }
	} else {
	    for (int j=0; j<h; j++) {
		const uchar* yl = s2image->scanLine(y2+j);
		for (int i=0; i<w; i++) {
		    if (*(yl + ((x2+i) >> 3)) & (1 << (7-((x2+i) & 7))))
		    {
			return true;
		    }
		}
	    }
	}
    }

    return false;
}

static bool collision_double_dispatch(const Q3CanvasSprite* s1,
				       const Q3CanvasPolygonalItem* p1,
				       const Q3CanvasRectangle* r1,
				       const Q3CanvasEllipse* e1,
				       const Q3CanvasText* t1,
				       const Q3CanvasSprite* s2,
				       const Q3CanvasPolygonalItem* p2,
				       const Q3CanvasRectangle* r2,
				       const Q3CanvasEllipse* e2,
				       const Q3CanvasText* t2)
{
    const Q3CanvasItem* i1 = s1 ?
			    (const Q3CanvasItem*)s1 : p1 ?
			    (const Q3CanvasItem*)p1 : r1 ?
			    (const Q3CanvasItem*)r1 : e1 ?
			    (const Q3CanvasItem*)e1 : (const Q3CanvasItem*)t1;
    const Q3CanvasItem* i2 = s2 ?
			    (const Q3CanvasItem*)s2 : p2 ?
			    (const Q3CanvasItem*)p2 : r2 ?
			    (const Q3CanvasItem*)r2 : e2 ?
			    (const Q3CanvasItem*)e2 : (const Q3CanvasItem*)t2;

    if (s1 && s2) {
	// a
	return qt_testCollision(s1,s2);
    } else if ((r1 || t1 || s1) && (r2 || t2 || s2)) {
	// b
	QRect rc1 = i1->boundingRectAdvanced();
	QRect rc2 = i2->boundingRectAdvanced();
	return rc1.intersects(rc2);
    } else if (e1 && e2
		&& e1->angleLength()>=360*16 && e2->angleLength()>=360*16
		&& e1->width()==e1->height()
		&& e2->width()==e2->height()) {
	// c
	double xd = (e1->x()+e1->xVelocity())-(e2->x()+e1->xVelocity());
	double yd = (e1->y()+e1->yVelocity())-(e2->y()+e1->yVelocity());
	double rd = (e1->width()+e2->width())/2;
	return xd*xd+yd*yd <= rd*rd;
    } else if (p1 && (p2 || s2 || t2)) {
	// d
	Q3PointArray pa1 = p1->areaPointsAdvanced();
	Q3PointArray pa2 = p2 ? p2->areaPointsAdvanced()
			  : Q3PointArray(i2->boundingRectAdvanced());
	bool col= !(QRegion(pa1) & QRegion(pa2,true)).isEmpty();

	return col;
    } else {
	return collision_double_dispatch(s2,p2,r2,e2,t2,
					 s1,p1,r1,e1,t1);
    }
}

/*!
    \fn bool Q3CanvasItem::collidesWith(const Q3CanvasItem* other) const

    Returns true if the canvas item will collide with the \a other
    item \e after they have moved by their current velocities;
    otherwise returns false.

    \sa collisions()
*/


/*!
    \class Q3CanvasSprite
    \compat
    \brief The Q3CanvasSprite class provides an animated canvas item on a Q3Canvas.

    A canvas sprite is an object which can contain any number of images
    (referred to as frames), only one of which is current, i.e.
    displayed, at any one time. The images can be passed in the
    constructor or set or changed later with setSequence(). If you
    subclass Q3CanvasSprite you can change the frame that is displayed
    periodically, e.g. whenever Q3CanvasItem::advance(1) is called to
    create the effect of animation.

    The current frame can be set with setFrame() or with move(). The
    number of frames available is given by frameCount(). The bounding
    rectangle of the current frame is returned by boundingRect().

    The current frame's image can be retrieved with image(); use
    imageAdvanced() to retrieve the image for the frame that will be
    shown after advance(1) is called. Use the image() overload passing
    it an integer index to retrieve a particular image from the list of
    frames.

    Use width() and height() to retrieve the dimensions of the current
    frame.

    Use leftEdge() and rightEdge() to retrieve the current frame's
    left-hand and right-hand x-coordinates respectively. Use
    bottomEdge() and topEdge() to retrieve the current frame's bottom
    and top y-coordinates respectively. These functions have an overload
    which will accept an integer frame number to retrieve the
    coordinates of a particular frame.

    Q3CanvasSprite draws very quickly, at the expense of memory.

    The current frame's image can be drawn on a painter with draw().

    Like any other canvas item, canvas sprites can be moved with
    move() which sets the x and y coordinates and the frame number, as
    well as with Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by
    setting coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY()
    and Q3CanvasItem::setZ().

    \sa QtCanvas, {Porting to Graphics View}
*/


/*!
  \reimp
*/
bool Q3CanvasSprite::collidesWith(const Q3CanvasItem* i) const
{
    return i->collidesWith(this,0,0,0,0);
}

/*!
    Returns true if the canvas item collides with any of the given
    items; otherwise returns false. The parameters, \a s, \a p, \a r,
    \a e and \a t, are all the same object, this is just a type
    resolution trick.
*/
bool Q3CanvasSprite::collidesWith(const Q3CanvasSprite* s,
				  const Q3CanvasPolygonalItem* p,
				  const Q3CanvasRectangle* r,
				  const Q3CanvasEllipse* e,
				  const Q3CanvasText* t) const
{
    return collision_double_dispatch(s,p,r,e,t,this,0,0,0,0);
}

/*!
  \reimp
*/
bool Q3CanvasPolygonalItem::collidesWith(const Q3CanvasItem* i) const
{
    return i->collidesWith(0,this,0,0,0);
}

bool Q3CanvasPolygonalItem::collidesWith( const Q3CanvasSprite* s,
				 const Q3CanvasPolygonalItem* p,
				 const Q3CanvasRectangle* r,
				 const Q3CanvasEllipse* e,
				 const Q3CanvasText* t) const
{
    return collision_double_dispatch(s,p,r,e,t,0,this,0,0,0);
}

/*!
  \reimp
*/
bool Q3CanvasRectangle::collidesWith(const Q3CanvasItem* i) const
{
    return i->collidesWith(0,this,this,0,0);
}

bool Q3CanvasRectangle::collidesWith( const Q3CanvasSprite* s,
				 const Q3CanvasPolygonalItem* p,
				 const Q3CanvasRectangle* r,
				 const Q3CanvasEllipse* e,
				 const Q3CanvasText* t) const
{
    return collision_double_dispatch(s,p,r,e,t,0,this,this,0,0);
}


/*!
  \reimp
*/
bool Q3CanvasEllipse::collidesWith(const Q3CanvasItem* i) const
{
    return i->collidesWith(0,this,0,this,0);
}

bool Q3CanvasEllipse::collidesWith( const Q3CanvasSprite* s,
				 const Q3CanvasPolygonalItem* p,
				 const Q3CanvasRectangle* r,
				 const Q3CanvasEllipse* e,
				 const Q3CanvasText* t) const
{
    return collision_double_dispatch(s,p,r,e,t,0,this,0,this,0);
}

/*!
  \reimp
*/
bool Q3CanvasText::collidesWith(const Q3CanvasItem* i) const
{
    return i->collidesWith(0,0,0,0,this);
}

bool Q3CanvasText::collidesWith( const Q3CanvasSprite* s,
				 const Q3CanvasPolygonalItem* p,
				 const Q3CanvasRectangle* r,
				 const Q3CanvasEllipse* e,
				 const Q3CanvasText* t) const
{
    return collision_double_dispatch(s,p,r,e,t,0,0,0,0,this);
}

/*!
    Returns the list of canvas items that this canvas item has
    collided with.

    A collision is generally defined as occurring when the pixels of
    one item draw on the pixels of another item, but not all
    subclasses are so precise. Also, since pixel-wise collision
    detection can be slow, this function works in either exact or
    inexact mode, according to the \a exact parameter.

    If \a exact is true, the canvas items returned have been
    accurately tested for collision with the canvas item.

    If \a exact is false, the canvas items returned are \e near the
    canvas item. You can test the canvas items returned using
    collidesWith() if any are interesting collision candidates. By
    using this approach, you can ignore some canvas items for which
    collisions are not relevant.

    The returned list is a list of Q3CanvasItems, but often you will
    need to cast the items to their subclass types. The safe way to do
    this is to use rtti() before casting. This provides some of the
    functionality of the standard C++ dynamic cast operation even on
    compilers where dynamic casts are not available.

    Note that a canvas item may be `on' a canvas, e.g. it was created
    with the canvas as parameter, even though its coordinates place it
    beyond the edge of the canvas's area. Collision detection only
    works for canvas items which are wholly or partly within the
    canvas's area.

    Note that if items have a velocity (see \l setVelocity()), then
    collision testing is done based on where the item \e will be when
    it moves, not its current location. For example, a "ball" item
    doesn't need to actually embed into a "wall" item before a
    collision is detected. For items without velocity, plain
    intersection is used.
*/
Q3CanvasItemList Q3CanvasItem::collisions(bool exact) const
{
    return canvas()->collisions(chunks(),this,exact);
}

/*!
    Returns a list of canvas items that collide with the point \a p.
    The list is ordered by z coordinates, from highest z coordinate
    (front-most item) to lowest z coordinate (rear-most item).
*/
Q3CanvasItemList Q3Canvas::collisions(const QPoint& p) const
{
    return collisions(QRect(p,QSize(1,1)));
}

/*!
    \overload

    Returns a list of items which collide with the rectangle \a r. The
    list is ordered by z coordinates, from highest z coordinate
    (front-most item) to lowest z coordinate (rear-most item).
*/
Q3CanvasItemList Q3Canvas::collisions(const QRect& r) const
{
    Q3CanvasRectangle i(r,(Q3Canvas*)this);
    i.setPen(NoPen);
    i.show(); // doesn't actually show, since we destroy it
    Q3CanvasItemList l = i.collisions(true);
    l.sort();
    return l;
}

/*!
    \overload

    Returns a list of canvas items which intersect with the chunks
    listed in \a chunklist, excluding \a item. If \a exact is true,
    only those which actually \link Q3CanvasItem::collidesWith()
    collide with\endlink \a item are returned; otherwise canvas items
    are included just for being in the chunks.

    This is a utility function mainly used to implement the simpler
    Q3CanvasItem::collisions() function.
*/
Q3CanvasItemList Q3Canvas::collisions(const Q3PointArray& chunklist,
	    const Q3CanvasItem* item, bool exact) const
{
    Q3PtrDict<void> seen;
    Q3CanvasItemList result;
    for (int i=0; i<(int)chunklist.count(); i++) {
	int x = chunklist[i].x();
	int y = chunklist[i].y();
	if (validChunk(x,y)) {
	    const Q3CanvasItemList* l = chunk(x,y).listPtr();
	    for (Q3CanvasItemList::ConstIterator it=l->begin(); it!=l->end(); ++it) {
		Q3CanvasItem *g=*it;
		if (g != item) {
		    if (!seen.find(g)) {
			seen.replace(g,(void*)1);
			if (!exact || item->collidesWith(g))
			    result.append(g);
		    }
		}
	    }
	}
    }
    return result;
}

/*!
  \internal
  Adds the item to all the chunks it covers.
*/
void Q3CanvasItem::addToChunks()
{
    if (isVisible() && canvas()) {
	Q3PointArray pa = chunks();
	for (int i=0; i<(int)pa.count(); i++)
	    canvas()->addItemToChunk(this,pa[i].x(),pa[i].y());
	val=(uint)true;
    }
}

/*!
  \internal
  Removes the item from all the chunks it covers.
*/
void Q3CanvasItem::removeFromChunks()
{
    if (isVisible() && canvas()) {
	Q3PointArray pa = chunks();
	for (int i=0; i<(int)pa.count(); i++)
	    canvas()->removeItemFromChunk(this,pa[i].x(),pa[i].y());
    }
}

/*!
  \internal
  Sets all the chunks covered by the item to be refreshed with Q3Canvas::update()
  is next called.
*/
void Q3CanvasItem::changeChunks()
{
    if (isVisible() && canvas()) {
	if (!val)
	    addToChunks();
	Q3PointArray pa = chunks();
	for (int i=0; i<(int)pa.count(); i++)
	    canvas()->setChangedChunk(pa[i].x(),pa[i].y());
    }
}

/*!
    \fn QRect Q3CanvasItem::boundingRect() const

    Returns the bounding rectangle in pixels that the canvas item covers.

    \sa boundingRectAdvanced()
*/

/*!
    Returns the bounding rectangle of pixels that the canvas item \e
    will cover after advance(1) is called.

    \sa boundingRect()
*/
QRect Q3CanvasItem::boundingRectAdvanced() const
{
    int dx = int(x()+xVelocity())-int(x());
    int dy = int(y()+yVelocity())-int(y());
    QRect r = boundingRect();
    r.moveBy(dx,dy);
    return r;
}

/*!
    \class Q3CanvasPixmap
    \compat
    \brief The Q3CanvasPixmap class provides pixmaps for Q3CanvasSprites.

    If you want to show a single pixmap on a Q3Canvas use a
    Q3CanvasSprite with just one pixmap.

    When pixmaps are inserted into a Q3CanvasPixmapArray they are held
    as Q3CanvasPixmaps. \l{Q3CanvasSprite}s are used to show pixmaps on
    \l{Q3Canvas}es and hold their pixmaps in a Q3CanvasPixmapArray. If
    you retrieve a frame (pixmap) from a Q3CanvasSprite it will be
    returned as a Q3CanvasPixmap.

    The pixmap is a QPixmap and can only be set in the constructor.
    There are three different constructors, one taking a QPixmap, one
    a QImage and one a file name that refers to a file in any
    supported file format (see QImageReader).

    Q3CanvasPixmap can have a hotspot which is defined in terms of an (x,
    y) offset. When you create a Q3CanvasPixmap from a PNG file or from
    a QImage that has a QImage::offset(), the offset() is initialized
    appropriately, otherwise the constructor leaves it at (0, 0). You
    can set it later using setOffset(). When the Q3CanvasPixmap is used
    in a Q3CanvasSprite, the offset position is the point at
    Q3CanvasItem::x() and Q3CanvasItem::y(), not the top-left corner of
    the pixmap.

    Note that for Q3CanvasPixmap objects created by a Q3CanvasSprite, the
    position of each Q3CanvasPixmap object is set so that the hotspot
    stays in the same position.

    \sa Q3CanvasPixmapArray Q3CanvasItem Q3CanvasSprite, QtCanvas, {Porting to Graphics View}
*/

#ifndef QT_NO_IMAGEIO

/*!
    Constructs a Q3CanvasPixmap that uses the image stored in \a
    datafilename.
*/
Q3CanvasPixmap::Q3CanvasPixmap(const QString& datafilename)
{
    QImage image(datafilename);
    init(image);
}

#endif

/*!
    Constructs a Q3CanvasPixmap from the image \a image.
*/
Q3CanvasPixmap::Q3CanvasPixmap(const QImage& image)
{
    init(image);
}
/*!
    Constructs a Q3CanvasPixmap from the pixmap \a pm using the offset
    \a offset.
*/
Q3CanvasPixmap::Q3CanvasPixmap(const QPixmap& pm, const QPoint& offset)
{
    init(pm,offset.x(),offset.y());
}

void Q3CanvasPixmap::init(const QImage& image)
{
    convertFromImage(image);
    hotx = image.offset().x();
    hoty = image.offset().y();
#ifndef QT_NO_IMAGE_DITHER_TO_1
    if(image.hasAlphaBuffer()) {
	QImage i = image.createAlphaMask();
	collision_mask = new QImage(i);
    } else
#endif
	collision_mask = 0;
}

void Q3CanvasPixmap::init(const QPixmap& pixmap, int hx, int hy)
{
    (QPixmap&)*this = pixmap;
    hotx = hx;
    hoty = hy;
    if(pixmap.hasAlphaChannel())  {
	QImage i = mask().convertToImage();
	collision_mask = new QImage(i);
    } else
	collision_mask = 0;
}

/*!
    Destroys the pixmap.
*/
Q3CanvasPixmap::~Q3CanvasPixmap()
{
    delete collision_mask;
}

/*!
    \fn int Q3CanvasPixmap::offsetX() const

    Returns the x-offset of the pixmap's hotspot.

    \sa setOffset()
*/

/*!
    \fn int Q3CanvasPixmap::offsetY() const

    Returns the y-offset of the pixmap's hotspot.

    \sa setOffset()
*/

/*!
    \fn void Q3CanvasPixmap::setOffset(int x, int y)

    Sets the offset of the pixmap's hotspot to (\a x, \a y).

    \warning Do not call this function if any Q3CanvasSprites are
    currently showing this pixmap.
*/

/*!
    \class Q3CanvasPixmapArray
    \compat
    \brief The Q3CanvasPixmapArray class provides an array of Q3CanvasPixmaps.

    This class is used by Q3CanvasSprite to hold an array of pixmaps.
    It is used to implement animated sprites, i.e. images that change
    over time, with each pixmap in the array holding one frame.

    Depending on the constructor you use you can load multiple pixmaps
    into the array either from a directory (specifying a wildcard
    pattern for the files), or from a list of QPixmaps. You can also
    read in a set of pixmaps after construction using readPixmaps().

    Individual pixmaps can be set with setImage() and retrieved with
    image(). The number of pixmaps in the array is returned by
    count().

    Q3CanvasSprite uses an image's mask for collision detection. You
    can change this by reading in a separate set of image masks using
    readCollisionMasks().

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs an invalid array (i.e. isValid() will return false).
    You must call readPixmaps() before being able to use this
    Q3CanvasPixmapArray.
*/
Q3CanvasPixmapArray::Q3CanvasPixmapArray()
: framecount(0), img(0)
{
}

#ifndef QT_NO_IMAGEIO
/*!
    Constructs a Q3CanvasPixmapArray from files.

    The \a fc parameter sets the number of frames to be loaded for
    this image.

    If \a fc is not 0, \a datafilenamepattern should contain "%1",
    e.g. "foo%1.png". The actual filenames are formed by replacing the
    %1 with four-digit integers from 0 to (fc - 1), e.g. foo0000.png,
    foo0001.png, foo0002.png, etc.

    If \a fc is 0, \a datafilenamepattern is asssumed to be a
    filename, and the image contained in this file will be loaded as
    the first (and only) frame.

    If \a datafilenamepattern does not exist, is not readable, isn't
    an image, or some other error occurs, the array ends up empty and
    isValid() returns false.
*/

Q3CanvasPixmapArray::Q3CanvasPixmapArray(const QString& datafilenamepattern,
					int fc)
: framecount(0), img(0)
{
    readPixmaps(datafilenamepattern,fc);
}
#endif

/*!
  \obsolete
  Use Q3CanvasPixmapArray::Q3CanvasPixmapArray(Q3ValueList<QPixmap>, Q3PointArray)
  instead.

  Constructs a Q3CanvasPixmapArray from the list of QPixmaps \a
  list. The \a hotspots list has to be of the same size as \a list.
*/
Q3CanvasPixmapArray::Q3CanvasPixmapArray(Q3PtrList<QPixmap> list, Q3PtrList<QPoint> hotspots) :
    framecount(list.count()),
    img(new Q3CanvasPixmap*[list.count()])
{
    if (list.count() != hotspots.count()) {
	qWarning("Q3CanvasPixmapArray: lists have different lengths");
	reset();
	img = 0;
    } else {
	list.first();
	hotspots.first();
	for (int i=0; i<framecount; i++) {
	    img[i]=new Q3CanvasPixmap(*list.current(), *hotspots.current());
	    list.next();
	    hotspots.next();
	}
    }
}

/*!
    Constructs a Q3CanvasPixmapArray from the list of QPixmaps in the
    \a list. Each pixmap will get a hotspot according to the \a
    hotspots array. If no hotspots are specified, each one is set to
    be at position (0, 0).

    If an error occurs, isValid() will return false.
*/
Q3CanvasPixmapArray::Q3CanvasPixmapArray(Q3ValueList<QPixmap> list, Q3PointArray hotspots) :
    framecount((int)list.size()),
    img(new Q3CanvasPixmap*[list.size()])
{
    bool have_hotspots = (hotspots.size() != 0);
    if (have_hotspots && list.count() != hotspots.count()) {
	qWarning("Q3CanvasPixmapArray: lists have different lengths");
	reset();
	img = 0;
    } else {
	Q3ValueList<QPixmap>::iterator it;
	it = list.begin();
	for (int i=0; i<framecount; i++) {
	    QPoint hs = have_hotspots ? hotspots[i] : QPoint(0, 0);
	    img[i]=new Q3CanvasPixmap(*it, hs);
	    ++it;
	}
    }
}

/*!
    Destroys the pixmap array and all the pixmaps it contains.
*/
Q3CanvasPixmapArray::~Q3CanvasPixmapArray()
{
    reset();
}

void Q3CanvasPixmapArray::reset()
{
    for (int i=0; i<framecount; i++)
	delete img[i];
    delete [] img;
    img = 0;
    framecount = 0;
}

#ifndef QT_NO_IMAGEIO
/*!
    Reads one or more pixmaps into the pixmap array.

    If \a fc is not 0, \a filenamepattern should contain "%1", e.g.
    "foo%1.png". The actual filenames are formed by replacing the %1
    with four-digit integers from 0 to (fc - 1), e.g. foo0000.png,
    foo0001.png, foo0002.png, etc.

    If \a fc is 0, \a filenamepattern is asssumed to be a filename,
    and the image contained in this file will be loaded as the first
    (and only) frame.

    If \a filenamepattern does not exist, is not readable, isn't an
    image, or some other error occurs, this function will return
    false, and isValid() will return false; otherwise this function
    will return true.

    \sa isValid()
*/
bool Q3CanvasPixmapArray::readPixmaps(const QString& filenamepattern,
				      int fc)
{
    return readPixmaps(filenamepattern,fc,false);
}

/*!
    Reads new collision masks for the array.

    By default, Q3CanvasSprite uses the image mask of a sprite to
    detect collisions. Use this function to set your own collision
    image masks.

    If count() is 1 \a filename must specify a real filename to read
    the mask from. If count() is greater than 1, the \a filename must
    contain a "%1" that will get replaced by the number of the mask to
    be loaded, just like Q3CanvasPixmapArray::readPixmaps().

    All collision masks must be 1-bit images or this function call
    will fail.

    If the file isn't readable, contains the wrong number of images,
    or there is some other error, this function will return false, and
    the array will be flagged as invalid; otherwise this function
    returns true.

    \sa isValid()
*/
bool Q3CanvasPixmapArray::readCollisionMasks(const QString& filename)
{
    return readPixmaps(filename,framecount,true);
}


bool Q3CanvasPixmapArray::readPixmaps(const QString& datafilenamepattern,
				      int fc, bool maskonly)
{
    if (!maskonly) {
	reset();
	framecount = fc;
	if (!framecount)
	    framecount=1;
	img = new Q3CanvasPixmap*[framecount];
    }
    if (!img)
        return false;

    bool ok = true;
    bool arg = fc > 1;
    if (!arg)
	framecount=1;
    for (int i=0; i<framecount; i++) {
	QString r;
	r.sprintf("%04d",i);
	if (maskonly) {
            if (!img[i]->collision_mask)
                img[i]->collision_mask = new QImage();
	    img[i]->collision_mask->load(
		arg ? datafilenamepattern.arg(r) : datafilenamepattern);
	    ok = ok
	       && !img[i]->collision_mask->isNull()
	       && img[i]->collision_mask->depth()==1;
	} else {
	    img[i]=new Q3CanvasPixmap(
		arg ? datafilenamepattern.arg(r) : datafilenamepattern);
	    ok = ok && !img[i]->isNull();
	}
    }
    if (!ok) {
	reset();
    }
    return ok;
}
#endif

/*!
  \obsolete

  Use isValid() instead.

  This returns false if the array is valid, and true if it is not.
*/
bool Q3CanvasPixmapArray::operator!()
{
    return img==0;
}

/*!
    Returns true if the pixmap array is valid; otherwise returns
    false.
*/
bool Q3CanvasPixmapArray::isValid() const
{
    return (img != 0);
}

/*!
    \fn Q3CanvasPixmap* Q3CanvasPixmapArray::image(int i) const

    Returns pixmap \a i in the array, if \a i is non-negative and less
    than than count(), and returns an unspecified value otherwise.
*/

// ### wouldn't it be better to put empty Q3CanvasPixmaps in there instead of
// initializing the additional elements in the array to 0? Lars
/*!
    Replaces the pixmap at index \a i with pixmap \a p.

    The array takes ownership of \a p and will delete \a p when the
    array itself is deleted.

    If \a i is beyond the end of the array the array is extended to at
    least i+1 elements, with elements count() to i-1 being initialized
    to 0.
*/
void Q3CanvasPixmapArray::setImage(int i, Q3CanvasPixmap* p)
{
    if (i >= framecount) {
	Q3CanvasPixmap** newimg = new Q3CanvasPixmap*[i+1];
	memcpy(newimg, img, sizeof(Q3CanvasPixmap *)*framecount);
	memset(newimg + framecount, 0, sizeof(Q3CanvasPixmap *)*(i+1 - framecount));
	framecount = i+1;
	delete [] img;
	img = newimg;
    }
    delete img[i]; img[i]=p;
}

/*!
    \fn uint Q3CanvasPixmapArray::count() const

    Returns the number of pixmaps in the array.
*/

/*!
    Returns the x-coordinate of the current left edge of the sprite.
    (This may change as the sprite animates since different frames may
    have different left edges.)

    \sa rightEdge() bottomEdge() topEdge()
*/
int Q3CanvasSprite::leftEdge() const
{
    return int(x()) - image()->hotx;
}

/*!
    \overload

    Returns what the x-coordinate of the left edge of the sprite would
    be if the sprite (actually its hotspot) were moved to x-position
    \a nx.

    \sa rightEdge() bottomEdge() topEdge()
*/
int Q3CanvasSprite::leftEdge(int nx) const
{
    return nx - image()->hotx;
}

/*!
    Returns the y-coordinate of the top edge of the sprite. (This may
    change as the sprite animates since different frames may have
    different top edges.)

    \sa leftEdge() rightEdge() bottomEdge()
*/
int Q3CanvasSprite::topEdge() const
{
    return int(y()) - image()->hoty;
}

/*!
    \overload

    Returns what the y-coordinate of the top edge of the sprite would
    be if the sprite (actually its hotspot) were moved to y-position
    \a ny.

    \sa leftEdge() rightEdge() bottomEdge()
*/
int Q3CanvasSprite::topEdge(int ny) const
{
    return ny - image()->hoty;
}

/*!
    Returns the x-coordinate of the current right edge of the sprite.
    (This may change as the sprite animates since different frames may
    have different right edges.)

    \sa leftEdge() bottomEdge() topEdge()
*/
int Q3CanvasSprite::rightEdge() const
{
    return leftEdge() + image()->width()-1;
}

/*!
    \overload

    Returns what the x-coordinate of the right edge of the sprite
    would be if the sprite (actually its hotspot) were moved to
    x-position \a nx.

    \sa leftEdge() bottomEdge() topEdge()
*/
int Q3CanvasSprite::rightEdge(int nx) const
{
    return leftEdge(nx) + image()->width()-1;
}

/*!
    Returns the y-coordinate of the current bottom edge of the sprite.
    (This may change as the sprite animates since different frames may
    have different bottom edges.)

    \sa leftEdge() rightEdge() topEdge()
*/
int Q3CanvasSprite::bottomEdge() const
{
    return topEdge() + image()->height()-1;
}

/*!
    \overload

    Returns what the y-coordinate of the top edge of the sprite would
    be if the sprite (actually its hotspot) were moved to y-position
    \a ny.

    \sa leftEdge() rightEdge() topEdge()
*/
int Q3CanvasSprite::bottomEdge(int ny) const
{
    return topEdge(ny) + image()->height()-1;
}

/*!
    \fn Q3CanvasPixmap* Q3CanvasSprite::image() const

    Returns the current frame's image.

    \sa frame(), setFrame()
*/

/*!
    \fn Q3CanvasPixmap* Q3CanvasSprite::image(int f) const
    \overload

    Returns the image for frame \a f. Does not do any bounds checking on \a f.
*/

/*!
    Returns the image the sprite \e will have after advance(1) is
    called. By default this is the same as image().
*/
Q3CanvasPixmap* Q3CanvasSprite::imageAdvanced() const
{
    return image();
}

/*!
    Returns the bounding rectangle for the image in the sprite's
    current frame. This assumes that the images are tightly cropped
    (i.e. do not have transparent pixels all along a side).
*/
QRect Q3CanvasSprite::boundingRect() const
{
    return QRect(leftEdge(), topEdge(), width(), height());
}


/*!
  \internal
  Returns the chunks covered by the item.
*/
Q3PointArray Q3CanvasItem::chunks() const
{
    Q3PointArray r;
    int n=0;
    QRect br = boundingRect();
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	br &= QRect(0,0,canvas()->width(),canvas()->height());
	if (br.isValid()) {
	    r.resize((br.width()/chunksize+2)*(br.height()/chunksize+2));
	    for (int j=br.top()/chunksize; j<=br.bottom()/chunksize; j++) {
		for (int i=br.left()/chunksize; i<=br.right()/chunksize; i++) {
		    r[n++] = QPoint(i,j);
		}
	    }
	}
    }
    r.resize(n);
    return r;
}


/*!
  \internal
  Add the sprite to the chunks in its Q3Canvas which it overlaps.
*/
void Q3CanvasSprite::addToChunks()
{
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	for (int j=topEdge()/chunksize; j<=bottomEdge()/chunksize; j++) {
	    for (int i=leftEdge()/chunksize; i<=rightEdge()/chunksize; i++) {
		canvas()->addItemToChunk(this,i,j);
	    }
	}
    }
}

/*!
  \internal
  Remove the sprite from the chunks in its Q3Canvas which it overlaps.

  \sa addToChunks()
*/
void Q3CanvasSprite::removeFromChunks()
{
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	for (int j=topEdge()/chunksize; j<=bottomEdge()/chunksize; j++) {
	    for (int i=leftEdge()/chunksize; i<=rightEdge()/chunksize; i++) {
		canvas()->removeItemFromChunk(this,i,j);
	    }
	}
    }
}

/*!
    The width of the sprite for the current frame's image.

    \sa frame()
*/
//### mark: Why don't we have width(int) and height(int) to be
//consistent with leftEdge() and leftEdge(int)?
int Q3CanvasSprite::width() const
{
    return image()->width();
}

/*!
    The height of the sprite for the current frame's image.

    \sa frame()
*/
int Q3CanvasSprite::height() const
{
    return image()->height();
}


/*!
    Draws the current frame's image at the sprite's current position
    on painter \a painter.
*/
void Q3CanvasSprite::draw(QPainter& painter)
{
    painter.drawPixmap(leftEdge(),topEdge(),*image());
}

/*!
    \class Q3CanvasView
    \compat
    \brief The Q3CanvasView class provides an on-screen view of a Q3Canvas.

    A Q3CanvasView is widget which provides a view of a Q3Canvas.

    If you want users to be able to interact with a canvas view,
    subclass Q3CanvasView. You might then reimplement
    Q3ScrollView::contentsMousePressEvent(). For example:

    \snippet doc/src/snippets/code/src_qt3support_canvas_q3canvas.cpp 1

    The canvas view shows canvas canvas(); this can be changed using
    setCanvas().

    A transformation matrix can be used to transform the view of the
    canvas in various ways, for example, zooming in or out or rotating.
    For example:

    \snippet doc/src/snippets/code/src_qt3support_canvas_q3canvas.cpp 2

    Use setWorldMatrix() to set the canvas view's world matrix: you must
    ensure that the world matrix is invertible. The current world matrix
    is retrievable with worldMatrix(), and its inversion is retrievable
    with inverseWorldMatrix().

    Example:

    The following code finds the part of the canvas that is visible in
    this view, i.e. the bounding rectangle of the view in canvas coordinates.

    \snippet doc/src/snippets/code/src_qt3support_canvas_q3canvas.cpp 3

    \sa QMatrix QPainter::setWorldMatrix(), QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs a Q3CanvasView with parent \a parent, and name \a name,
    using the widget flags \a f. The canvas view is not associated
    with a canvas, so you must to call setCanvas() to view a
    canvas.
*/
Q3CanvasView::Q3CanvasView(QWidget* parent, const char* name, Qt::WindowFlags f)
    : Q3ScrollView(parent,name,f|WResizeNoErase|WStaticContents)
{
    d = new Q3CanvasViewData;
    viewing = 0;
    setCanvas(0);
}

/*!
    \overload

    Constructs a Q3CanvasView which views canvas \a canvas, with parent
    \a parent, and name \a name, using the widget flags \a f.
*/
Q3CanvasView::Q3CanvasView(Q3Canvas* canvas, QWidget* parent, const char* name, Qt::WindowFlags f)
    : Q3ScrollView(parent,name,f|WResizeNoErase|WStaticContents)
{
    d = new Q3CanvasViewData;
    viewing = 0;
    setCanvas(canvas);
}

/*!
    Destroys the canvas view. The associated canvas is \e not deleted.
*/
Q3CanvasView::~Q3CanvasView()
{
    delete d;
    d = 0;
    setCanvas(0);
}

/*!
    \fn Q3Canvas* Q3CanvasView::canvas() const

    Returns a pointer to the canvas which the Q3CanvasView is currently
    showing.
*/


/*!
    Sets the canvas that the Q3CanvasView is showing to the canvas \a
    canvas.
*/
void Q3CanvasView::setCanvas(Q3Canvas* canvas)
{
    if (viewing == canvas)
        return;

    if (viewing) {
	disconnect(viewing);
	viewing->removeView(this);
    }
    viewing=canvas;
    if (viewing) {
	connect(viewing,SIGNAL(resized()), this, SLOT(updateContentsSize()));
	viewing->addView(this);
	viewing->setAllChanged();
    }
    if (d) // called by d'tor
        updateContentsSize();
    update();
}

#ifndef QT_NO_TRANSFORMATIONS
/*!
    Returns a reference to the canvas view's current transformation matrix.

    \sa setWorldMatrix() inverseWorldMatrix()
*/
const QMatrix &Q3CanvasView::worldMatrix() const
{
    return d->xform;
}

/*!
    Returns a reference to the inverse of the canvas view's current
    transformation matrix.

    \sa setWorldMatrix() worldMatrix()
*/
const QMatrix &Q3CanvasView::inverseWorldMatrix() const
{
    return d->ixform;
}

/*!
    Sets the transformation matrix of the Q3CanvasView to \a wm. The
    matrix must be invertible (i.e. if you create a world matrix that
    zooms out by 2 times, then the inverse of this matrix is one that
    will zoom in by 2 times).

    When you use this, you should note that the performance of the
    Q3CanvasView will decrease considerably.

    Returns false if \a wm is not invertable; otherwise returns true.

    \sa worldMatrix() inverseWorldMatrix() QMatrix::isInvertible()
*/
bool Q3CanvasView::setWorldMatrix(const QMatrix & wm)
{
    bool ok = wm.isInvertible();
    if (ok) {
	d->xform = wm;
	d->ixform = wm.invert();
	updateContentsSize();
	viewport()->update();
    }
    return ok;
}
#endif

void Q3CanvasView::updateContentsSize()
{
    if (viewing) {
	QRect br;
#ifndef QT_NO_TRANSFORMATIONS
	br = d->xform.map(QRect(0,0,viewing->width(),viewing->height()));
#else
	br = QRect(0,0,viewing->width(),viewing->height());
#endif

	if (br.width() < contentsWidth()) {
	    QRect r(contentsToViewport(QPoint(br.width(),0)),
		    QSize(contentsWidth()-br.width(),contentsHeight()));
            d->eraseRegion = r;
	}
	if (br.height() < contentsHeight()) {
	    QRect r(contentsToViewport(QPoint(0,br.height())),
		    QSize(contentsWidth(),contentsHeight()-br.height()));
            d->eraseRegion |= r;
	}

	resizeContents(br.width(),br.height());
    } else {
        d->eraseRegion = rect();
	resizeContents(1,1);
    }
}

/*!
    Repaints part of the Q3Canvas that the canvas view is showing
    starting at \a cx by \a cy, with a width of \a cw and a height of \a
    ch using the painter \a p.
*/
void Q3CanvasView::drawContents(QPainter *p, int cx, int cy, int cw, int ch)
{
    QRect r(cx,cy,cw,ch);
    if (!d->eraseRegion.isEmpty()) {
        const QVector<QRect> rects = d->eraseRegion.rects();
        for (int i = 0; i < rects.size(); ++i)
            p->eraseRect(rects.at(i));

        d->eraseRegion = QRegion();
    }

    if (viewing) {
        viewing->drawViewArea(this,p,r,false);
    } else {
	p->eraseRect(r);
    }
}

/*!
  \reimp
  \internal

  (Implemented to get rid of a compiler warning.)
*/
void Q3CanvasView::drawContents(QPainter *)
{
}

/*!
    Suggests a size sufficient to view the entire canvas.
*/
QSize Q3CanvasView::sizeHint() const
{
    if (!canvas())
	return Q3ScrollView::sizeHint();
    // should maybe take transformations into account
    return (canvas()->size() + 2 * QSize(frameWidth(), frameWidth()))
	   .boundedTo(3 * QApplication::desktop()->size() / 4);
}

/*!
    \class Q3CanvasPolygonalItem
    \compat
    \brief The Q3CanvasPolygonalItem class provides a polygonal canvas item
    on a Q3Canvas.

    The mostly rectangular classes, such as Q3CanvasSprite and
    Q3CanvasText, use the object's bounding rectangle for movement,
    repainting and collision calculations. For most other items, the
    bounding rectangle can be far too large -- a diagonal line being
    the worst case, and there are many other cases which are also bad.
    Q3CanvasPolygonalItem provides polygon-based bounding rectangle
    handling, etc., which is much faster for non-rectangular items.

    Derived classes should try to define as small an area as possible
    to maximize efficiency, but the polygon must \e definitely be
    contained completely within the polygonal area. Calculating the
    exact requirements is usually difficult, but if you allow a small
    overestimate it can be easy and quick, while still getting almost
    all of Q3CanvasPolygonalItem's speed.

    Note that all subclasses \e must call hide() in their destructor
    since hide() needs to be able to access areaPoints().

    Normally, Q3CanvasPolygonalItem uses the odd-even algorithm for
    determining whether an object intersects this object. You can
    change this to the winding algorithm using setWinding().

    The bounding rectangle is available using boundingRect(). The
    points bounding the polygonal item are retrieved with
    areaPoints(). Use areaPointsAdvanced() to retrieve the bounding
    points the polygonal item \e will have after
    Q3CanvasItem::advance(1) has been called.

    If the shape of the polygonal item is about to change while the
    item is visible, call invalidate() before updating with a
    different result from \l areaPoints().

    By default, Q3CanvasPolygonalItem objects have a black pen and no
    brush (the default QPen and QBrush constructors). You can change
    this with setPen() and setBrush(), but note that some
    Q3CanvasPolygonalItem subclasses only use the brush, ignoring the
    pen setting.

    The polygonal item can be drawn on a painter with draw().
    Subclasses must reimplement drawShape() to draw themselves.

    Like any other canvas item polygonal items can be moved with
    Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting coordinates
    with Q3CanvasItem::setX(), Q3CanvasItem::setY() and Q3CanvasItem::setZ().

    \sa QtCanvas, {Porting to Graphics View}
*/


/*
  Since most polygonal items don't have a pen, the default is
  NoPen and a black brush.
*/
static const QPen& defaultPolygonPen()
{
    static QPen* dp=0;
    if (!dp)
	dp = new QPen;
    return *dp;
}

static const QBrush& defaultPolygonBrush()
{
    static QBrush* db=0;
    if (!db)
	db = new QBrush;
    return *db;
}

/*!
    Constructs a Q3CanvasPolygonalItem on the canvas \a canvas.
*/
Q3CanvasPolygonalItem::Q3CanvasPolygonalItem(Q3Canvas* canvas) :
    Q3CanvasItem(canvas),
    br(defaultPolygonBrush()),
    pn(defaultPolygonPen())
{
    wind=0;
}

/*!
    Note that all subclasses \e must call hide() in their destructor
    since hide() needs to be able to access areaPoints().
*/
Q3CanvasPolygonalItem::~Q3CanvasPolygonalItem()
{
}

/*!
    Returns true if the polygonal item uses the winding algorithm to
    determine the "inside" of the polygon. Returns false if it uses
    the odd-even algorithm.

    The default is to use the odd-even algorithm.

    \sa setWinding()
*/
bool Q3CanvasPolygonalItem::winding() const
{
    return wind;
}

/*!
    If \a enable is true, the polygonal item will use the winding
    algorithm to determine the "inside" of the polygon; otherwise the
    odd-even algorithm will be used.

    The default is to use the odd-even algorithm.

    \sa winding()
*/
void Q3CanvasPolygonalItem::setWinding(bool enable)
{
    wind = enable;
}

/*!
    Invalidates all information about the area covered by the canvas
    item. The item will be updated automatically on the next call that
    changes the item's status, for example, move() or update(). Call
    this function if you are going to change the shape of the item (as
    returned by areaPoints()) while the item is visible.
*/
void Q3CanvasPolygonalItem::invalidate()
{
    val = (uint)false;
    removeFromChunks();
}

/*!
    \fn Q3CanvasPolygonalItem::isValid() const

    Returns true if the polygonal item's area information has not been
    invalidated; otherwise returns false.

    \sa invalidate()
*/

/*!
    Returns the points the polygonal item \e will have after
    Q3CanvasItem::advance(1) is called, i.e. what the points are when
    advanced by the current xVelocity() and yVelocity().
*/
Q3PointArray Q3CanvasPolygonalItem::areaPointsAdvanced() const
{
    int dx = int(x()+xVelocity())-int(x());
    int dy = int(y()+yVelocity())-int(y());
    Q3PointArray r = areaPoints();
    r.detach(); // Explicit sharing is stupid.
    if (dx || dy)
	r.translate(dx,dy);
    return r;
}

//#define QCANVAS_POLYGONS_DEBUG
#ifdef QCANVAS_POLYGONS_DEBUG
static QWidget* dbg_wid=0;
static QPainter* dbg_ptr=0;
#endif

class QPolygonalProcessor {
public:
    QPolygonalProcessor(Q3Canvas* c, const Q3PointArray& pa) :
	canvas(c)
    {
	QRect pixelbounds = pa.boundingRect();
	int cs = canvas->chunkSize();
    QRect canvasbounds = pixelbounds.intersected(canvas->rect());
    bounds.setLeft(canvasbounds.left()/cs);
    bounds.setRight(canvasbounds.right()/cs);
    bounds.setTop(canvasbounds.top()/cs);
    bounds.setBottom(canvasbounds.bottom()/cs);
    bitmap = QImage(bounds.width() + 1, bounds.height(), 1, 2, QImage::LittleEndian);
    pnt = 0;
	bitmap.fill(0);
#ifdef QCANVAS_POLYGONS_DEBUG
	dbg_start();
#endif
    }

    inline void add(int x, int y)
    {
	if (pnt >= (int)result.size()) {
	    result.resize(pnt*2+10);
	}
	result[pnt++] = QPoint(x+bounds.x(),y+bounds.y());
#ifdef QCANVAS_POLYGONS_DEBUG
	if (dbg_ptr) {
	    int cs = canvas->chunkSize();
	    QRect r(x*cs+bounds.x()*cs,y*cs+bounds.y()*cs,cs-1,cs-1);
	    dbg_ptr->setPen(Qt::blue);
	    dbg_ptr->drawRect(r);
	}
#endif
    }

    inline void addBits(int x1, int x2, uchar newbits, int xo, int yo)
    {
	for (int i=x1; i<=x2; i++)
	    if (newbits & (1<<i))
		add(xo+i,yo);
    }

#ifdef QCANVAS_POLYGONS_DEBUG
    void dbg_start()
    {
	if (!dbg_wid) {
	    dbg_wid = new QWidget;
	    dbg_wid->resize(800,600);
	    dbg_wid->show();
	    dbg_ptr = new QPainter(dbg_wid);
	    dbg_ptr->setBrush(Qt::NoBrush);
	}
	dbg_ptr->fillRect(dbg_wid->rect(),Qt::white);
    }
#endif

    void doSpans(int n, QPoint* pt, int* w)
    {
	int cs = canvas->chunkSize();
	for (int j=0; j<n; j++) {
	    int y = pt[j].y()/cs-bounds.y();
        if (y >= bitmap.height() || y < 0) continue;
	    uchar* l = bitmap.scanLine(y);
	    int x = pt[j].x();
	    int x1 = x/cs-bounds.x();
        if (x1 > bounds.width()) continue;
        x1  = QMAX(0,x1);
	    int x2 = (x+w[j])/cs-bounds.x();
        if (x2 < 0) continue;
        x2 = QMIN(bounds.width(), x2);
	    int x1q = x1/8;
	    int x1r = x1%8;
	    int x2q = x2/8;
	    int x2r = x2%8;
#ifdef QCANVAS_POLYGONS_DEBUG
	    if (dbg_ptr) dbg_ptr->setPen(Qt::yellow);
#endif
	    if (x1q == x2q) {
		uchar newbits = (~l[x1q]) & (((2<<(x2r-x1r))-1)<<x1r);
		if (newbits) {
#ifdef QCANVAS_POLYGONS_DEBUG
		    if (dbg_ptr) dbg_ptr->setPen(Qt::darkGreen);
#endif
		    addBits(x1r,x2r,newbits,x1q*8,y);
		    l[x1q] |= newbits;
		}
	    } else {
#ifdef QCANVAS_POLYGONS_DEBUG
		if (dbg_ptr) dbg_ptr->setPen(Qt::blue);
#endif
		uchar newbits1 = (~l[x1q]) & (0xff<<x1r);
		if (newbits1) {
#ifdef QCANVAS_POLYGONS_DEBUG
		    if (dbg_ptr) dbg_ptr->setPen(Qt::green);
#endif
		    addBits(x1r,7,newbits1,x1q*8,y);
		    l[x1q] |= newbits1;
		}
		for (int i=x1q+1; i<x2q; i++) {
		    if (l[i] != 0xff) {
			addBits(0,7,~l[i],i*8,y);
			l[i]=0xff;
		    }
		}
		uchar newbits2 = (~l[x2q]) & (0xff>>(7-x2r));
		if (newbits2) {
#ifdef QCANVAS_POLYGONS_DEBUG
		    if (dbg_ptr) dbg_ptr->setPen(Qt::red);
#endif
		    addBits(0,x2r,newbits2,x2q*8,y);
		    l[x2q] |= newbits2;
		}
	    }
#ifdef QCANVAS_POLYGONS_DEBUG
	    if (dbg_ptr) {
		dbg_ptr->drawLine(pt[j],pt[j]+QPoint(w[j],0));
	    }
#endif
	}
	result.resize(pnt);
    }

    int pnt;
    Q3PointArray result;
    Q3Canvas* canvas;
    QRect bounds;
    QImage bitmap;
};


Q3PointArray Q3CanvasPolygonalItem::chunks() const
{
    Q3PointArray pa = areaPoints();

    if (!pa.size()) {
	pa.detach(); // Explicit sharing is stupid.
	return pa;
    }

    QPolygonalProcessor processor(canvas(),pa);

    scanPolygon(pa, wind, processor);

    return processor.result;
}
/*!
    Simply calls Q3CanvasItem::chunks().
*/
Q3PointArray Q3CanvasRectangle::chunks() const
{
    // No need to do a polygon scan!
    return Q3CanvasItem::chunks();
}

/*!
    Returns the bounding rectangle of the polygonal item, based on
    areaPoints().
*/
QRect Q3CanvasPolygonalItem::boundingRect() const
{
    return areaPoints().boundingRect();
}

/*!
    Reimplemented from Q3CanvasItem, this draws the polygonal item by
    setting the pen and brush for the item on the painter \a p and
    calling drawShape().
*/
void Q3CanvasPolygonalItem::draw(QPainter & p)
{
    p.setPen(pn);
    p.setBrush(br);
    drawShape(p);
}

/*!
    \fn void Q3CanvasPolygonalItem::drawShape(QPainter & p)

    Subclasses must reimplement this function to draw their shape. The
    pen and brush of \a p are already set to pen() and brush() prior
    to calling this function.

    \sa draw()
*/

/*!
    \fn QPen Q3CanvasPolygonalItem::pen() const

    Returns the QPen used to draw the outline of the item, if any.

    \sa setPen()
*/

/*!
    \fn QBrush Q3CanvasPolygonalItem::brush() const

    Returns the QBrush used to fill the item, if filled.

    \sa setBrush()
*/

/*!
    Sets the QPen used when drawing the item to the pen \a p.
    Note that many Q3CanvasPolygonalItems do not use the pen value.

    \sa setBrush(), pen(), drawShape()
*/
void Q3CanvasPolygonalItem::setPen(QPen p)
{
    if (pn != p) {
	removeFromChunks();
	pn = p;
	addToChunks();
    }
}

/*!
    Sets the QBrush used when drawing the polygonal item to the brush \a b.

    \sa setPen(), brush(), drawShape()
*/
void Q3CanvasPolygonalItem::setBrush(QBrush b)
{
    if (br != b) {
	br = b;
	changeChunks();
    }
}


/*!
    \class Q3CanvasPolygon
    \compat
    \brief The Q3CanvasPolygon class provides a polygon on a Q3Canvas.

    Paints a polygon with a QBrush. The polygon's points can be set in
    the constructor or set or changed later using setPoints(). Use
    points() to retrieve the points, or areaPoints() to retrieve the
    points relative to the canvas's origin.

    The polygon can be drawn on a painter with drawShape().

    Like any other canvas item polygons can be moved with
    Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting
    coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY() and
    Q3CanvasItem::setZ().

    Note: Q3CanvasPolygon does not use the pen.

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs a point-less polygon on the canvas \a canvas. You
    should call setPoints() before using it further.
*/
Q3CanvasPolygon::Q3CanvasPolygon(Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas)
{
}

/*!
    Destroys the polygon.
*/
Q3CanvasPolygon::~Q3CanvasPolygon()
{
    hide();
}

/*!
    Draws the polygon using the painter \a p.

    Note that Q3CanvasPolygon does not support an outline (the pen is
    always NoPen).
*/
void Q3CanvasPolygon::drawShape(QPainter & p)
{
    // ### why can't we draw outlines? We could use drawPolyline for it. Lars
    // ### see other message. Warwick

    p.setPen(NoPen); // since QRegion(Q3PointArray) excludes outline :-()-:
    p.drawPolygon(poly);
}

/*!
    Sets the points of the polygon to be \a pa. These points will have
    their x and y coordinates automatically translated by x(), y() as
    the polygon is moved.
*/
void Q3CanvasPolygon::setPoints(Q3PointArray pa)
{
    removeFromChunks();
    poly = pa;
    poly.detach(); // Explicit sharing is stupid.
    poly.translate((int)x(),(int)y());
    addToChunks();
}

/*!
  \reimp
*/
void Q3CanvasPolygon::moveBy(double dx, double dy)
{
    // Note: does NOT call Q3CanvasPolygonalItem::moveBy(), since that
    // only does half this work.
    //
    int idx = int(x()+dx)-int(x());
    int idy = int(y()+dy)-int(y());
    if (idx || idy) {
	removeFromChunks();
	poly.translate(idx,idy);
    }
    myx+=dx;
    myy+=dy;
    if (idx || idy) {
	addToChunks();
    }
}

/*!
    \class Q3CanvasSpline
    \compat
    \brief The Q3CanvasSpline class provides multi-bezier splines on a Q3Canvas.

    A Q3CanvasSpline is a sequence of 4-point bezier curves joined
    together to make a curved shape.

    You set the control points of the spline with setControlPoints().

    If the bezier is closed(), then the first control point will be
    re-used as the last control point. Therefore, a closed bezier must
    have a multiple of 3 control points and an open bezier must have
    one extra point.

    The beziers are not necessarily joined "smoothly". To ensure this,
    set control points appropriately (general reference texts about
    beziers will explain this in detail).

    Like any other canvas item splines can be moved with
    Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting
    coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY() and
    Q3CanvasItem::setZ().

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Create a spline with no control points on the canvas \a canvas.

    \sa setControlPoints()
*/
Q3CanvasSpline::Q3CanvasSpline(Q3Canvas* canvas) :
    Q3CanvasPolygon(canvas),
    cl(true)
{
}

/*!
    Destroy the spline.
*/
Q3CanvasSpline::~Q3CanvasSpline()
{
}

/*!
    Set the spline control points to \a ctrl.

    If \a close is true, then the first point in \a ctrl will be
    re-used as the last point, and the number of control points must
    be a multiple of 3. If \a close is false, one additional control
    point is required, and the number of control points must be one of
    (4, 7, 10, 13, ...).

    If the number of control points doesn't meet the above conditions,
    the number of points will be truncated to the largest number of
    points that do meet the requirement.
*/
void Q3CanvasSpline::setControlPoints(Q3PointArray ctrl, bool close)
{
    if ((int)ctrl.count() % 3 != (close ? 0 : 1)) {
	qWarning("Q3CanvasSpline::setControlPoints(): Number of points doesn't fit.");
	int numCurves = (ctrl.count() - (close ? 0 : 1))/ 3;
	ctrl.resize(numCurves*3 + (close ? 0 : 1));
    }

    cl = close;
    bez = ctrl;
    recalcPoly();
}

/*!
    Returns the current set of control points.

    \sa setControlPoints(), closed()
*/
Q3PointArray Q3CanvasSpline::controlPoints() const
{
    return bez;
}

/*!
    Returns true if the control points are a closed set; otherwise
    returns false.
*/
bool Q3CanvasSpline::closed() const
{
    return cl;
}

void Q3CanvasSpline::recalcPoly()
{
    Q3PtrList<Q3PointArray> segs;
    segs.setAutoDelete(true);
    int n=0;
    for (int i=0; i<(int)bez.count()-1; i+=3) {
	Q3PointArray ctrl(4);
	ctrl[0] = bez[i+0];
	ctrl[1] = bez[i+1];
	ctrl[2] = bez[i+2];
	if (cl)
	    ctrl[3] = bez[(i+3)%(int)bez.count()];
	else
	    ctrl[3] = bez[i+3];
	Q3PointArray *seg = new Q3PointArray(ctrl.cubicBezier());
	n += seg->count()-1;
	segs.append(seg);
    }
    Q3PointArray p(n+1);
    n=0;
    for (Q3PointArray* seg = segs.first(); seg; seg = segs.next()) {
	for (int i=0; i<(int)seg->count()-1; i++)
	    p[n++] = seg->point(i);
	if (n == (int)p.count()-1)
	    p[n] = seg->point(seg->count()-1);
    }
    Q3CanvasPolygon::setPoints(p);
}

/*!
    \fn Q3PointArray Q3CanvasPolygonalItem::areaPoints() const

    This function must be reimplemented by subclasses. It \e must
    return the points bounding (i.e. outside and not touching) the
    shape or drawing errors will occur.
*/

/*!
    \fn Q3PointArray Q3CanvasPolygon::points() const

    Returns the vertices of the polygon, not translated by the position.

    \sa setPoints(), areaPoints()
*/
Q3PointArray Q3CanvasPolygon::points() const
{
    Q3PointArray pa = areaPoints();
    pa.translate(int(-x()),int(-y()));
    return pa;
}

/*!
    Returns the vertices of the polygon translated by the polygon's
    current x(), y() position, i.e. relative to the canvas's origin.

    \sa setPoints(), points()
*/
Q3PointArray Q3CanvasPolygon::areaPoints() const
{
    return poly.copy();
}

/*!
    \class Q3CanvasLine
    \compat
    \brief The Q3CanvasLine class provides a line on a Q3Canvas.

    The line inherits functionality from Q3CanvasPolygonalItem, for
    example the setPen() function. The start and end points of the
    line are set with setPoints().

    Like any other canvas item lines can be moved with
    Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting
    coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY() and
    Q3CanvasItem::setZ().

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs a line from (0,0) to (0,0) on \a canvas.

    \sa setPoints()
*/
Q3CanvasLine::Q3CanvasLine(Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas)
{
    x1 = y1 = x2 = y2 = 0;
}

/*!
    Destroys the line.
*/
Q3CanvasLine::~Q3CanvasLine()
{
    hide();
}

/*!
  \reimp
*/
void Q3CanvasLine::setPen(QPen p)
{
    Q3CanvasPolygonalItem::setPen(p);
}

/*!
    \fn QPoint Q3CanvasLine::startPoint () const

    Returns the start point of the line.

    \sa setPoints(), endPoint()
*/

/*!
    \fn QPoint Q3CanvasLine::endPoint () const

    Returns the end point of the line.

    \sa setPoints(), startPoint()
*/

/*!
    Sets the line's start point to (\a xa, \a ya) and its end point to
    (\a xb, \a yb).
*/
void Q3CanvasLine::setPoints(int xa, int ya, int xb, int yb)
{
    if (x1 != xa || x2 != xb || y1 != ya || y2 != yb) {
	removeFromChunks();
	x1 = xa;
	y1 = ya;
	x2 = xb;
	y2 = yb;
	addToChunks();
    }
}

/*!
  \reimp
*/
void Q3CanvasLine::drawShape(QPainter &p)
{
    p.drawLine((int)(x()+x1), (int)(y()+y1), (int)(x()+x2), (int)(y()+y2));
}

/*!
    \reimp

    Note that the area defined by the line is somewhat thicker than
    the line that is actually drawn.
*/
Q3PointArray Q3CanvasLine::areaPoints() const
{
    Q3PointArray p(4);
    int xi = int(x());
    int yi = int(y());
    int pw = pen().width();
    int dx = QABS(x1-x2);
    int dy = QABS(y1-y2);
    pw = pw*4/3+2; // approx pw*sqrt(2)
    int px = x1<x2 ? -pw : pw ;
    int py = y1<y2 ? -pw : pw ;
    if (dx && dy && (dx > dy ? (dx*2/dy <= 2) : (dy*2/dx <= 2))) {
	// steep
	if (px == py) {
	    p[0] = QPoint(x1+xi   ,y1+yi+py);
	    p[1] = QPoint(x2+xi-px,y2+yi  );
	    p[2] = QPoint(x2+xi   ,y2+yi-py);
	    p[3] = QPoint(x1+xi+px,y1+yi  );
	} else {
	    p[0] = QPoint(x1+xi+px,y1+yi  );
	    p[1] = QPoint(x2+xi   ,y2+yi-py);
	    p[2] = QPoint(x2+xi-px,y2+yi  );
	    p[3] = QPoint(x1+xi   ,y1+yi+py);
	}
    } else if (dx > dy) {
	// horizontal
	p[0] = QPoint(x1+xi+px,y1+yi+py);
	p[1] = QPoint(x2+xi-px,y2+yi+py);
	p[2] = QPoint(x2+xi-px,y2+yi-py);
	p[3] = QPoint(x1+xi+px,y1+yi-py);
    } else {
	// vertical
	p[0] = QPoint(x1+xi+px,y1+yi+py);
	p[1] = QPoint(x2+xi+px,y2+yi-py);
	p[2] = QPoint(x2+xi-px,y2+yi-py);
	p[3] = QPoint(x1+xi-px,y1+yi+py);
    }
    return p;
}

/*!
    \reimp

*/

void Q3CanvasLine::moveBy(double dx, double dy)
{
    Q3CanvasPolygonalItem::moveBy(dx, dy);
}

/*!
    \class Q3CanvasRectangle
    \compat
    \brief The Q3CanvasRectangle class provides a rectangle on a Q3Canvas.

    This item paints a single rectangle which may have any pen() and
    brush(), but may not be tilted/rotated. For rotated rectangles,
    use Q3CanvasPolygon.

    The rectangle's size and initial position can be set in the
    constructor. The size can be set or changed later using setSize().
    Use height() and width() to retrieve the rectangle's dimensions.

    The rectangle can be drawn on a painter with drawShape().

    Like any other canvas item rectangles can be moved with
    Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting
    coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY() and
    Q3CanvasItem::setZ().

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs a rectangle at position (0,0) with both width and
    height set to 32 pixels on \a canvas.
*/
Q3CanvasRectangle::Q3CanvasRectangle(Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas),
    w(32), h(32)
{
}

/*!
    Constructs a rectangle positioned and sized by \a r on \a canvas.
*/
Q3CanvasRectangle::Q3CanvasRectangle(const QRect& r, Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas),
    w(r.width()), h(r.height())
{
    move(r.x(),r.y());
}

/*!
    Constructs a rectangle at position (\a x, \a y) and size \a width
    by \a height, on \a canvas.
*/
Q3CanvasRectangle::Q3CanvasRectangle(int x, int y, int width, int height,
	Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas),
    w(width), h(height)
{
    move(x,y);
}

/*!
    Destroys the rectangle.
*/
Q3CanvasRectangle::~Q3CanvasRectangle()
{
    hide();
}


/*!
    Returns the width of the rectangle.
*/
int Q3CanvasRectangle::width() const
{
    return w;
}

/*!
    Returns the height of the rectangle.
*/
int Q3CanvasRectangle::height() const
{
    return h;
}

/*!
    Sets the \a width and \a height of the rectangle.
*/
void Q3CanvasRectangle::setSize(int width, int height)
{
    if (w != width || h != height) {
	removeFromChunks();
	w = width;
	h = height;
	addToChunks();
    }
}

/*!
    \fn QSize Q3CanvasRectangle::size() const

    Returns the width() and height() of the rectangle.

    \sa rect(), setSize()
*/

/*!
    \fn QRect Q3CanvasRectangle::rect() const

    Returns the integer-converted x(), y() position and size() of the
    rectangle as a QRect.
*/

/*!
  \reimp
*/
Q3PointArray Q3CanvasRectangle::areaPoints() const
{
    Q3PointArray pa(4);
    int pw = (pen().width()+1)/2;
    if (pw < 1) pw = 1;
    if (pen() == NoPen) pw = 0;
    pa[0] = QPoint((int)x()-pw,(int)y()-pw);
    pa[1] = pa[0] + QPoint(w+pw*2,0);
    pa[2] = pa[1] + QPoint(0,h+pw*2);
    pa[3] = pa[0] + QPoint(0,h+pw*2);
    return pa;
}

/*!
    Draws the rectangle on painter \a p.
*/
void Q3CanvasRectangle::drawShape(QPainter & p)
{
    p.drawRect((int)x(), (int)y(), w, h);
}


/*!
    \class Q3CanvasEllipse
    \compat
    \brief The Q3CanvasEllipse class provides an ellipse or ellipse segment on a Q3Canvas.

    A canvas item that paints an ellipse or ellipse segment with a QBrush.
    The ellipse's height, width, start angle and angle length can be set
    at construction time. The size can be changed at runtime with
    setSize(), and the angles can be changed (if you're displaying an
    ellipse segment rather than a whole ellipse) with setAngles().

    Note that angles are specified in 16ths of a degree.

    \target anglediagram
    \img qcanvasellipse.png Ellipse

    If a start angle and length angle are set then an ellipse segment
    will be drawn. The start angle is the angle that goes from zero in a
    counter-clockwise direction (shown in green in the diagram). The
    length angle is the angle from the start angle in a
    counter-clockwise direction (shown in blue in the diagram). The blue
    segment is the segment of the ellipse that would be drawn. If no
    start angle and length angle are specified the entire ellipse is
    drawn.

    The ellipse can be drawn on a painter with drawShape().

    Like any other canvas item ellipses can be moved with move() and
    moveBy(), or by setting coordinates with setX(), setY() and setZ().

    Note: Q3CanvasEllipse does not use the pen.

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs a 32x32 ellipse, centered at (0, 0) on \a canvas.
*/
Q3CanvasEllipse::Q3CanvasEllipse(Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas),
    w(32), h(32),
    a1(0), a2(360*16)
{
}

/*!
    Constructs a \a width by \a height pixel ellipse, centered at
    (0, 0) on \a canvas.
*/
Q3CanvasEllipse::Q3CanvasEllipse(int width, int height, Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas),
    w(width),h(height),
    a1(0),a2(360*16)
{
}

// ### add a constructor taking degrees in float. 1/16 degrees is stupid. Lars
// ### it's how QPainter does it, so Q3Canvas does too for consistency. If it's
// ###  a good idea, it should be added to QPainter, not just to Q3Canvas. Warwick
/*!
    Constructs a \a width by \a height pixel ellipse, centered at
    (0, 0) on \a canvas. Only a segment of the ellipse is drawn,
    starting at angle \a startangle, and extending for angle \a angle
    (the angle length).

    Note that angles are specified in sixteenths of a degree.
*/
Q3CanvasEllipse::Q3CanvasEllipse(int width, int height,
    int startangle, int angle, Q3Canvas* canvas) :
    Q3CanvasPolygonalItem(canvas),
    w(width),h(height),
    a1(startangle),a2(angle)
{
}

/*!
    Destroys the ellipse.
*/
Q3CanvasEllipse::~Q3CanvasEllipse()
{
    hide();
}

/*!
    Returns the width of the ellipse.
*/
int Q3CanvasEllipse::width() const
{
    return w;
}

/*!
    Returns the height of the ellipse.
*/
int Q3CanvasEllipse::height() const
{
    return h;
}

/*!
    Sets the \a width and \a height of the ellipse.
*/
void Q3CanvasEllipse::setSize(int width, int height)
{
    if (w != width || h != height) {
	removeFromChunks();
	w = width;
	h = height;
	addToChunks();
    }
}

/*!
    \fn int Q3CanvasEllipse::angleStart() const

    Returns the start angle in 16ths of a degree. Initially
    this will be 0.

    \sa setAngles(), angleLength()
*/

/*!
    \fn int Q3CanvasEllipse::angleLength() const

    Returns the length angle (the extent of the ellipse segment) in
    16ths of a degree. Initially this will be 360 * 16 (a complete
    ellipse).

    \sa setAngles(), angleStart()
*/

/*!
    Sets the angles for the ellipse. The start angle is \a start and
    the extent of the segment is \a length (the angle length) from the
    \a start. The angles are specified in 16ths of a degree. By
    default the ellipse will start at 0 and have an angle length of
    360 * 16 (a complete ellipse).

    \sa angleStart(), angleLength()
*/
void Q3CanvasEllipse::setAngles(int start, int length)
{
    if (a1 != start || a2 != length) {
	removeFromChunks();
	a1 = start;
	a2 = length;
	addToChunks();
    }
}

/*!
  \reimp
*/
Q3PointArray Q3CanvasEllipse::areaPoints() const
{
    Q3PointArray r;
    // makeArc at 0,0, then translate so that fixed point math doesn't overflow
    r.makeArc(int(x()-w/2.0+0.5)-1, int(y()-h/2.0+0.5)-1, w+3, h+3, a1, a2);
    r.resize(r.size()+1);
    r.setPoint(r.size()-1,int(x()),int(y()));
    return r;
}

// ### support outlines! Lars
// ### QRegion doesn't, so we cannot (try it). Warwick
/*!
    Draws the ellipse, centered at x(), y() using the painter \a p.

    Note that Q3CanvasEllipse does not support an outline (the pen is
    always NoPen).
*/
void Q3CanvasEllipse::drawShape(QPainter & p)
{
    p.setPen(NoPen); // since QRegion(Q3PointArray) excludes outline :-()-:
    if (!a1 && a2 == 360*16) {
	p.drawEllipse(int(x()-w/2.0+0.5), int(y()-h/2.0+0.5), w, h);
    } else {
	p.drawPie(int(x()-w/2.0+0.5), int(y()-h/2.0+0.5), w, h, a1, a2);
    }
}


/*!
    \class Q3CanvasText
    \compat
    \brief The Q3CanvasText class provides a text object on a Q3Canvas.

    A canvas text item has text with font, color and alignment
    attributes. The text and font can be set in the constructor or set
    or changed later with setText() and setFont(). The color is set
    with setColor() and the alignment with setTextFlags(). The text
    item's bounding rectangle is retrieved with boundingRect().

    The text can be drawn on a painter with draw().

    Like any other canvas item text items can be moved with
    Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting
    coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY() and
    Q3CanvasItem::setZ().

    \sa QtCanvas, {Porting to Graphics View}
*/

/*!
    Constructs a Q3CanvasText with the text "\<text\>", on \a canvas.
*/
Q3CanvasText::Q3CanvasText(Q3Canvas* canvas) :
    Q3CanvasItem(canvas),
    txt(QLatin1String("<text>")), flags(0)
{
    setRect();
}

// ### add textflags to the constructor? Lars
/*!
    Constructs a Q3CanvasText with the text \a t, on canvas \a canvas.
*/
Q3CanvasText::Q3CanvasText(const QString& t, Q3Canvas* canvas) :
    Q3CanvasItem(canvas),
    txt(t), flags(0)
{
    setRect();
}

// ### see above
/*!
    Constructs a Q3CanvasText with the text \a t and font \a f, on the
    canvas \a canvas.
*/
Q3CanvasText::Q3CanvasText(const QString& t, QFont f, Q3Canvas* canvas) :
    Q3CanvasItem(canvas),
    txt(t), flags(0),
    fnt(f)
{
    setRect();
}

/*!
    Destroys the canvas text item.
*/
Q3CanvasText::~Q3CanvasText()
{
    removeFromChunks();
}

/*!
    Returns the bounding rectangle of the text.
*/
QRect Q3CanvasText::boundingRect() const { return brect; }

void Q3CanvasText::setRect()
{
    brect = QFontMetrics(fnt).boundingRect(int(x()), int(y()), 0, 0, flags, txt);
}

/*!
    \fn int Q3CanvasText::textFlags() const

    Returns the currently set alignment flags.

    \sa setTextFlags() Qt::AlignmentFlag
*/


/*!
    Sets the alignment flags to \a f. These are a bitwise OR of the
    flags available to QPainter::drawText() -- see the
    \l{Qt::AlignmentFlag}s.

    \sa setFont() setColor()
*/
void Q3CanvasText::setTextFlags(int f)
{
    if (flags != f) {
	removeFromChunks();
	flags = f;
	setRect();
	addToChunks();
    }
}

/*!
    Returns the text item's text.

    \sa setText()
*/
QString Q3CanvasText::text() const
{
    return txt;
}


/*!
    Sets the text item's text to \a t. The text may contain newlines.

    \sa text(), setFont(), setColor() setTextFlags()
*/
void Q3CanvasText::setText(const QString& t)
{
    if (txt != t) {
	removeFromChunks();
	txt = t;
	setRect();
	addToChunks();
    }
}

/*!
    Returns the font in which the text is drawn.

    \sa setFont()
*/
QFont Q3CanvasText::font() const
{
    return fnt;
}

/*!
    Sets the font in which the text is drawn to font \a f.

    \sa font()
*/
void Q3CanvasText::setFont(const QFont& f)
{
    if (f != fnt) {
	removeFromChunks();
	fnt = f;
	setRect();
	addToChunks();
    }
}

/*!
    Returns the color of the text.

    \sa setColor()
*/
QColor Q3CanvasText::color() const
{
    return col;
}

/*!
    Sets the color of the text to the color \a c.

    \sa color(), setFont()
*/
void Q3CanvasText::setColor(const QColor& c)
{
    col=c;
    changeChunks();
}


/*!
  \reimp
*/
void Q3CanvasText::moveBy(double dx, double dy)
{
    int idx = int(x()+dx)-int(x());
    int idy = int(y()+dy)-int(y());
    if (idx || idy) {
	removeFromChunks();
    }
    myx+=dx;
    myy+=dy;
    if (idx || idy) {
	brect.moveBy(idx,idy);
	addToChunks();
    }
}

/*!
    Draws the text using the painter \a painter.
*/
void Q3CanvasText::draw(QPainter& painter)
{
    painter.setFont(fnt);
    painter.setPen(col);
    painter.drawText(painter.fontMetrics().boundingRect(int(x()), int(y()), 0, 0, flags, txt), flags, txt);
}

/*!
  \internal
*/
void Q3CanvasText::changeChunks()
{
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	for (int j=brect.top()/chunksize; j<=brect.bottom()/chunksize; j++) {
	    for (int i=brect.left()/chunksize; i<=brect.right()/chunksize; i++) {
		canvas()->setChangedChunk(i,j);
	    }
	}
    }
}

/*!
    Adds the text item to the appropriate chunks.
*/
void Q3CanvasText::addToChunks()
{
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	for (int j=brect.top()/chunksize; j<=brect.bottom()/chunksize; j++) {
	    for (int i=brect.left()/chunksize; i<=brect.right()/chunksize; i++) {
		canvas()->addItemToChunk(this,i,j);
	    }
	}
    }
}

/*!
    Removes the text item from the appropriate chunks.
*/
void Q3CanvasText::removeFromChunks()
{
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	for (int j=brect.top()/chunksize; j<=brect.bottom()/chunksize; j++) {
	    for (int i=brect.left()/chunksize; i<=brect.right()/chunksize; i++) {
		canvas()->removeItemFromChunk(this,i,j);
	    }
	}
    }
}


/*!
    Returns 0 (Q3CanvasItem::Rtti_Item).

    Make your derived classes return their own values for rtti(), so
    that you can distinguish between objects returned by
    Q3Canvas::at(). You should use values greater than 1000 to allow
    for extensions to this class.

    Overuse of this functionality can damage its extensibility. For
    example, once you have identified a base class of a Q3CanvasItem
    found by Q3Canvas::at(), cast it to that type and call meaningful
    methods rather than acting upon the object based on its rtti
    value.

    For example:

    \snippet doc/src/snippets/code/src_qt3support_canvas_q3canvas.cpp 4
*/
int Q3CanvasItem::rtti() const { return RTTI; }
int Q3CanvasItem::RTTI = Rtti_Item;

/*!
    Returns 1 (Q3CanvasItem::Rtti_Sprite).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasSprite::rtti() const { return RTTI; }
int Q3CanvasSprite::RTTI = Rtti_Sprite;

/*!
    Returns 2 (Q3CanvasItem::Rtti_PolygonalItem).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasPolygonalItem::rtti() const { return RTTI; }
int Q3CanvasPolygonalItem::RTTI = Rtti_PolygonalItem;

/*!
    Returns 3 (Q3CanvasItem::Rtti_Text).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasText::rtti() const { return RTTI; }
int Q3CanvasText::RTTI = Rtti_Text;

/*!
    Returns 4 (Q3CanvasItem::Rtti_Polygon).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasPolygon::rtti() const { return RTTI; }
int Q3CanvasPolygon::RTTI = Rtti_Polygon;

/*!
    Returns 5 (Q3CanvasItem::Rtti_Rectangle).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasRectangle::rtti() const { return RTTI; }
int Q3CanvasRectangle::RTTI = Rtti_Rectangle;

/*!
    Returns 6 (Q3CanvasItem::Rtti_Ellipse).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasEllipse::rtti() const { return RTTI; }
int Q3CanvasEllipse::RTTI = Rtti_Ellipse;

/*!
    Returns 7 (Q3CanvasItem::Rtti_Line).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasLine::rtti() const { return RTTI; }
int Q3CanvasLine::RTTI = Rtti_Line;

/*!
    Returns 8 (Q3CanvasItem::Rtti_Spline).

    \sa Q3CanvasItem::rtti()
*/
int Q3CanvasSpline::rtti() const { return RTTI; }
int Q3CanvasSpline::RTTI = Rtti_Spline;

/*!
    Constructs a Q3CanvasSprite which uses images from the
    Q3CanvasPixmapArray \a a.

    The sprite in initially positioned at (0, 0) on \a canvas, using
    frame 0.
*/
Q3CanvasSprite::Q3CanvasSprite(Q3CanvasPixmapArray* a, Q3Canvas* canvas) :
    Q3CanvasItem(canvas),
    frm(0),
    anim_val(0),
    anim_state(0),
    anim_type(0),
    images(a)
{
}


/*!
    Set the array of images used for displaying the sprite to the
    Q3CanvasPixmapArray \a a.

    If the current frame() is larger than the number of images in \a
    a, the current frame will be reset to 0.
*/
void Q3CanvasSprite::setSequence(Q3CanvasPixmapArray* a)
{
    bool isvisible = isVisible();
    if (isvisible && images)
	hide();
    images = a;
    if (frm >= (int)images->count())
	frm = 0;
    if (isvisible)
	show();
}

/*!
\internal

Marks any chunks the sprite touches as changed.
*/
void Q3CanvasSprite::changeChunks()
{
    if (isVisible() && canvas()) {
	int chunksize=canvas()->chunkSize();
	for (int j=topEdge()/chunksize; j<=bottomEdge()/chunksize; j++) {
	    for (int i=leftEdge()/chunksize; i<=rightEdge()/chunksize; i++) {
		canvas()->setChangedChunk(i,j);
	    }
	}
    }
}

/*!
    Destroys the sprite and removes it from the canvas. Does \e not
    delete the images.
*/
Q3CanvasSprite::~Q3CanvasSprite()
{
    removeFromChunks();
}

/*!
    Sets the animation frame used for displaying the sprite to \a f,
    an index into the Q3CanvasSprite's Q3CanvasPixmapArray. The call
    will be ignored if \a f is larger than frameCount() or smaller
    than 0.

    \sa frame() move()
*/
void Q3CanvasSprite::setFrame(int f)
{
    move(x(),y(),f);
}

/*!
    \enum Q3CanvasSprite::FrameAnimationType

    This enum is used to identify the different types of frame
    animation offered by Q3CanvasSprite.

    \value Cycle at each advance the frame number will be incremented by
    1 (modulo the frame count).
    \value Oscillate at each advance the frame number will be
    incremented by 1 up to the frame count then decremented to by 1 to
    0, repeating this sequence forever.
*/

/*!
    Sets the animation characteristics for the sprite.

    For \a type == \c Cycle, the frames will increase by \a step
    at each advance, modulo the frameCount().

    For \a type == \c Oscillate, the frames will increase by \a step
    at each advance, up to the frameCount(), then decrease by \a step
    back to 0, repeating forever.

    The \a state parameter is for internal use.
*/
void Q3CanvasSprite::setFrameAnimation(FrameAnimationType type, int step, int state)
{
    anim_val = step;
    anim_type = type;
    anim_state = state;
    setAnimated(true);
}

/*!
    Extends the default Q3CanvasItem implementation to provide the
    functionality of setFrameAnimation().

    The \a phase is 0 or 1: see Q3CanvasItem::advance() for details.

    \sa Q3CanvasItem::advance() setVelocity()
*/
void Q3CanvasSprite::advance(int phase)
{
    if (phase==1) {
	int nf = frame();
	if (anim_type == Oscillate) {
	    if (anim_state)
		nf += anim_val;
	    else
		nf -= anim_val;
	    if (nf < 0) {
		nf = abs(anim_val);
		anim_state = !anim_state;
	    } else if (nf >= frameCount()) {
		nf = frameCount()-1-abs(anim_val);
		anim_state = !anim_state;
	    }
	} else {
	    nf = (nf + anim_val + frameCount()) % frameCount();
	}
	move(x()+xVelocity(),y()+yVelocity(),nf);
    }
}


/*!
    \fn int Q3CanvasSprite::frame() const

    Returns the index of the current animation frame in the
    Q3CanvasSprite's Q3CanvasPixmapArray.

    \sa setFrame(), move()
*/

/*!
    \fn int Q3CanvasSprite::frameCount() const

    Returns the number of frames in the Q3CanvasSprite's
    Q3CanvasPixmapArray.
*/


/*!
    Moves the sprite to (\a x, \a y).
*/
void Q3CanvasSprite::move(double x, double y) { Q3CanvasItem::move(x,y); }

/*!
    \fn void Q3CanvasSprite::move(double nx, double ny, int nf)

    Moves the sprite to (\a nx, \a ny) and sets the current
    frame to \a nf. \a nf will be ignored if it is larger than
    frameCount() or smaller than 0.
*/
void Q3CanvasSprite::move(double nx, double ny, int nf)
{
    if (isVisible() && canvas()) {
	hide();
	Q3CanvasItem::move(nx,ny);
	if (nf >= 0 && nf < frameCount())
	    frm=nf;
	show();
    } else {
	Q3CanvasItem::move(nx,ny);
	if (nf >= 0 && nf < frameCount())
	    frm=nf;
    }
}

class Q3CanvasPolygonScanner : public Q3PolygonScanner {
    QPolygonalProcessor& processor;
public:
    Q3CanvasPolygonScanner(QPolygonalProcessor& p) :
	processor(p)
    {
    }
    void processSpans(int n, QPoint* point, int* width)
    {
	processor.doSpans(n,point,width);
    }
};

void Q3CanvasPolygonalItem::scanPolygon(const Q3PointArray& pa, int winding, QPolygonalProcessor& process) const
{
    Q3CanvasPolygonScanner scanner(process);
    scanner.scan(pa,winding);
}

QT_END_NAMESPACE
