/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of a Qt Solutions component.
**
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
****************************************************************************/

#include "qtcanvas.h"
#include <QApplication>
#include <QBitmap>
#include <QDesktopWidget>
#include <QImage>
#include <QPainter>
#include <QTimer>
#include <QHash>
#include <QSet>
#include <QtAlgorithms>
#include <QEvent>
#include <QPaintEvent>
#include <QPainterPath>

#include <stdlib.h>
using namespace Qt;

class QtCanvasData {
public:
    QtCanvasData()
    {
    }

    QList<QtCanvasView *> viewList;
    QSet<QtCanvasItem *> itemDict;
    QSet<QtCanvasItem *> animDict;
};

class QtCanvasViewData {
public:
    QtCanvasViewData() {}
    QMatrix xform;
    QMatrix ixform;
    bool highQuality;
};

// clusterizer

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

    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 QtCanvasClusterizer groups rectangles (QRects) into non-overlapping rectangles
by a merging heuristic.
*/
QtCanvasClusterizer::QtCanvasClusterizer(int maxclusters) :
    cluster(new QRect[maxclusters]),
    count(0),
    maxcl(maxclusters)
{ }

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

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

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

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

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

    //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& QtCanvasClusterizer::operator[](int i) const
{
    return cluster[i];
}

// end of clusterizer


class QtCanvasItemLess
{
public:
    inline bool operator()(const QtCanvasItem *i1, const QtCanvasItem *i2) const
    {
        if (i1->z() == i2->z())
            return i1 > i2;
        return (i1->z() > i2->z());
    }
};


class QtCanvasChunk {
public:
    QtCanvasChunk() : 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()
    {
        qSort(m_list.begin(), m_list.end(), QtCanvasItemLess());
    }

    const QtCanvasItemList &list() const
    {
        return m_list;
    }

    void add(QtCanvasItem* item)
    {
        m_list.prepend(item);
        changed = true;
    }

    void remove(QtCanvasItem* item)
    {
        m_list.removeAll(item);
        changed = true;
    }

    void change()
    {
        changed = true;
    }

    bool hasChanged() const
    {
        return changed;
    }

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

private:
    QtCanvasItemList m_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 QtCanvas qtcanvas.h
    \brief The QtCanvas class provides a 2D area that can contain QtCanvasItem objects.

    The QtCanvas 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 QtCanvasView.
    Multiple QtCanvasView 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 QtScrollView subclass.

    Qt provides a rich
    set of canvas item classes, e.g. QtCanvasEllipse, QtCanvasLine,
    QtCanvasPolygon, QtCanvasPolygonalItem, QtCanvasRectangle, QtCanvasSpline,
    QtCanvasSprite and QtCanvasText. You can subclass to create your own
    canvas items; QtCanvasPolygonalItem is the most common base class used
    for this purpose.

    Items appear on the canvas after their \link QtCanvasItem::show()
    show()\endlink function has been called (or \link
    QtCanvasItem::setVisible() setVisible(true)\endlink), and \e after
    update() has been called. The canvas only shows items that are
    \link QtCanvasItem::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 QtCanvas 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 QtCanvasView objects can view the same canvas.

    \i An arbitrary transformation matrix can be set on each QtCanvasView
    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 QtCanvas 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 QtCanvasView 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 QtCanvasItem::setCanvas().

