/****************************************************************************
**
** 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