    Canvas items are movable (and in the case of QtCanvasSprites, animated)
    objects that inherit QtCanvasItem. 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 QtCanvasItem::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 QtCanvasItem::move(). The advance()
    function moves all QtCanvasItem::animated() canvas items and
    setAdvancePeriod() makes QtCanvas move them automatically on a periodic
    basis. In the context of the QtCanvas classes, to `animate' a canvas item
    is to set it in motion, i.e. using QtCanvasItem::setVelocity(). Animation
    of a canvas item itself, i.e. items which change over time, is enabled
    by calling QtCanvasSprite::setFrameAnimation(), or more generally by
    subclassing and reimplementing QtCanvasItem::advance(). To detect collisions
    use one of the QtCanvasItem::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
    QtCanvasItem::advance() on every item that is \link
    QtCanvasItem::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.)

    QtCanvas 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 QtCanvas'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 QtCanvas 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 QtCanvas's facilities.

    \sa QtCanvasView QtCanvasItem
*/
void QtCanvas::init(int w, int h, int chunksze, int mxclusters)
{
    d = new QtCanvasData;
    awidth = w;
    aheight = h;
    chunksize = chunksze;
    maxclusters = mxclusters;
    chwidth = (w+chunksize-1)/chunksize;
    chheight = (h+chunksize-1)/chunksize;
    chunks = new QtCanvasChunk[chwidth*chheight];
    update_timer = 0;
    bgcolor = white;
    grid = 0;
    htiles = 0;
    vtiles = 0;
    debug_redraw_areas = false;
}

/*
    Create a QtCanvas with no size. \a parent is passed to the QObject
    superclass.

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

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

/*
    Constructs a QtCanvas 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 QtCanvas 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()
*/
QtCanvas::QtCanvas(QPixmap p,
        int h, int v, int tilewidth, int tileheight)
{
    init(h*tilewidth, v*tileheight, scm(tilewidth, tileheight));
    setTiles(p, h, v, tilewidth, tileheight);
}

/*
    Destroys the canvas and all the canvas's canvas items.
*/
QtCanvas::~QtCanvas()
{
    for (int i = 0; i < d->viewList.size(); ++i)
        d->viewList[i]->viewing = 0;
    QtCanvasItemList all = allItems();
    for (QtCanvasItemList::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.
*/
QtCanvasChunk& QtCanvas::chunk(int i, int j) const
{
    return chunks[i+chwidth*j];
}

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

/*
    Returns a list of all the items in the canvas.
*/
QtCanvasItemList QtCanvas::allItems()
{
    return d->itemDict.toList();
}


/*
    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 QtCanvas::resize(int w, int h)
{
    if (awidth == w && aheight == h)
        return;

    QList<QtCanvasItem *> hidden;
    for (QSet<QtCanvasItem *>::const_iterator it = d->itemDict.begin(); it != d->itemDict.end(); ++it) {
        if ((*it)->isVisible()) {
            (*it)->hide();
            hidden.append(*it);
        }
    }

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

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

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

    for (int i = 0; i < hidden.size(); ++i)
        hidden.at(i)->show();

    setAllChanged();

    emit resized();
}

/*
    \fn void QtCanvas::resized()

    This signal is emitted whenever the canvas is resized. Each
    QtCanvasView 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 QtCanvas::retune(int chunksze, int mxclusters)
{
    maxclusters = mxclusters;

    if (chunksize!= chunksze) {
        QList<QtCanvasItem *> hidden;
        for (QSet<QtCanvasItem *>::const_iterator it = d->itemDict.begin(); it != d->itemDict.end(); ++it) {
            if ((*it)->isVisible()) {
                (*it)->hide();
                hidden.append(*it);
            }
        }

        chunksize = chunksze;

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

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

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

        for (int i = 0; i < hidden.size(); ++i)
            hidden.at(i)->show();
    }
}

/*
    \fn int QtCanvas::width() const

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

/*
    \fn int QtCanvas::height() const

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

/*
    \fn QSize QtCanvas::size() const

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

/*
    \fn QRect QtCanvas::rect() const

    Returns a rectangle the size of the canvas.
*/


/*
    \fn bool QtCanvas::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 QtCanvas::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 QtCanvas::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 QtCanvas::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 QtCanvas::chunkSize() const

    Returns the chunk size of the canvas.

    \sa retune()
*/

/*
\fn bool QtCanvas::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 QtCanvasItem objects
in the QtCanvas. The QtCanvasItem class calls this.
*/
void QtCanvas::addItem(QtCanvasItem* item)
{
    d->itemDict.insert(item);
}

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

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

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

/*
\internal
This method adds the view \a view to the list of QtCanvasView objects
viewing this QtCanvas. The QtCanvasView class calls this.
*/
void QtCanvas::addView(QtCanvasView* view)
{
    d->viewList.append(view);
    if (htiles>1 || vtiles>1 || pm.isNull()) {
        QPalette::ColorRole role = view->widget()->backgroundRole();
        QPalette viewPalette = view->widget()->palette();
        viewPalette.setColor(role, backgroundColor());
        view->widget()->setPalette(viewPalette);
    }
}

/*
\internal
This method removes the view \a view from the list of QtCanvasView objects
viewing this QtCanvas. The QtCanvasView class calls this.
*/
void QtCanvas::removeView(QtCanvasView* view)
{
    d->viewList.removeAll(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 QtCanvas::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 QtCanvas::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 QtCanvasItem::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
    QtCanvasItem::advance() function of each QtCanvasItem::animated()
    canvas item is called with paramater 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 QtCanvasItem 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 QtCanvas::advance()
{
    QSetIterator<QtCanvasItem *> it = d->animDict;
    while (it.hasNext()) {
        QtCanvasItem *i = it.next();
        if (i)
            i->advance(0);
    }
    // we expect the dict contains the exact same items as in the
    // first pass.
    it.toFront();
    while (it.hasNext()) {
        QtCanvasItem* i = it.next();
        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 QtCanvas::drawViewArea(QtCanvasView* view, QPainter* p, const QRect& vr, bool)
{
    QMatrix wm = view->worldMatrix();
    QMatrix iwm = wm.inverted();
    // ivr = covers all chunks in vr
    QRect ivr = iwm.mapRect(vr);

    p->setMatrix(wm);
    drawCanvasArea(ivr, p, false);
}

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

    \sa advance()
*/
void QtCanvas::update()
{
    QRect r = changeBounds();
    for (int i = 0; i < d->viewList.size(); ++i) {
        QtCanvasView* view = d->viewList.at(i);
        if (!r.isEmpty()) {
            QRect tr = view->worldMatrix().mapRect(r);
            view->widget()->update(tr);
        }
    }
    setUnchanged(r);
}


/*
    Marks the whole canvas as changed.
    All views of the canvas will be entirely redrawn when
    update() is called next.
*/
void QtCanvas::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 QtCanvas::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 QtCanvas::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 QtCanvas::changeBounds()
{
    QRect area = 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) {
            QtCanvasChunk& ch = chunk(x, y);
            if (ch.hasChanged())
                result |= QRect(x*chunksize, y*chunksize, chunksize + 1, chunksize + 1);
            y++;
        }
        x++;
    }

    return result;
}

/*
    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:
    \code
    QPrinter pr;
    if (pr.setup()) {
        QPainter p(&pr);
        canvas.drawArea(canvas.rect(), &p);
    }
    \endcode
*/
void QtCanvas::drawArea(const QRect& clip, QPainter* painter, bool dbuf)
{
    if (painter)
        drawCanvasArea(clip, painter, dbuf);
}

#include <QtCore/QDebug>
/*
  \internal
*/
void QtCanvas::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;

    QtCanvasItemList 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).list();
                }
            } else {
                allvisible += chunk(x, y).list();
            }
        }
    }
    qSort(allvisible.begin(), allvisible.end(), QtCanvasItemLess());

    drawBackground(*p, area);
    if (!allvisible.isEmpty()) {
        QtCanvasItem* prev = 0;
        for (int i = allvisible.size() - 1; i >= 0; --i) {
            QtCanvasItem *g = allvisible[i];
            if (g != prev) {
                g->draw(*p);
                prev = g;
            }
        }
    }

    drawForeground(*p, area);
}

/*
\internal
This method to informs the QtCanvas 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 QtCanvasItem
must do so too. SetChangedChunkContaining can be used instead.
*/
void QtCanvas::setChangedChunk(int x, int y)
{
    if (validChunk(x, y)) {
        QtCanvasChunk& ch = chunk(x, y);
        ch.change();
    }
}

/*
\internal
This method to informs the QtCanvas 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 QtCanvasItem must
do so too. SetChangedChunk can be used instead.
*/
void QtCanvas::setChangedChunkContaining(int x, int y)
{
    if (x>= 0 && x < width() && y>= 0 && y < height()) {
        QtCanvasChunk& chunk = chunkContaining(x, y);
        chunk.change();
    }
}

/*
\internal
This method adds the QtCanvasItem \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 QtCanvas::addItemToChunk(QtCanvasItem* g, int x, int y)
{
    if (validChunk(x, y)) {
        chunk(x, y).add(g);
    }
}

/*
\internal
This method removes the QtCanvasItem \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 QtCanvas::removeItemFromChunk(QtCanvasItem* g, int x, int y)
{
    if (validChunk(x, y)) {
        chunk(x, y).remove(g);
    }
}


/*
\internal
This method adds the QtCanvasItem \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 QtCanvas::addItemToChunkContaining(QtCanvasItem* g, int x, int y)
{
    if (x>= 0 && x < width() && y>= 0 && y < height()) {
        chunkContaining(x, y).add(g);
    }
}

/*
\internal
This method removes the QtCanvasItem \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 QtCanvas::removeItemFromChunkContaining(QtCanvasItem* 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() (QtCanvas is not a subclass of QWidget),
    but all QtCanvasViews that are viewing the canvas will set their
    backgrounds to this color.

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

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

    \sa backgroundColor(), setBackgroundPixmap(), setTiles()
*/
void QtCanvas::setBackgroundColor(const QColor& c)
{
    if (bgcolor != c) {
        bgcolor = c;
        for (int i = 0; i < d->viewList.size(); ++i) {
            QtCanvasView *view = d->viewList.at(i);
            QPalette::ColorRole role = view->widget()->backgroundRole();
            QPalette viewPalette = view->widget()->palette();
            viewPalette.setColor(role, bgcolor);
            view->widget()->setPalette(viewPalette);
        }
        setAllChanged();
    }
}

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

    \sa setBackgroundPixmap(), backgroundColor()
*/
QPixmap QtCanvas::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 QtCanvas::setBackgroundPixmap(const QPixmap& p)
{
    setTiles(p, 1, 1, p.width(), p.height());
    for (int i = 0; i < d->viewList.size(); ++i) {
        QtCanvasView* view = d->viewList.at(i);
        view->widget()->update();
    }
}

/*
    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 QtCanvas::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 QtCanvas::drawForeground(QPainter& painter, const QRect& clip)
{
    if (debug_redraw_areas) {
        painter.setPen(red);
        painter.setBrush(NoBrush);
        painter.drawRect(clip);
    }
}

/*
    Sets the QtCanvas 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 QtCanvas::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 QtCanvas::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 QtCanvas::tilesHorizontally() const

    Returns the number of tiles horizontally.
*/

/*
    \fn int QtCanvas::tilesVertically() const

    Returns the number of tiles vertically.
*/

/*
    \fn int QtCanvas::tileWidth() const

    Returns the width of each tile.
*/

/*
    \fn int QtCanvas::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 QtCanvas::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 QtCanvasItemExtra {
    QtCanvasItemExtra() : vx(0.0), vy(0.0) { }
    double vx, vy;
    friend class QtCanvasItem;
};


/*
    \class QtCanvasItem qtcanvas.h
    \brief The QtCanvasItem class provides an abstract graphic object on a QtCanvas.

    A variety of QtCanvasItem 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.
    QtCanvasItem is not intended for direct subclassing. It is much easier
    to subclass one of its subclasses, e.g. QtCanvasPolygonalItem (the
    commonest base class), QtCanvasRectangle, QtCanvasSprite, QtCanvasEllipse
    or QtCanvasText.

    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 QtCanvas::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 QtCanvasItem 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 QtCanvasSprite or your own subclass of QtCanvasSprite 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 QtCanvasItem.
    The canvas() function returns a pointer to the canvas which contains the
    canvas item.

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

    QtCanvasItem 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
    QtCanvasItem 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.

*/

/*
    \enum QtCanvasItem::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 QtCanvasItem::update()

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

/*
    Constructs a QtCanvasItem on canvas \a canvas.

    \sa setCanvas()
*/
QtCanvasItem::QtCanvasItem(QtCanvas* 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 QtCanvasItem and removes it from its canvas.
*/
QtCanvasItem::~QtCanvasItem()
{
    if (cnv) {
        cnv->removeItem(this);
        cnv->removeAnimation(this);
    }
    delete ext;
}

QtCanvasItemExtra& QtCanvasItem::extra()
{
    if (!ext)
        ext = new QtCanvasItemExtra;
    return *ext;
}

/*
    \fn double QtCanvasItem::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 QtCanvasItem::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 QtCanvasItem::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 QtCanvasItem::setX(double x)

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

    \sa x(), move()
*/

/*
    \fn void QtCanvasItem::setY(double y)

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

    \sa y(), move()
*/

/*
    \fn void QtCanvasItem::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 QtCanvasItem::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 QtCanvasItem::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 QtCanvasItem::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(), QtCanvas::advance()
*/
void QtCanvasItem::setAnimated(bool y)
{
    if (y != (bool)ani) {
        ani = (uint)y;
        if (y) {
            cnv->addAnimation(this);
        } else {
            cnv->removeAnimation(this);
        }
    }
}

/*
    \fn void QtCanvasItem::setXVelocity(double vx)

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

    \sa setYVelocity() setVelocity()
*/

/*
    \fn void QtCanvasItem::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 QtCanvasItem::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 QtCanvasItem::xVelocity() const
{
    return ext ? ext->vx : 0;
}

/*
    Returns the vertical velocity component of the canvas item.
*/
double QtCanvasItem::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 QtCanvas::advance() setVelocity()
*/
void QtCanvasItem::advance(int phase)
{
    if (ext && phase == 1)
        moveBy(ext->vx, ext->vy);
}

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

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

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

    \sa canvas()
*/
void QtCanvasItem::setCanvas(QtCanvas* 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 QtCanvas* QtCanvasItem::canvas() const

    Returns the canvas containing the canvas item.
*/

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

/* Shorthand for setVisible(false). */
void QtCanvasItem::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 QtCanvas::update() is
    next called.
*/
void QtCanvasItem::setVisible(bool yes)
{
    if ((bool)vis!= yes) {
        if (yes) {
            vis = (uint)yes;
            addToChunks();
        } else {
            removeFromChunks();
            vis = (uint)yes;
        }
    }
}
/*
    \obsolete
    \fn bool QtCanvasItem::visible() const
    Use isVisible() instead.
*/

/*
    \fn bool QtCanvasItem::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 QtCanvasItem::selected() const
    Use isSelected() instead.
*/

/*
    \fn bool QtCanvasItem::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
    QtCanvas::update() is next called.

    The QtCanvas, QtCanvasItem and the Qt-supplied QtCanvasItem
    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 QtCanvasItem::setSelected(bool yes)
{
    if ((bool)sel!= yes) {
        sel = (uint)yes;
        changeChunks();
    }
}

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

/*
    \fn bool QtCanvasItem::isEnabled() const

    Returns true if the QtCanvasItem 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
    QtCanvas::update() is next called.

    The QtCanvas, QtCanvasItem and the Qt-supplied QtCanvasItem
    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 QtCanvasItem::setEnabled(bool yes)
{
    if (ena!= (uint)yes) {
        ena = (uint)yes;
        changeChunks();
    }
}

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

/*
    \fn bool QtCanvasItem::isActive() const

    Returns true if the QtCanvasItem 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
    QtCanvas::update() is next called.

    The QtCanvas, QtCanvasItem and the Qt-supplied QtCanvasItem
    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 QtCanvasItem::setActive(bool yes)
{
    if (act!= (uint)yes) {
        act = (uint)yes;
        changeChunks();
    }
}

bool qt_testCollision(const QtCanvasSprite* s1, const QtCanvasSprite* 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->format() == QImage::Format_MonoLSB) {
            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->format() == QImage::Format_MonoLSB) {
            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 QtCanvasSprite* s1,
                                       const QtCanvasPolygonalItem* p1,
                                       const QtCanvasRectangle* r1,
                                       const QtCanvasEllipse* e1,
                                       const QtCanvasText* t1,
                                       const QtCanvasSprite* s2,
                                       const QtCanvasPolygonalItem* p2,
                                       const QtCanvasRectangle* r2,
                                       const QtCanvasEllipse* e2,
                                       const QtCanvasText* t2)
{
    const QtCanvasItem* i1 = s1 ?
                            (const QtCanvasItem*)s1 : p1 ?
                            (const QtCanvasItem*)p1 : r1 ?
                            (const QtCanvasItem*)r1 : e1 ?
                            (const QtCanvasItem*)e1 : (const QtCanvasItem*)t1;
    const QtCanvasItem* i2 = s2 ?
                            (const QtCanvasItem*)s2 : p2 ?
                            (const QtCanvasItem*)p2 : r2 ?
                            (const QtCanvasItem*)r2 : e2 ?
                            (const QtCanvasItem*)e2 : (const QtCanvasItem*)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
        QPolygon pa1 = p1->areaPointsAdvanced();
        QPolygon pa2 = p2 ? p2->areaPointsAdvanced()
                          : QPolygon(i2->boundingRectAdvanced());
        bool col = !(QRegion(pa1) & QRegion(pa2, Qt::WindingFill)).isEmpty();

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

/*
    \fn bool QtCanvasItem::collidesWith(const QtCanvasItem* 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 QtCanvasSprite qtcanvas.h
    \brief The QtCanvasSprite class provides an animated canvas item on a QtCanvas.

    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 QtCanvasSprite you can change the frame that is displayed
    periodically, e.g. whenever QtCanvasItem::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.

    QtCanvasSprite 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 QtCanvasItem::move() and QtCanvasItem::moveBy(), or by
    setting coordinates with QtCanvasItem::setX(), QtCanvasItem::setY()
    and QtCanvasItem::setZ().

*/


/*
  \reimp
*/
bool QtCanvasSprite::collidesWith(const QtCanvasItem* 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 QtCanvasSprite::collidesWith(const QtCanvasSprite* s,
                                  const QtCanvasPolygonalItem* p,
                                  const QtCanvasRectangle* r,
                                  const QtCanvasEllipse* e,
                                  const QtCanvasText* t) const
{
    return collision_double_dispatch(s, p, r, e, t, this, 0, 0, 0, 0);
}

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

bool QtCanvasPolygonalItem::collidesWith(const QtCanvasSprite* s,
                                 const QtCanvasPolygonalItem* p,
                                 const QtCanvasRectangle* r,
                                 const QtCanvasEllipse* e,
                                 const QtCanvasText* t) const
{
    return collision_double_dispatch(s, p, r, e, t, 0, this, 0, 0, 0);
}

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

bool QtCanvasRectangle::collidesWith(const QtCanvasSprite* s,
                                 const QtCanvasPolygonalItem* p,
                                 const QtCanvasRectangle* r,
                                 const QtCanvasEllipse* e,
                                 const QtCanvasText* t) const
{
    return collision_double_dispatch(s, p, r, e, t, 0, this, this, 0, 0);
}


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

bool QtCanvasEllipse::collidesWith(const QtCanvasSprite* s,
                                 const QtCanvasPolygonalItem* p,
                                 const QtCanvasRectangle* r,
                                 const QtCanvasEllipse* e,
                                 const QtCanvasText* t) const
{
    return collision_double_dispatch(s, p, r, e, t, 0, this, 0, this, 0);
}

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

bool QtCanvasText::collidesWith(const QtCanvasSprite* s,
                                 const QtCanvasPolygonalItem* p,
                                 const QtCanvasRectangle* r,
                                 const QtCanvasEllipse* e,
                                 const QtCanvasText* 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 QtCanvasItems, 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.
*/
QtCanvasItemList QtCanvasItem::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).
*/
QtCanvasItemList QtCanvas::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).
*/
QtCanvasItemList QtCanvas::collisions(const QRect& r) const
{
    QtCanvasRectangle i(r, (QtCanvas*)this);
    i.setPen(NoPen);
    i.show(); // doesn't actually show, since we destroy it
    QtCanvasItemList l = i.collisions(true);
    qSort(l.begin(), l.end(), QtCanvasItemLess());
    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 QtCanvasItem::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
    QtCanvasItem::collisions() function.
*/
QtCanvasItemList QtCanvas::collisions(const QPolygon& chunklist, 
            const QtCanvasItem* item, bool exact) const
{
    QSet<QtCanvasItem *> seen;
    QtCanvasItemList 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 QtCanvasItemList &l = chunk(x, y).list();
            for (int i = 0; i < l.size(); ++i) {
                QtCanvasItem *g = l.at(i);
                if (g != item) {
                    if (!seen.contains(g)) {
                        seen.insert(g);
                        if (!exact || item->collidesWith(g))
                            result.append(g);
                    }
                }
            }
        }
    }
    return result;
}

/*
  \internal
  Adds the item to all the chunks it covers.
*/
void QtCanvasItem::addToChunks()
{
    if (isVisible() && canvas()) {
        QPolygon 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 QtCanvasItem::removeFromChunks()
{
    if (isVisible() && canvas()) {
        QPolygon 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 QtCanvas::update()
  is next called.
*/
void QtCanvasItem::changeChunks()
{
    if (isVisible() && canvas()) {
        if (!val)
            addToChunks();
        QPolygon pa = chunks();
        for (int i = 0; i < (int)pa.count(); i++)
            canvas()->setChangedChunk(pa[i].x(), pa[i].y());
    }
}

/*
    \fn QRect QtCanvasItem::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 QtCanvasItem::boundingRectAdvanced() const
{
    int dx = int(x()+xVelocity())-int(x());
    int dy = int(y()+yVelocity())-int(y());
    QRect r = boundingRect();
    r.translate(dx, dy);
    return r;
}

/*
    \class QtCanvasPixmap qtcanvas.h
    \brief The QtCanvasPixmap class provides pixmaps for QtCanvasSprites.

    If you want to show a single pixmap on a QtCanvas use a
    QtCanvasSprite with just one pixmap.

    When pixmaps are inserted into a QtCanvasPixmapArray they are held
    as QtCanvasPixmaps. \l{QtCanvasSprite}s are used to show pixmaps on
    \l{QtCanvas}es and hold their pixmaps in a QtCanvasPixmapArray. If
    you retrieve a frame (pixmap) from a QtCanvasSprite it will be
    returned as a QtCanvasPixmap.

    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).

    QtCanvasPixmap can have a hotspot which is defined in terms of an (x,
    y) offset. When you create a QtCanvasPixmap 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 QtCanvasPixmap is used
    in a QtCanvasSprite, the offset position is the point at
    QtCanvasItem::x() and QtCanvasItem::y(), not the top-left corner of
    the pixmap.

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

    \sa QtCanvasPixmapArray QtCanvasItem QtCanvasSprite
*/


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


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

void QtCanvasPixmap::init(const QImage& image)
{
    this->QPixmap::operator = (QPixmap::fromImage(image));
    hotx = image.offset().x();
    hoty = image.offset().y();
#ifndef QT_NO_IMAGE_DITHER_TO_1
    if(image.hasAlphaChannel()) {
        QImage i = image.createAlphaMask();
        collision_mask = new QImage(i);
    } else
#endif
        collision_mask = 0;
}

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

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

/*
    \fn int QtCanvasPixmap::offsetX() const

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

    \sa setOffset()
*/

/*
    \fn int QtCanvasPixmap::offsetY() const

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

    \sa setOffset()
*/

/*
    \fn void QtCanvasPixmap::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 QtCanvasSprites are
    currently showing this pixmap.
*/

/*
    \class QtCanvasPixmapArray qtcanvas.h
    \brief The QtCanvasPixmapArray class provides an array of QtCanvasPixmaps.

    This class is used by QtCanvasSprite 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().

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

*/

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

/*
    Constructs a QtCanvasPixmapArray 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.
*/

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

/*
  \obsolete
  Use QtCanvasPixmapArray::QtCanvasPixmapArray(QtValueList<QPixmap>, QPolygon)
  instead.

  Constructs a QtCanvasPixmapArray from the list of QPixmaps \a
  list. The \a hotspots list has to be of the same size as \a list.
*/
QtCanvasPixmapArray::QtCanvasPixmapArray(const QList<QPixmap> &list, const QPolygon &hotspots)
    : framecount(list.count()),
      img(new QtCanvasPixmap*[list.count()])
{
    if (list.count() != hotspots.count()) {
        qWarning("QtCanvasPixmapArray: lists have different lengths");
        reset();
        img = 0;
    } else {
        for (int i = 0; i < framecount; i++)
            img[i] = new QtCanvasPixmap(list.at(i), hotspots.at(i));
    }
}


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

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

/*
    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 QtCanvasPixmapArray::readPixmaps(const QString& filenamepattern,
                                      int fc)
{
    return readPixmaps(filenamepattern, fc, false);
}

/*
    Reads new collision masks for the array.

    By default, QtCanvasSprite 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 QtCanvasPixmapArray::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 QtCanvasPixmapArray::readCollisionMasks(const QString& filename)
{
    return readPixmaps(filename, framecount, true);
}


bool QtCanvasPixmapArray::readPixmaps(const QString& datafilenamepattern,
                                      int fc, bool maskonly)
{
    if (!maskonly) {
        reset();
        framecount = fc;
        if (!framecount)
            framecount = 1;
        img = new QtCanvasPixmap*[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 QtCanvasPixmap(
                arg ? datafilenamepattern.arg(r) : datafilenamepattern);
            ok = ok && !img[i]->isNull();
        }
    }
    if (!ok) {
        reset();
    }
    return ok;
}

/*
  \obsolete

  Use isValid() instead.

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

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

/*
    \fn QtCanvasPixmap* QtCanvasPixmapArray::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 QtCanvasPixmaps 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 QtCanvasPixmapArray::setImage(int i, QtCanvasPixmap* p)
{
    if (i >= framecount) {
        QtCanvasPixmap** newimg = new QtCanvasPixmap*[i+1];
        memcpy(newimg, img, sizeof(QtCanvasPixmap *)*framecount);
        memset(newimg + framecount, 0, sizeof(QtCanvasPixmap *)*(i+1 - framecount));
        framecount = i+1;
        delete [] img;
        img = newimg;
    }
    delete img[i]; img[i] = p;
}

/*
    \fn uint QtCanvasPixmapArray::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 QtCanvasSprite::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 QtCanvasSprite::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 QtCanvasSprite::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 QtCanvasSprite::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 QtCanvasSprite::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 QtCanvasSprite::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 QtCanvasSprite::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 QtCanvasSprite::bottomEdge(int ny) const
{
    return topEdge(ny) + image()->height()-1;
}

/*
    \fn QtCanvasPixmap* QtCanvasSprite::image() const

    Returns the current frame's image.

    \sa frame(), setFrame()
*/

/*
    \fn QtCanvasPixmap* QtCanvasSprite::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().
*/
QtCanvasPixmap* QtCanvasSprite::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 QtCanvasSprite::boundingRect() const
{
    return QRect(leftEdge(), topEdge(), width(), height());
}


/*
  \internal
  Returns the chunks covered by the item.
*/
QPolygon QtCanvasItem::chunks() const
{
    QPolygon 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 QtCanvas which it overlaps.
*/
void QtCanvasSprite::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 QtCanvas which it overlaps.

  \sa addToChunks()
*/
void QtCanvasSprite::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 QtCanvasSprite::width() const
{
    return image()->width();
}

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

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


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

/*
    \class QtCanvasView qtcanvas.h
    \brief The QtCanvasView class provides an on-screen view of a QtCanvas.

    A QtCanvasView is widget which provides a view of a QtCanvas.

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

    \code
    void MyCanvasView::contentsMousePressEvent(QMouseEvent* e)
    {
        QtCanvasItemList l = canvas()->collisions(e->pos());
        for (QtCanvasItemList::Iterator it = l.begin(); it!= l.end(); ++it) {
            if ((*it)->rtti() == QtCanvasRectangle::RTTI)
                qDebug("A QtCanvasRectangle lies somewhere at this point");
        }
    }
    \endcode

    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:

    \code
    QMatrix wm;
    wm.scale(2, 2);   // Zooms in by 2 times
    wm.rotate(90);    // Rotates 90 degrees counter clockwise
                        // around the origin.
    wm.translate(0, -canvas->height());
                        // moves the canvas down so what was visible
                        // before is still visible.
    myCanvasView->setWorldMatrix(wm);
    \endcode

    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.

    \code
    QRect rc = QRect(myCanvasView->contentsX(), myCanvasView->contentsY(),
                        myCanvasView->visibleWidth(), myCanvasView->visibleHeight());
    QRect canvasRect = myCanvasView->inverseWorldMatrix().mapRect(rc);
    \endcode

    \sa QMatrix QPainter::setWorldMatrix()

*/

class QtCanvasWidget : public QWidget
{
public:
    QtCanvasWidget(QtCanvasView *view) : QWidget(view) { m_view = view; }
protected:
    void paintEvent(QPaintEvent *e);
    void mousePressEvent(QMouseEvent *e) {
        m_view->contentsMousePressEvent(e);
    }
    void mouseMoveEvent(QMouseEvent *e) {
        m_view->contentsMouseMoveEvent(e);
    }
    void mouseReleaseEvent(QMouseEvent *e) {
        m_view->contentsMouseReleaseEvent(e);
    }
    void mouseDoubleClickEvent(QMouseEvent *e) {
        m_view->contentsMouseDoubleClickEvent(e);
    }
    void dragEnterEvent(QDragEnterEvent *e) {
        m_view->contentsDragEnterEvent(e);
    }
    void dragMoveEvent(QDragMoveEvent *e) {
        m_view->contentsDragMoveEvent(e);
    }
    void dragLeaveEvent(QDragLeaveEvent *e) {
        m_view->contentsDragLeaveEvent(e);
    }
    void dropEvent(QDropEvent *e) {
        m_view->contentsDropEvent(e);
    }
    void wheelEvent(QWheelEvent *e) {
        m_view->contentsWheelEvent(e);
    }
    void contextMenuEvent(QContextMenuEvent *e) {
        m_view->contentsContextMenuEvent(e);
    }

    QtCanvasView *m_view;
};

void QtCanvasWidget::paintEvent(QPaintEvent *e)
{
    QPainter p(this);
    if (m_view->d->highQuality) {
        p.setRenderHint(QPainter::Antialiasing);
        p.setRenderHint(QPainter::SmoothPixmapTransform);
    }
    m_view->drawContents(&p, e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
}

/*
    Constructs a QtCanvasView with parent \a parent. The canvas view
    is not associated with a canvas, so you must to call setCanvas()
    to view a canvas.
*/
QtCanvasView::QtCanvasView(QWidget* parent)
    : QScrollArea(parent)
{
    d = new QtCanvasViewData;
    setWidget(new QtCanvasWidget(this));
    d->highQuality = false;
    viewing = 0;
    setCanvas(0);
}

/*
    \overload

    Constructs a QtCanvasView which views canvas \a canvas, with parent
    \a parent.
*/
QtCanvasView::QtCanvasView(QtCanvas* canvas, QWidget* parent)
    : QScrollArea(parent)
{
    d = new QtCanvasViewData;
    d->highQuality = false;
    setWidget(new QtCanvasWidget(this));
    viewing = 0;
    setCanvas(canvas);
}

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

/*
    \property QtCanvasView::highQualityRendering
    \brief whether high quality rendering is turned on

    If high quality rendering is turned on, the canvas view will paint itself
    using the QPainter::Antialiasing and QPainter::SmoothPixmapTransform
    rendering flags.

    Enabling these flag will usually improve the visual appearance on the screen
    at the cost of rendering speed.
*/
bool QtCanvasView::highQualityRendering() const
{
    return d->highQuality;
}

void QtCanvasView::setHighQualityRendering(bool enable)
{
    d->highQuality = enable;
    widget()->update();
}


void QtCanvasView::contentsMousePressEvent(QMouseEvent *e)
{
    e->ignore();
}

void QtCanvasView::contentsMouseReleaseEvent(QMouseEvent *e)
{
    e->ignore();
}

void QtCanvasView::contentsMouseDoubleClickEvent(QMouseEvent *e)
{
    e->ignore();
}

void QtCanvasView::contentsMouseMoveEvent(QMouseEvent *e)
{
    e->ignore();
}

void QtCanvasView::contentsDragEnterEvent(QDragEnterEvent *)
{
}

void QtCanvasView::contentsDragMoveEvent(QDragMoveEvent *)
{
}

void QtCanvasView::contentsDragLeaveEvent(QDragLeaveEvent *)
{
}

void QtCanvasView::contentsDropEvent(QDropEvent *)
{
}

void QtCanvasView::contentsWheelEvent(QWheelEvent *e)
{
    e->ignore();
}

void QtCanvasView::contentsContextMenuEvent(QContextMenuEvent *e)
{
    e->ignore();
}

/*
    \fn QtCanvas* QtCanvasView::canvas() const

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


/*
    Sets the canvas that the QtCanvasView is showing to the canvas \a
    canvas.
*/
void QtCanvasView::setCanvas(QtCanvas* 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);
    }
    if (d) // called by d'tor
        updateContentsSize();
    update();
}

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

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

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

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

/*
    Sets the transformation matrix of the QtCanvasView 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
    QtCanvasView will decrease considerably.

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

    \sa worldMatrix() inverseWorldMatrix() QMatrix::isInvertible()
*/
bool QtCanvasView::setWorldMatrix(const QMatrix & wm)
{
    bool ok = wm.isInvertible();
    if (ok) {
        d->xform = wm;
        d->ixform = wm.inverted();
        updateContentsSize();
        widget()->update();
    }
    return ok;
}

void QtCanvasView::updateContentsSize()
{
    if (viewing) {
        QRect br;
        br = d->xform.mapRect(QRect(0, 0, viewing->width(), viewing->height()));

        widget()->resize(br.size());
    } else {
        widget()->resize(size());
    }
}

/*
    Repaints part of the QtCanvas 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 QtCanvasView::drawContents(QPainter *p, int cx, int cy, int cw, int ch)
{
    if (!viewing)
        return;
    QPainterPath clipPath;
    clipPath.addRect(viewing->rect());
    p->setClipPath(d->xform.map(clipPath), Qt::IntersectClip);
    viewing->drawViewArea(this, p, QRect(cx, cy, cw, ch), false);
}

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

/*
    \class QtCanvasPolygonalItem qtcanvas.h
    \brief The QtCanvasPolygonalItem class provides a polygonal canvas item
    on a QtCanvas.

    The mostly rectangular classes, such as QtCanvasSprite and
    QtCanvasText, 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.
    QtCanvasPolygonalItem 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 QtCanvasPolygonalItem's speed.

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

    Normally, QtCanvasPolygonalItem 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
    QtCanvasItem::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, QtCanvasPolygonalItem 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
    QtCanvasPolygonalItem 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
    QtCanvasItem::move() and QtCanvasItem::moveBy(), or by setting coordinates
    with QtCanvasItem::setX(), QtCanvasItem::setY() and QtCanvasItem::setZ().

*/


/*
  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 QtCanvasPolygonalItem on the canvas \a canvas.
*/
QtCanvasPolygonalItem::QtCanvasPolygonalItem(QtCanvas* canvas) :
    QtCanvasItem(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().
*/
QtCanvasPolygonalItem::~QtCanvasPolygonalItem()
{
}

/*
    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 QtCanvasPolygonalItem::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 QtCanvasPolygonalItem::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 QtCanvasPolygonalItem::invalidate()
{
    val = (uint)false;
    removeFromChunks();
}

/*
    \fn QtCanvasPolygonalItem::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
    QtCanvasItem::advance(1) is called, i.e. what the points are when
    advanced by the current xVelocity() and yVelocity().
*/
QPolygon QtCanvasPolygonalItem::areaPointsAdvanced() const
{
    int dx = int(x()+xVelocity())-int(x());
    int dy = int(y()+yVelocity())-int(y());
    QPolygon 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(QtCanvas* c, const QPolygon& 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(), bounds.height(), QImage::Format_MonoLSB);
        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;
    QPolygon result;
    QtCanvas* canvas;
    QRect bounds;
    QImage bitmap;
};


QPolygon QtCanvasPolygonalItem::chunks() const
{
    QPolygon 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 QtCanvasItem::chunks().
*/
QPolygon QtCanvasRectangle::chunks() const
{
    // No need to do a polygon scan!
    return QtCanvasItem::chunks();
}

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

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

/*
    \fn void QtCanvasPolygonalItem::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 QtCanvasPolygonalItem::pen() const

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

    \sa setPen()
*/

/*
    \fn QBrush QtCanvasPolygonalItem::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 QtCanvasPolygonalItems do not use the pen value.

    \sa setBrush(), pen(), drawShape()
*/
void QtCanvasPolygonalItem::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 QtCanvasPolygonalItem::setBrush(QBrush b)
{
    if (br != b) {
        br = b;
        changeChunks();
    }
}


/*
    \class QtCanvasPolygon qtcanvas.h
    \brief The QtCanvasPolygon class provides a polygon on a QtCanvas.

    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
    QtCanvasItem::move() and QtCanvasItem::moveBy(), or by setting
    coordinates with QtCanvasItem::setX(), QtCanvasItem::setY() and
    QtCanvasItem::setZ().

    Note: QtCanvasPolygon does not use the pen.
*/

/*
    Constructs a point-less polygon on the canvas \a canvas. You
    should call setPoints() before using it further.
*/
QtCanvasPolygon::QtCanvasPolygon(QtCanvas* canvas) :
    QtCanvasPolygonalItem(canvas)
{
}

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

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

    Note that QtCanvasPolygon does not support an outline (the pen is
    always NoPen).
*/
void QtCanvasPolygon::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(QPolygon) 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 QtCanvasPolygon::setPoints(QPolygon pa)
{
    removeFromChunks();
    poly = pa;
    poly.detach(); // Explicit sharing is stupid.
    poly.translate((int)x(), (int)y());
    addToChunks();
}

/*
  \reimp
*/
void QtCanvasPolygon::moveBy(double dx, double dy)
{
    // Note: does NOT call QtCanvasPolygonalItem::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 QtCanvasSpline qtcanvas.h
    \brief The QtCanvasSpline class provides multi-bezier splines on a QtCanvas.

    A QtCanvasSpline 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
    QtCanvasItem::move() and QtCanvasItem::moveBy(), or by setting
    coordinates with QtCanvasItem::setX(), QtCanvasItem::setY() and
    QtCanvasItem::setZ().

*/

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

    \sa setControlPoints()
*/
QtCanvasSpline::QtCanvasSpline(QtCanvas* canvas) :
    QtCanvasPolygon(canvas), 
    cl(true)
{
}

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

/*
    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 QtCanvasSpline::setControlPoints(QPolygon ctrl, bool close)
{
    if ((int)ctrl.count() % 3 != (close ? 0 : 1)) {
        qWarning("QtCanvasSpline::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()
*/
QPolygon QtCanvasSpline::controlPoints() const
{
    return bez;
}

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

void QtCanvasSpline::recalcPoly()
{
    if (bez.count() == 0)
        return;

    QPainterPath path;
    path.moveTo(bez[0]);
    for (int i = 1; i < (int)bez.count()-1; i+= 3) {
        path.cubicTo(bez[i], bez[i+1], cl ? bez[(i+2)%bez.size()] : bez[i+2]);
    }
    QPolygon p = path.toFillPolygon().toPolygon();
    QtCanvasPolygon::setPoints(p);
}

/*
    \fn QPolygon QtCanvasPolygonalItem::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 QPolygon QtCanvasPolygon::points() const

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

    \sa setPoints(), areaPoints()
*/
QPolygon QtCanvasPolygon::points() const
{
    QPolygon 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()
*/
QPolygon QtCanvasPolygon::areaPoints() const
{
    return poly;
}

/*
    \class QtCanvasLine qtcanvas.h
    \brief The QtCanvasLine class provides a line on a QtCanvas.

    The line inherits functionality from QtCanvasPolygonalItem, 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
    QtCanvasItem::move() and QtCanvasItem::moveBy(), or by setting
    coordinates with QtCanvasItem::setX(), QtCanvasItem::setY() and
    QtCanvasItem::setZ().
*/

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

    \sa setPoints()
*/
QtCanvasLine::QtCanvasLine(QtCanvas* canvas) :
    QtCanvasPolygonalItem(canvas)
{
    x1 = y1 = x2 = y2 = 0;
}

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

/*
  \reimp
*/
void QtCanvasLine::setPen(QPen p)
{
    QtCanvasPolygonalItem::setPen(p);
}

/*
    \fn QPoint QtCanvasLine::startPoint () const

    Returns the start point of the line.

    \sa setPoints(), endPoint()
*/

/*
    \fn QPoint QtCanvasLine::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 QtCanvasLine::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 QtCanvasLine::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.
*/
QPolygon QtCanvasLine::areaPoints() const
{
    QPolygon 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 QtCanvasLine::moveBy(double dx, double dy)
{
    QtCanvasPolygonalItem::moveBy(dx, dy);
}

/*
    \class QtCanvasRectangle qtcanvas.h
    \brief The QtCanvasRectangle class provides a rectangle on a QtCanvas.

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

    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
    QtCanvasItem::move() and QtCanvasItem::moveBy(), or by setting
    coordinates with QtCanvasItem::setX(), QtCanvasItem::setY() and
    QtCanvasItem::setZ().

*/

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

/*
    Constructs a rectangle positioned and sized by \a r on \a canvas.
*/
QtCanvasRectangle::QtCanvasRectangle(const QRect& r, QtCanvas* canvas) :
    QtCanvasPolygonalItem(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.
*/
QtCanvasRectangle::QtCanvasRectangle(int x, int y, int width, int height,
        QtCanvas* canvas) :
    QtCanvasPolygonalItem(canvas),
    w(width), h(height)
{
    move(x, y);
}

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


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

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

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

/*
    \fn QSize QtCanvasRectangle::size() const

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

    \sa rect(), setSize()
*/

/*
    \fn QRect QtCanvasRectangle::rect() const

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

/*
  \reimp
*/
QPolygon QtCanvasRectangle::areaPoints() const
{
    QPolygon 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 QtCanvasRectangle::drawShape(QPainter & p)
{
    p.drawRect((int)x(), (int)y(), w, h);
}


/*
    \class QtCanvasEllipse qtcanvas.h
    \brief The QtCanvasEllipse class provides an ellipse or ellipse segment on a QtCanvas.

    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: QtCanvasEllipse does not use the pen.
*/

/*
    Constructs a 32x32 ellipse, centered at (0, 0) on \a canvas.
*/
QtCanvasEllipse::QtCanvasEllipse(QtCanvas* canvas) :
    QtCanvasPolygonalItem(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.
*/
QtCanvasEllipse::QtCanvasEllipse(int width, int height, QtCanvas* canvas) :
    QtCanvasPolygonalItem(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 QtCanvas does too for consistency. If it's
// ###  a good idea, it should be added to QPainter, not just to QtCanvas. 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.
*/
QtCanvasEllipse::QtCanvasEllipse(int width, int height, 
    int startangle, int angle, QtCanvas* canvas) :
    QtCanvasPolygonalItem(canvas), 
    w(width), h(height), 
    a1(startangle), a2(angle)
{
}

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

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

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

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

/*
    \fn int QtCanvasEllipse::angleStart() const

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

    \sa setAngles(), angleLength()
*/

/*
    \fn int QtCanvasEllipse::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 QtCanvasEllipse::setAngles(int start, int length)
{
    if (a1 != start || a2 != length) {
        removeFromChunks();
        a1 = start;
        a2 = length;
        addToChunks();
    }
}

/*
  \reimp
*/
QPolygon QtCanvasEllipse::areaPoints() const
{
    QPainterPath path;
    path.arcTo(QRectF(x()-w/2.0+0.5-1, y()-h/2.0+0.5-1, w+3, h+3), a1/16., a2/16.);
    return path.toFillPolygon().toPolygon();
}

/*
    Draws the ellipse, centered at x(), y() using the painter \a p.

    Note that QtCanvasEllipse does not support an outline (the pen is
    always NoPen).
*/
void QtCanvasEllipse::drawShape(QPainter & p)
{
    p.setPen(NoPen); // since QRegion(QPolygon) 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 QtCanvasText
    \brief The QtCanvasText class provides a text object on a QtCanvas.

    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
    QtCanvasItem::move() and QtCanvasItem::moveBy(), or by setting
    coordinates with QtCanvasItem::setX(), QtCanvasItem::setY() and
    QtCanvasItem::setZ().
*/

/*
    Constructs a QtCanvasText with the text "\<text\>", on \a canvas.
*/
QtCanvasText::QtCanvasText(QtCanvas* canvas) :
    QtCanvasItem(canvas), 
    txt("<text>"), flags(0)
{
    setRect();
}

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

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

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

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

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

/*
    \fn int QtCanvasText::textFlags() const

    Returns the currently set alignment flags.

    \sa setTextFlags() Qt::AlignmentFlag Qt::TextFlag
*/


/*
    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 and \l{Qt::TextFlag}s.

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

/*
    Returns the text item's text.

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


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

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

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

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

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

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

/*
    Returns the color of the text.

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

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

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


/*
  \reimp
*/
void QtCanvasText::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.translate(idx, idy);
        addToChunks();
    }
}

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

/*
  \reimp
*/
void QtCanvasText::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 QtCanvasText::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 QtCanvasText::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 (QtCanvasItem::Rtti_Item).

    Make your derived classes return their own values for rtti(), so
    that you can distinguish between objects returned by
    QtCanvas::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 QtCanvasItem
    found by QtCanvas::at(), cast it to that type and call meaningful
    methods rather than acting upon the object based on its rtti
    value.

    For example:

    \code
        QtCanvasItem* item;
        // Find an item, e.g. with QtCanvasItem::collisions().
        ...
        if (item->rtti() == MySprite::RTTI) {
            MySprite* s = (MySprite*)item;
            if (s->isDamagable()) s->loseHitPoints(1000);
            if (s->isHot()) myself->loseHitPoints(1000);
            ...
        }
    \endcode
*/
int QtCanvasItem::rtti() const { return RTTI; }
int QtCanvasItem::RTTI = Rtti_Item;

/*
    Returns 1 (QtCanvasItem::Rtti_Sprite).

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

/*
    Returns 2 (QtCanvasItem::Rtti_PolygonalItem).

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

/*
    Returns 3 (QtCanvasItem::Rtti_Text).

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

/*
    Returns 4 (QtCanvasItem::Rtti_Polygon).

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

/*
    Returns 5 (QtCanvasItem::Rtti_Rectangle).

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

/*
    Returns 6 (QtCanvasItem::Rtti_Ellipse).

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

/*
    Returns 7 (QtCanvasItem::Rtti_Line).

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

/*
    Returns 8 (QtCanvasItem::Rtti_Spline).

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

/*
    Constructs a QtCanvasSprite which uses images from the
    QtCanvasPixmapArray \a a.

    The sprite in initially positioned at (0, 0) on \a canvas, using
    frame 0.
*/
QtCanvasSprite::QtCanvasSprite(QtCanvasPixmapArray* a, QtCanvas* canvas) :
    QtCanvasItem(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
    QtCanvasPixmapArray \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 QtCanvasSprite::setSequence(QtCanvasPixmapArray* 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 QtCanvasSprite::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.
*/
QtCanvasSprite::~QtCanvasSprite()
{
    removeFromChunks();
}

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

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

/*
    \enum QtCanvasSprite::FrameAnimationType

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

    \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 QtCanvasSprite::setFrameAnimation(FrameAnimationType type, int step, int state)
{
    anim_val = step;
    anim_type = type;
    anim_state = state;
    setAnimated(true);
}

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

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

    \sa QtCanvasItem::advance() setVelocity()
*/
void QtCanvasSprite::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 QtCanvasSprite::frame() const

    Returns the index of the current animation frame in the
    QtCanvasSprite's QtCanvasPixmapArray.

    \sa setFrame(), move()
*/

/*
    \fn int QtCanvasSprite::frameCount() const

    Returns the number of frames in the QtCanvasSprite's
    QtCanvasPixmapArray.
*/


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

/*
    \fn void QtCanvasSprite::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 QtCanvasSprite::move(double nx, double ny, int nf)
{
    if (isVisible() && canvas()) {
        hide();
        QtCanvasItem::move(nx, ny);
        if (nf >= 0 && nf < frameCount())
            frm = nf;
        show();
    } else {
        QtCanvasItem::move(nx, ny);
        if (nf >= 0 && nf < frameCount())
            frm = nf;
    }
}


class QPoint;

class QtPolygonScanner {
public:
    virtual ~QtPolygonScanner() {}
    void scan(const QPolygon& pa, bool winding, int index = 0, int npoints = -1);
    void scan(const QPolygon& pa, bool winding, int index, int npoints, bool stitchable);
    enum Edge { Left = 1, Right = 2, Top = 4, Bottom = 8 };
    void scan(const QPolygon& pa, bool winding, int index, int npoints, Edge edges);
    virtual void processSpans(int n, QPoint* point, int* width) = 0;
};


// Based on Xserver code miFillGeneralPoly...
/*
 *
 *     Written by Brian Kelleher;  Oct. 1985
 *
 *     Routine to fill a polygon.  Two fill rules are
 *     supported: frWINDING and frEVENODD.
 *
 *     See fillpoly.h for a complete description of the algorithm.
 */

/*
 *     These are the data structures needed to scan
 *     convert regions.  Two different scan conversion
 *     methods are available -- the even-odd method, and
 *     the winding number method.
 *     The even-odd rule states that a point is inside
 *     the polygon if a ray drawn from that point in any
 *     direction will pass through an odd number of
 *     path segments.
 *     By the winding number rule, a point is decided
 *     to be inside the polygon if a ray drawn from that
 *     point in any direction passes through a different
 *     number of clockwise and counterclockwise path
 *     segments.
 *
 *     These data structures are adapted somewhat from
 *     the algorithm in (Foley/Van Dam) for scan converting
 *     polygons.
 *     The basic algorithm is to start at the top (smallest y)
 *     of the polygon, stepping down to the bottom of
 *     the polygon by incrementing the y coordinate.  We
 *     keep a list of edges which the current scanline crosses, 
 *     sorted by x.  This list is called the Active Edge Table (AET)
 *     As we change the y-coordinate, we update each entry in
 *     in the active edge table to reflect the edges new xcoord.
 *     This list must be sorted at each scanline in case
 *     two edges intersect.
 *     We also keep a data structure known as the Edge Table (ET), 
 *     which keeps track of all the edges which the current
 *     scanline has not yet reached.  The ET is basically a
 *     list of ScanLineList structures containing a list of
 *     edges which are entered at a given scanline.  There is one
 *     ScanLineList per scanline at which an edge is entered.
 *     When we enter a new edge, we move it from the ET to the AET.
 *
 *     From the AET, we can implement the even-odd rule as in
 *     (Foley/Van Dam).
 *     The winding number rule is a little trickier.  We also
 *     keep the EdgeTableEntries in the AET linked by the
 *     nextWETE (winding EdgeTableEntry) link.  This allows
 *     the edges to be linked just as before for updating
 *     purposes, but only uses the edges linked by the nextWETE
 *     link as edges representing spans of the polygon to
 *     drawn (as with the even-odd rule).
 */

/* $XConsortium: miscanfill.h, v 1.5 94/04/17 20:27:50 dpw Exp $ */
/*

Copyright (c) 1987  X Consortium

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, 
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the X Consortium.

*/


/*
 *     scanfill.h
 *
 *     Written by Brian Kelleher; Jan 1985
 *
 *     This file contains a few macros to help track
 *     the edge of a filled object.  The object is assumed
 *     to be filled in scanline order, and thus the
 *     algorithm used is an extension of Bresenham's line
 *     drawing algorithm which assumes that y is always the
 *     major axis.
 *     Since these pieces of code are the same for any filled shape, 
 *     it is more convenient to gather the library in one
 *     place, but since these pieces of code are also in
 *     the inner loops of output primitives, procedure call
 *     overhead is out of the question.
 *     See the author for a derivation if needed.
 */

/*
 *  In scan converting polygons, we want to choose those pixels
 *  which are inside the polygon.  Thus, we add .5 to the starting
 *  x coordinate for both left and right edges.  Now we choose the
 *  first pixel which is inside the pgon for the left edge and the
 *  first pixel which is outside the pgon for the right edge.
 *  Draw the left pixel, but not the right.
 *
 *  How to add .5 to the starting x coordinate:
 *      If the edge is moving to the right, then subtract dy from the
 *  error term from the general form of the algorithm.
 *      If the edge is moving to the left, then add dy to the error term.
 *
 *  The reason for the difference between edges moving to the left
 *  and edges moving to the right is simple:  If an edge is moving
 *  to the right, then we want the algorithm to flip immediately.
 *  If it is moving to the left, then we don't want it to flip until
 *  we traverse an entire pixel.
 */
#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
    int dx;      /* local storage */ \
\
    /* \
     *  if the edge is horizontal, then it is ignored \
     *  and assumed not to be processed.  Otherwise, do this stuff. \
     */ \
    if ((dy) != 0) { \
        xStart = (x1); \
        dx = (x2) - xStart; \
        if (dx < 0) { \
            m = dx / (dy); \
            m1 = m - 1; \
            incr1 = -2 * dx + 2 * (dy) * m1; \
            incr2 = -2 * dx + 2 * (dy) * m; \
            d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
        } else { \
            m = dx / (dy); \
            m1 = m + 1; \
            incr1 = 2 * dx - 2 * (dy) * m1; \
            incr2 = 2 * dx - 2 * (dy) * m; \
            d = -2 * m * (dy) + 2 * dx; \
        } \
    } \
}

#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
    if (m1 > 0) { \
        if (d > 0) { \
            minval += m1; \
            d += incr1; \
        } \
        else { \
            minval += m; \
            d += incr2; \
        } \
    } else {\
        if (d >= 0) { \
            minval += m1; \
            d += incr1; \
        } \
        else { \
            minval += m; \
            d += incr2; \
        } \
    } \
}


/*
 *     This structure contains all of the information needed
 *     to run the bresenham algorithm.
 *     The variables may be hardcoded into the declarations
 *     instead of using this structure to make use of
 *     register declarations.
 */
typedef struct {
    int minor;         /* minor axis        */
    int d;           /* decision variable */
    int m, m1;       /* slope and slope+1 */
    int incr1, incr2; /* error increments */
} BRESINFO;


#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
        BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, \
                     bres.m, bres.m1, bres.incr1, bres.incr2)

#define BRESINCRPGONSTRUCT(bres) \
        BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)


typedef struct _EdgeTableEntry {
     int ymax;             /* ycoord at which we exit this edge. */
     BRESINFO bres;        /* Bresenham info to run the edge     */
     struct _EdgeTableEntry *next;       /* next in the list     */
     struct _EdgeTableEntry *back;       /* for insertion sort   */
     struct _EdgeTableEntry *nextWETE;   /* for winding num rule */
     int ClockWise;        /* flag for winding number rule       */
} EdgeTableEntry;


typedef struct _ScanLineList{
     int scanline;              /* the scanline represented */
     EdgeTableEntry *edgelist;  /* header node              */
     struct _ScanLineList *next;  /* next in the list       */
} ScanLineList;


typedef struct {
     int ymax;                 /* ymax for the polygon     */
     int ymin;                 /* ymin for the polygon     */
     ScanLineList scanlines;   /* header node              */
} EdgeTable;


/*
 * Here is a struct to help with storage allocation
 * so we can allocate a big chunk at a time, and then take
 * pieces from this heap when we need to.
 */
#define SLLSPERBLOCK 25

typedef struct _ScanLineListBlock {
     ScanLineList SLLs[SLLSPERBLOCK];
     struct _ScanLineListBlock *next;
} ScanLineListBlock;

/*
 * number of points to buffer before sending them off
 * to scanlines() :  Must be an even number
 */
#define NUMPTSTOBUFFER 200

/*
 *
 *     a few macros for the inner loops of the fill code where
 *     performance considerations don't allow a procedure call.
 *
 *     Evaluate the given edge at the given scanline.
 *     If the edge has expired, then we leave it and fix up
 *     the active edge table; otherwise, we increment the
 *     x value to be ready for the next scanline.
 *     The winding number rule is in effect, so we must notify
 *     the caller when the edge has been removed so he
 *     can reorder the Winding Active Edge Table.
 */
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
   if (pAET->ymax == y) {          /* leaving this edge */ \
      pPrevAET->next = pAET->next; \
      pAET = pPrevAET->next; \
      fixWAET = 1; \
      if (pAET) \
         pAET->back = pPrevAET; \
   } \
   else { \
      BRESINCRPGONSTRUCT(pAET->bres); \
      pPrevAET = pAET; \
      pAET = pAET->next; \
   } \
}


/*
 *     Evaluate the given edge at the given scanline.
 *     If the edge has expired, then we leave it and fix up
 *     the active edge table; otherwise, we increment the
 *     x value to be ready for the next scanline.
 *     The even-odd rule is in effect.
 */
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
   if (pAET->ymax == y) {          /* leaving this edge */ \
      pPrevAET->next = pAET->next; \
      pAET = pPrevAET->next; \
      if (pAET) \
         pAET->back = pPrevAET; \
   } \
   else { \
      BRESINCRPGONSTRUCT(pAET->bres) \
      pPrevAET = pAET; \
      pAET = pAET->next; \
   } \
}

/***********************************************************

Copyright (c) 1987  X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the X Consortium.


Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

#define MAXINT 0x7fffffff
#define MININT -MAXINT

/*
 *     fillUtils.c
 *
 *     Written by Brian Kelleher;  Oct. 1985
 *
 *     This module contains all of the utility functions
 *     needed to scan convert a polygon.
 *
 */
/*
 *     InsertEdgeInET
 *
 *     Insert the given edge into the edge table.
 *     First we must find the correct bucket in the
 *     Edge table, then find the right slot in the
 *     bucket.  Finally, we can insert it.
 *
 */
static bool
miInsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, 
        int scanline, ScanLineListBlock **SLLBlock, int *iSLLBlock)
{
    register EdgeTableEntry *start, *prev;
    register ScanLineList *pSLL, *pPrevSLL;
    ScanLineListBlock *tmpSLLBlock;

    /*
     * find the right bucket to put the edge into
     */
    pPrevSLL = &ET->scanlines;
    pSLL = pPrevSLL->next;
    while (pSLL && (pSLL->scanline < scanline))
    {
        pPrevSLL = pSLL;
        pSLL = pSLL->next;
    }

    /*
     * reassign pSLL (pointer to ScanLineList) if necessary
     */
    if ((!pSLL) || (pSLL->scanline > scanline))
    {
        if (*iSLLBlock > SLLSPERBLOCK-1)
        {
            tmpSLLBlock = 
                  (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
            if (!tmpSLLBlock)
                return false;
            (*SLLBlock)->next = tmpSLLBlock;
            tmpSLLBlock->next = 0;
            *SLLBlock = tmpSLLBlock;
            *iSLLBlock = 0;
        }
        pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);

        pSLL->next = pPrevSLL->next;
        pSLL->edgelist = 0;
        pPrevSLL->next = pSLL;
    }
    pSLL->scanline = scanline;

    /*
     * now insert the edge in the right bucket
     */
    prev = 0;
    start = pSLL->edgelist;
    while (start && (start->bres.minor < ETE->bres.minor))
    {
        prev = start;
        start = start->next;
    }
    ETE->next = start;

    if (prev)
        prev->next = ETE;
    else
        pSLL->edgelist = ETE;
    return true;
}

/*
 *     CreateEdgeTable
 *
 *     This routine creates the edge table for
 *     scan converting polygons.
 *     The Edge Table (ET) looks like:
 *
 *    EdgeTable
 *     --------
 *    |  ymax  |        ScanLineLists
 *    |scanline|-->------------>-------------->...
 *     --------   |scanline|   |scanline|
 *                |edgelist|   |edgelist|
 *                ---------    ---------
 *                    |             |
 *                    |             |
 *                    V             V
 *              list of ETEs   list of ETEs
 *
 *     where ETE is an EdgeTableEntry data structure, 
 *     and there is one ScanLineList per scanline at
 *     which an edge is initially entered.
 *
 */

typedef struct {
#if defined(Q_OS_MAC)
    int y, x;
#else
    int x, y;
#endif

} DDXPointRec, *DDXPointPtr;

/*
 *     Clean up our act.
 */
static void
miFreeStorage(ScanLineListBlock   *pSLLBlock)
{
    register ScanLineListBlock   *tmpSLLBlock;

    while (pSLLBlock)
    {
        tmpSLLBlock = pSLLBlock->next;
        free(pSLLBlock);
        pSLLBlock = tmpSLLBlock;
    }
}

static bool
miCreateETandAET(int count, DDXPointPtr pts, EdgeTable *ET, 
        EdgeTableEntry *AET, EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
{
    register DDXPointPtr top, bottom;
    register DDXPointPtr PrevPt, CurrPt;
    int iSLLBlock = 0;

    int dy;

    if (count < 2)  return true;

    /*
     *  initialize the Active Edge Table
     */
    AET->next = 0;
    AET->back = 0;
    AET->nextWETE = 0;
    AET->bres.minor = MININT;

    /*
     *  initialize the Edge Table.
     */
    ET->scanlines.next = 0;
    ET->ymax = MININT;
    ET->ymin = MAXINT;
    pSLLBlock->next = 0;

    PrevPt = &pts[count-1];

    /*
     *  for each vertex in the array of points.
     *  In this loop we are dealing with two vertices at
     *  a time -- these make up one edge of the polygon.
     */
    while (count--)
    {
        CurrPt = pts++;

        /*
         *  find out which point is above and which is below.
         */
        if (PrevPt->y > CurrPt->y)
        {
            bottom = PrevPt, top = CurrPt;
            pETEs->ClockWise = 0;
        }
        else
        {
            bottom = CurrPt, top = PrevPt;
            pETEs->ClockWise = 1;
        }

        /*
         * don't add horizontal edges to the Edge table.
         */
        if (bottom->y != top->y)
        {
            pETEs->ymax = bottom->y-1;  /* -1 so we don't get last scanline */

            /*
             *  initialize integer edge algorithm
             */
            dy = bottom->y - top->y;
            BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres)

            if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
            {
                miFreeStorage(pSLLBlock->next);
                return false;
            }

            ET->ymax = qMax(ET->ymax, PrevPt->y);
            ET->ymin = qMin(ET->ymin, PrevPt->y);
            pETEs++;
        }

        PrevPt = CurrPt;
    }
    return true;
}

/*
 *     loadAET
 *
 *     This routine moves EdgeTableEntries from the
 *     EdgeTable into the Active Edge Table, 
 *     leaving them sorted by smaller x coordinate.
 *
 */

static void
miloadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)
{
    register EdgeTableEntry *pPrevAET;
    register EdgeTableEntry *tmp;

    pPrevAET = AET;
    AET = AET->next;
    while (ETEs)
    {
        while (AET && (AET->bres.minor < ETEs->bres.minor))
        {
            pPrevAET = AET;
            AET = AET->next;
        }
        tmp = ETEs->next;
        ETEs->next = AET;
        if (AET)
            AET->back = ETEs;
        ETEs->back = pPrevAET;
        pPrevAET->next = ETEs;
        pPrevAET = ETEs;

        ETEs = tmp;
    }
}

/*
 *     computeWAET
 *
 *     This routine links the AET by the
 *     nextWETE (winding EdgeTableEntry) link for
 *     use by the winding number rule.  The final
 *     Active Edge Table (AET) might look something
 *     like:
 *
 *     AET
 *     ----------  ---------   ---------
 *     |ymax    |  |ymax    |  |ymax    |
 *     | ...    |  |...     |  |...     |
 *     |next    |->|next    |->|next    |->...
 *     |nextWETE|  |nextWETE|  |nextWETE|
 *     ---------   ---------   ^--------
 *         |                   |       |
 *         V------------------->       V---> ...
 *
 */
static void
micomputeWAET(EdgeTableEntry *AET)
{
    register EdgeTableEntry *pWETE;
    register int inside = 1;
    register int isInside = 0;

    AET->nextWETE = 0;
    pWETE = AET;
    AET = AET->next;
    while (AET)
    {
        if (AET->ClockWise)
            isInside++;
        else
            isInside--;

        if ((!inside && !isInside) ||
            (inside &&  isInside))
        {
            pWETE->nextWETE = AET;
            pWETE = AET;
            inside = !inside;
        }
        AET = AET->next;
    }
    pWETE->nextWETE = 0;
}

/*
 *     InsertionSort
 *
 *     Just a simple insertion sort using
 *     pointers and back pointers to sort the Active
 *     Edge Table.
 *
 */

static int
miInsertionSort(EdgeTableEntry *AET)
{
    register EdgeTableEntry *pETEchase;
    register EdgeTableEntry *pETEinsert;
    register EdgeTableEntry *pETEchaseBackTMP;
    register int changed = 0;

    AET = AET->next;
    while (AET)
    {
        pETEinsert = AET;
        pETEchase = AET;
        while (pETEchase->back->bres.minor > AET->bres.minor)
            pETEchase = pETEchase->back;

        AET = AET->next;
        if (pETEchase != pETEinsert)
        {
            pETEchaseBackTMP = pETEchase->back;
            pETEinsert->back->next = AET;
            if (AET)
                AET->back = pETEinsert->back;
            pETEinsert->next = pETEchase;
            pETEchase->back->next = pETEinsert;
            pETEchase->back = pETEinsert;
            pETEinsert->back = pETEchaseBackTMP;
            changed = 1;
        }
    }
    return changed;
}

/*
    \overload
*/
void QtPolygonScanner::scan(const QPolygon& pa, bool winding, int index, int npoints)
{
    scan(pa, winding, index, npoints, true);
}

/*
    \overload

    If \a stitchable is false, the right and bottom edges of the
    polygon are included. This causes adjacent polygons to overlap.
*/
void QtPolygonScanner::scan(const QPolygon& pa, bool winding, int index, int npoints, bool stitchable)
{
    scan(pa, winding, index, npoints, 
        stitchable ? Edge(Left+Top) : Edge(Left+Right+Top+Bottom));
}

/*
    Calls processSpans() for all scanlines of the polygon defined by
    \a npoints starting at \a index in \a pa.

    If \a winding is true, the Winding algorithm rather than the
    Odd-Even rule is used.

    The \a edges is any bitwise combination of:
    \list
    \i QtPolygonScanner::Left
    \i QtPolygonScanner::Right
    \i QtPolygonScanner::Top
    \i QtPolygonScanner::Bottom
    \endlist
    \a edges determines which edges are included.

    \warning The edges feature does not work properly.

*/
void QtPolygonScanner::scan(const QPolygon& pa, bool winding, int index, int npoints, Edge edges)
{


    DDXPointPtr ptsIn = (DDXPointPtr)pa.data();
    ptsIn += index;
    register EdgeTableEntry *pAET;  /* the Active Edge Table   */
    register int y;                 /* the current scanline    */
    register int nPts = 0;          /* number of pts in buffer */
    register EdgeTableEntry *pWETE; /* Winding Edge Table      */
    register ScanLineList *pSLL;    /* Current ScanLineList    */
    register DDXPointPtr ptsOut;      /* ptr to output buffers   */
    int *width;
    DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
    int FirstWidth[NUMPTSTOBUFFER];
    EdgeTableEntry *pPrevAET;       /* previous AET entry      */
    EdgeTable ET;                   /* Edge Table header node  */
    EdgeTableEntry AET;             /* Active ET header node   */
    EdgeTableEntry *pETEs;          /* Edge Table Entries buff */
    ScanLineListBlock SLLBlock;     /* header for ScanLineList */
    int fixWAET = 0;
    int edge_l = (edges & Left) ? 1 : 0;
    int edge_r = (edges & Right) ? 1 : 0;
    int edge_t = 1; //#### (edges & Top) ? 1 : 0;
    int edge_b = (edges & Bottom) ? 1 : 0;

    if (npoints == -1)
        npoints = pa.size();

    if (npoints < 3)
        return;

    if(!(pETEs = (EdgeTableEntry *)
        malloc(sizeof(EdgeTableEntry) * npoints)))
        return;
    ptsOut = FirstPoint;
    width = FirstWidth;
    if (!miCreateETandAET(npoints, ptsIn, &ET, &AET, pETEs, &SLLBlock))
    {
        free(pETEs);
        return;
    }
    pSLL = ET.scanlines.next;

    if (!winding)
    {
        /*
         *  for each scanline
         */
        for (y = ET.ymin+1-edge_t; y < ET.ymax+edge_b; y++)
        {
            /*
             *  Add a new edge to the active edge table when we
             *  get to the next edge.
             */
            if (pSLL && y == pSLL->scanline)
            {
                miloadAET(&AET, pSLL->edgelist);
                pSLL = pSLL->next;
            }
            pPrevAET = &AET;
            pAET = AET.next;

            /*
             *  for each active edge
             */
            while (pAET)
            {
                ptsOut->x = pAET->bres.minor + 1 - edge_l;
                ptsOut++->y = y;
                *width++ = pAET->next->bres.minor - pAET->bres.minor
                    - 1 + edge_l + edge_r;
                nPts++;

                /*
                 *  send out the buffer when its full
                 */
                if (nPts == NUMPTSTOBUFFER)
                {
                    processSpans(nPts, (QPoint*)FirstPoint, FirstWidth);
                    ptsOut = FirstPoint;
                    width = FirstWidth;
                    nPts = 0;
                }
                EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
                EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
            }
            miInsertionSort(&AET);
        }
    }
    else      /* default to WindingNumber */
    {
        /*
         *  for each scanline
         */
        for (y = ET.ymin+1-edge_t; y < ET.ymax+edge_b; y++)
        {
            /*
             *  Add a new edge to the active edge table when we
             *  get to the next edge.
             */
            if (pSLL && y == pSLL->scanline)
            {
                miloadAET(&AET, pSLL->edgelist);
                micomputeWAET(&AET);
                pSLL = pSLL->next;
            }
            pPrevAET = &AET;
            pAET = AET.next;
            pWETE = pAET;

            /*
             *  for each active edge
             */
            while (pAET)
            {
                /*
                 *  if the next edge in the active edge table is
                 *  also the next edge in the winding active edge
                 *  table.
                 */
                if (pWETE == pAET)
                {
                    ptsOut->x = pAET->bres.minor + 1 - edge_l;
                    ptsOut++->y = y;
                    *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor - 1 + edge_l + edge_r;
                    nPts++;

                    /*
                     *  send out the buffer
                     */
                    if (nPts == NUMPTSTOBUFFER)
                    {
                        processSpans(nPts, (QPoint*)FirstPoint, FirstWidth);
                        ptsOut = FirstPoint;
                        width  = FirstWidth;
                        nPts = 0;
                    }

                    pWETE = pWETE->nextWETE;
                    while (pWETE != pAET) {
                        EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
                    }
                    pWETE = pWETE->nextWETE;
                }
                EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
            }

            /*
             *  reevaluate the Winding active edge table if we
             *  just had to resort it or if we just exited an edge.
             */
            if (miInsertionSort(&AET) || fixWAET)
            {
                micomputeWAET(&AET);
                fixWAET = 0;
            }
        }
    }

    /*
     *     Get any spans that we missed by buffering
     */


    processSpans(nPts, (QPoint*)FirstPoint, FirstWidth);
    free(pETEs);
    miFreeStorage(SLLBlock.next);
}
/***** END OF X11-based CODE *****/





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

void QtCanvasPolygonalItem::scanPolygon(const QPolygon& pa, int winding, QPolygonalProcessor& process) const
{
    QtCanvasPolygonScanner scanner(process);
    scanner.scan(pa, winding);
}
