45#include <QApplication>
47#include <QDesktopWidget>
51#include <qalgorithms.h>
54#include <qpainterpath.h>
91 void add(
int x,
int y,
int w,
int h);
92 void add(
const QRect& rect);
111include(QRect& r,
const QRect& rect)
113 if (rect.left() < r.left())
115 r.setLeft(rect.left());
118 if (rect.right() > r.right())
120 r.setRight(rect.right());
123 if (rect.top() < r.top())
125 r.setTop(rect.top());
128 if (rect.bottom() > r.bottom())
130 r.setBottom(rect.bottom());
139 cluster(new QRect[maxclusters]), count(0), maxcl(maxclusters)
157 add(QRect(x, y, 1, 1));
163 add(QRect(x, y, w, h));
169 QRect biggerrect(rect.x() - 1, rect.y() - 1, rect.width() + 2, rect.height() + 2);
175 for (cursor = 0; cursor < count; cursor++)
184 int lowestcost = 9999999;
188 while (cursor < count)
192 QRect larger = cluster[cursor];
193 include(larger, rect);
194 int cost = larger.width() * larger.height() -
195 cluster[cursor].width() * cluster[cursor].height();
197 if (cost < lowestcost)
201 for (
int c = 0;
c < count && !bad;
c++)
203 bad = cluster[
c].intersects(larger) &&
c != cursor;
219 include(cluster[cheapest], rect);
225 cluster[count++] = rect;
233 lowestcost = 9999999;
237 while (cursor < count)
239 QRect larger = cluster[cursor];
240 include(larger, rect);
242 larger.width() * larger.height() - cluster[cursor].width() * cluster[cursor].height();
244 if (cost < lowestcost)
248 for (
int c = 0;
c < count && !bad;
c++)
250 bad = cluster[
c].intersects(larger) &&
c != cursor;
267 int cheapestmerge1 = -1;
268 int cheapestmerge2 = -1;
272 while (merge1 < count)
276 while (merge2 < count)
278 if (merge1 != merge2)
280 QRect larger = cluster[merge1];
281 include(larger, cluster[merge2]);
282 int cost = larger.width() * larger.height() -
283 cluster[merge1].width() * cluster[merge1].height() -
284 cluster[merge2].width() * cluster[merge2].height();
286 if (cost < lowestcost)
290 for (
int c = 0;
c < count && !bad;
c++)
292 bad = cluster[
c].intersects(larger) &&
c != cursor;
297 cheapestmerge1 = merge1;
298 cheapestmerge2 = merge2;
310 if (cheapestmerge1 >= 0)
312 include(cluster[cheapestmerge1], cluster[cheapestmerge2]);
313 cluster[cheapestmerge2] = cluster[count--];
318 include(cluster[cheapest], rect);
347 if (i1->
z() == i2->
z())
352 return (i1->
z() > i2->
z());
381 m_list.prepend(item);
388 m_list.removeAll(item);
593QtCanvas::init(
int w,
int h,
int chunksze,
int mxclusters)
595 d =
new QtCanvasData;
598 chunksize = chunksze;
599 maxclusters = mxclusters;
600 chwidth = (w + chunksize - 1) / chunksize;
601 chheight = (h + chunksize - 1) / chunksize;
602 chunks =
new QtCanvasChunk[chwidth * chheight];
608 debug_redraw_areas =
false;
656 init(h * tilewidth, v * tileheight, scm(tilewidth, tileheight));
657 setTiles(p, h, v, tilewidth, tileheight);
665 for (
int i = 0; i < d->viewList.size(); ++i)
667 d->viewList[i]->viewing = 0;
672 for (QtCanvasItemList::Iterator it =
all.begin(); it !=
all.end(); ++it)
687QtCanvas::chunk(
int i,
int j)
const
689 return chunks[i + chwidth * j];
697QtCanvas::chunkContaining(
int x,
int y)
const
699 return chunk(x / chunksize, y / chunksize);
708 return d->itemDict.toList();
718 if (awidth == w && aheight == h)
723 QList<QtCanvasItem*> hidden;
725 for (QSet<QtCanvasItem*>::const_iterator it = d->itemDict.begin(); it != d->itemDict.end();
728 if ((*it)->isVisible())
735 int nchwidth = (w + chunksize - 1) / chunksize;
736 int nchheight = (h + chunksize - 1) / chunksize;
738 QtCanvasChunk* newchunks =
new QtCanvasChunk[nchwidth * nchheight];
745 chheight = nchheight;
749 for (
int i = 0; i < hidden.size(); ++i)
751 hidden.at(i)->show();
802 maxclusters = mxclusters;
804 if (chunksize != chunksze)
806 QList<QtCanvasItem*> hidden;
808 for (QSet<QtCanvasItem*>::const_iterator it = d->itemDict.begin(); it != d->itemDict.end();
811 if ((*it)->isVisible())
818 chunksize = chunksze;
820 int nchwidth = (awidth + chunksize - 1) / chunksize;
821 int nchheight = (aheight + chunksize - 1) / chunksize;
823 QtCanvasChunk* newchunks =
new QtCanvasChunk[nchwidth * nchheight];
828 chheight = nchheight;
832 for (
int i = 0; i < hidden.size(); ++i)
834 hidden.at(i)->show();
924 d->itemDict.insert(item);
935 d->animDict.insert(item);
946 d->animDict.remove(item);
957 d->itemDict.remove(item);
968 d->viewList.append(view);
970 if (htiles > 1 || vtiles > 1 || pm.isNull())
972 QPalette::ColorRole role = view->widget()->backgroundRole();
973 QPalette viewPalette = view->widget()->palette();
975 view->widget()->setPalette(viewPalette);
987 d->viewList.removeAll(view);
1004 update_timer->stop();
1011 delete update_timer;
1014 update_timer =
new QTimer(
this);
1015 connect(update_timer, SIGNAL(timeout()),
this, SLOT(
advance()));
1016 update_timer->start(ms);
1034 update_timer->stop();
1041 delete update_timer;
1044 update_timer =
new QTimer(
this);
1045 connect(update_timer, SIGNAL(timeout()),
this, SLOT(
update()));
1046 update_timer->start(ms);
1075 QSetIterator<QtCanvasItem*> it = d->animDict;
1077 while (it.hasNext())
1079 QtCanvasItem* i = it.next();
1091 while (it.hasNext())
1093 QtCanvasItem* i = it.next();
1113 QMatrix iwm = wm.inverted();
1115 QRect ivr = iwm.mapRect(vr);
1129 QRect r = changeBounds();
1131 for (
int i = 0; i < d->viewList.size(); ++i)
1133 QtCanvasView* view = d->viewList.at(i);
1138 view->widget()->update(tr);
1163 QRect thearea = area.intersected(QRect(0, 0,
width(),
height()));
1165 int mx = (thearea.x() + thearea.width() + chunksize) / chunksize;
1166 int my = (thearea.y() + thearea.height() + chunksize) / chunksize;
1178 int x = thearea.x() / chunksize;
1182 int y = thearea.y() / chunksize;
1186 chunk(x, y).change();
1202 QRect thearea = area.intersected(QRect(0, 0,
width(),
height()));
1204 int mx = (thearea.x() + thearea.width() + chunksize) / chunksize;
1205 int my = (thearea.y() + thearea.height() + chunksize) / chunksize;
1217 int x = thearea.x() / chunksize;
1221 int y = thearea.y() / chunksize;
1225 chunk(x, y).takeChange();
1237QtCanvas::changeBounds()
1241 int mx = (area.x() + area.width() + chunksize) / chunksize;
1242 int my = (area.y() + area.height() + chunksize) / chunksize;
1256 int x = area.x() / chunksize;
1260 int y = area.y() / chunksize;
1264 QtCanvasChunk& ch = chunk(x, y);
1268 result |= QRect(x * chunksize, y * chunksize, chunksize + 1, chunksize + 1);
1310 QRect area = inarea.intersected(QRect(0, 0,
width(),
height()));
1317 int lx = area.x() / chunksize;
1318 int ly = area.y() / chunksize;
1319 int mx = area.right() / chunksize;
1320 int my = area.bottom() / chunksize;
1338 for (
int x = lx; x <= mx; x++)
1340 for (
int y = ly; y <= my; y++)
1349 if (chunk(x, y).takeChange())
1353 x * chunksize - area.x(), y * chunksize - area.y(), chunksize, chunksize);
1354 allvisible += chunk(x, y).list();
1359 allvisible += chunk(x, y).list();
1364 qSort(allvisible.begin(), allvisible.end(), QtCanvasItemLess());
1368 if (!allvisible.isEmpty())
1370 QtCanvasItem* prev = 0;
1372 for (
int i = allvisible.size() - 1; i >= 0; --i)
1374 QtCanvasItem* g = allvisible[i];
1402 QtCanvasChunk& ch = chunk(x, y);
1420 if (x >= 0 && x <
width() && y >= 0 && y <
height())
1422 QtCanvasChunk& chunk = chunkContaining(x, y);
1455 chunk(x, y).remove(g);
1469 if (x >= 0 && x <
width() && y >= 0 && y <
height())
1471 chunkContaining(x, y).add(g);
1485 if (x >= 0 && x <
width() && y >= 0 && y <
height())
1487 chunkContaining(x, y).remove(g);
1520 for (
int i = 0; i < d->viewList.size(); ++i)
1522 QtCanvasView* view = d->viewList.at(i);
1523 QPalette::ColorRole role = view->widget()->backgroundRole();
1524 QPalette viewPalette = view->widget()->palette();
1525 viewPalette.setColor(role, bgcolor);
1526 view->widget()->setPalette(viewPalette);
1554 setTiles(p, 1, 1, p.width(), p.height());
1556 for (
int i = 0; i < d->viewList.size(); ++i)
1558 QtCanvasView* view = d->viewList.at(i);
1559 view->widget()->update();
1581 painter.fillRect(clip, bgcolor);
1585 for (
int x = clip.x() / pm.width();
1586 x < (clip.x() + clip.width() + pm.width() - 1) / pm.width();
1589 for (
int y = clip.y() / pm.height();
1590 y < (clip.y() + clip.height() + pm.height() - 1) / pm.height();
1593 painter.drawPixmap(x * pm.width(), y * pm.height(), pm);
1599 const int x1 = clip.left() / tilew;
1600 int x2 = clip.right() / tilew;
1601 const int y1 = clip.top() / tileh;
1602 int y2 = clip.bottom() / tileh;
1604 const int roww = pm.width() / tilew;
1606 for (
int j = y1; j <= y2; j++)
1610 for (
int i = x1; i <= x2; i++)
1615 painter.drawPixmap(i * tilew, j * tileh, pm, tx * tilew, ty * tileh, tilew, tileh);
1635 if (debug_redraw_areas)
1637 painter.setPen(red);
1638 painter.setBrush(NoBrush);
1639 painter.drawRect(clip);
1673 (!tilewidth || !tileheight || p.width() % tilewidth != 0 || p.height() % tileheight != 0))
1683 if (h && v && !p.isNull())
1685 grid =
new ushort[h *
v];
1686 memset(grid, 0, h * v *
sizeof(ushort));
1697 int s = scm(tilewidth, tileheight);
1698 retune(s < 128 ? s : qMax(tilewidth, tileheight));
1762 ushort& t = grid[x + y * htiles];
1768 if (tilew == tileh && tilew == chunksize)
1774 setChanged(QRect(x * tilew, y * tileh, tilew, tileh));
1783 QtCanvasItemExtra() : vx(0.0), vy(0.0)
1903 cnv->removeItem(
this);
1904 cnv->removeAnimation(
this);
1911QtCanvasItem::extra()
1915 ext =
new QtCanvasItemExtra;
2021 cnv->addAnimation(
this);
2025 cnv->removeAnimation(
this);
2055 if (ext || vx != 0.0 || vy != 0.0)
2073 return ext ? ext->vx : 0;
2082 return ext ? ext->vy : 0;
2099 if (ext && phase == 1)
2101 moveBy(ext->vx, ext->vy);
2126 cnv->removeAnimation(
this);
2129 cnv->removeItem(
this);
2140 cnv->addAnimation(
this);
2175 if ((
bool)vis != yes)
2236 if ((
bool)sel != yes)
2268 if (ena != (uint)yes)
2300 if (act != (uint)yes)
2310 const QImage* s2image = s2->
imageAdvanced()->collision_mask;
2313 QRect cyourarea(s2area.x(), s2area.y(), s2area.width(), s2area.height());
2319 QRect ourarea = s1area.intersected(cyourarea);
2321 if (ourarea.isEmpty())
2326 int x2 = ourarea.x() - cyourarea.x();
2327 int y2 = ourarea.y() - cyourarea.y();
2328 int x1 = ourarea.x() - s1area.x();
2329 int y1 = ourarea.y() - s1area.y();
2330 int w = ourarea.width();
2331 int h = ourarea.height();
2337 return w > 0 && h > 0;
2365 if (s1image->format() == QImage::Format_MonoLSB)
2367 for (
int j = 0; j < h; j++)
2369 uchar* ml = s1image->scanLine(y1 + j);
2370 const uchar* yl = s2image->scanLine(y2 + j);
2372 for (
int i = 0; i < w; i++)
2374 if (*(yl + ((x2 + i) >> 3)) & (1 << ((x2 + i) & 7)) &&
2375 *(ml + ((x1 + i) >> 3)) & (1 << ((x1 + i) & 7)))
2384 for (
int j = 0; j < h; j++)
2386 uchar* ml = s1image->scanLine(y1 + j);
2387 const uchar* yl = s2image->scanLine(y2 + j);
2389 for (
int i = 0; i < w; i++)
2391 if (*(yl + ((x2 + i) >> 3)) & (1 << (7 - ((x2 + i) & 7))) &&
2392 *(ml + ((x1 + i) >> 3)) & (1 << (7 - ((x1 + i) & 7))))
2402 if (s2image->format() == QImage::Format_MonoLSB)
2404 for (
int j = 0; j < h; j++)
2406 const uchar* yl = s2image->scanLine(y2 + j);
2408 for (
int i = 0; i < w; i++)
2410 if (*(yl + ((x2 + i) >> 3)) & (1 << ((x2 + i) & 7)))
2419 for (
int j = 0; j < h; j++)
2421 const uchar* yl = s2image->scanLine(y2 + j);
2423 for (
int i = 0; i < w; i++)
2425 if (*(yl + ((x2 + i) >> 3)) & (1 << (7 - ((x2 + i) & 7))))
2465 else if ((r1 || t1 || s1) && (r2 || t2 || s2))
2470 return rc1.intersects(rc2);
2476 double xd = (e1->x() + e1->xVelocity()) - (e2->x() + e1->xVelocity());
2477 double yd = (e1->y() + e1->yVelocity()) - (e2->y() + e1->yVelocity());
2478 double rd = (e1->width() + e2->width()) / 2;
2479 return xd * xd + yd * yd <= rd * rd;
2481 else if (p1 && (p2 || s2 || t2))
2486 bool col = !(QRegion(pa1) & QRegion(pa2, Qt::WindingFill)).isEmpty();
2492 return collision_double_dispatch(s2, p2, r2, e2, t2, s1, p1, r1, e1, t1);
2574 return collision_double_dispatch(s, p, r, e, t,
this, 0, 0, 0, 0);
2593 return collision_double_dispatch(s, p, r, e, t, 0,
this, 0, 0, 0);
2612 return collision_double_dispatch(s, p, r, e, t, 0,
this,
this, 0, 0);
2631 return collision_double_dispatch(s, p, r, e, t, 0,
this, 0,
this, 0);
2650 return collision_double_dispatch(s, p, r, e, t, 0, 0, 0, 0,
this);
2718 QtCanvasRectangle i(r, (
QtCanvas*)
this);
2722 qSort(l.begin(), l.end(), QtCanvasItemLess());
2741 QSet<QtCanvasItem*> seen;
2744 for (
int i = 0; i < (int)chunklist.count(); i++)
2746 int x = chunklist[i].x();
2747 int y = chunklist[i].y();
2753 for (
int i = 0; i < l.size(); ++i)
2755 QtCanvasItem* g = l.at(i);
2759 if (!seen.contains(g))
2781QtCanvasItem::addToChunks()
2785 QPolygon pa = chunks();
2787 for (
int i = 0; i < (int)pa.count(); i++)
2801QtCanvasItem::removeFromChunks()
2805 QPolygon pa = chunks();
2807 for (
int i = 0; i < (int)pa.count(); i++)
2820QtCanvasItem::changeChunks()
2829 QPolygon pa = chunks();
2831 for (
int i = 0; i < (int)pa.count(); i++)
2858 r.translate(dx, dy);
2903 QImage image(datafilename);
2921 init(pm, offset.x(), offset.y());
2925QtCanvasPixmap::init(
const QImage& image)
2927 this->QPixmap::operator=(QPixmap::fromImage(image));
2928 hotx = image.offset().x();
2929 hoty = image.offset().y();
2930#ifndef QT_NO_IMAGE_DITHER_TO_1
2932 if (image.hasAlphaChannel())
2934 QImage i = image.createAlphaMask();
2935 collision_mask =
new QImage(i);
2943QtCanvasPixmap::init(
const QPixmap& pixmap,
int hx,
int hy)
2945 (QPixmap&)*
this = pixmap;
2949 if (pixmap.hasAlphaChannel())
2951 QImage i = mask().toImage();
2952 collision_mask =
new QImage(i);
2965 delete collision_mask;
3046 framecount(0), img(0)
3048 readPixmaps(datafilenamepattern, fc);
3062 if (list.count() != hotspots.count())
3064 qWarning(
"QtCanvasPixmapArray: lists have different lengths");
3070 for (int i = 0; i < framecount; i++)
3072 img[i] = new QtCanvasPixmap(list.at(i), hotspots.at(i));
3086QtCanvasPixmapArray::reset()
3088 for (
int i = 0; i < framecount; i++)
3164 img =
new QtCanvasPixmap*[framecount];
3180 for (
int i = 0; i < framecount; i++)
3183 r.sprintf(
"%04d", i);
3187 if (!img[i]->collision_mask)
3189 img[i]->collision_mask =
new QImage();
3192 img[i]->collision_mask->load(arg ? datafilenamepattern.arg(r) : datafilenamepattern);
3193 ok =
ok && !img[i]->collision_mask->isNull() && img[i]->collision_mask->depth() == 1;
3197 img[i] =
new QtCanvasPixmap(arg ? datafilenamepattern.arg(r) : datafilenamepattern);
3198 ok =
ok && !img[i]->isNull();
3255 if (i >= framecount)
3257 QtCanvasPixmap** newimg =
new QtCanvasPixmap*[i + 1];
3258 memcpy(newimg, img,
sizeof(QtCanvasPixmap*) * framecount);
3259 memset(newimg + framecount, 0,
sizeof(QtCanvasPixmap*) * (i + 1 - framecount));
3285 return int(
x()) -
image()->hotx;
3300 return nx -
image()->hotx;
3313 return int(
y()) -
image()->hoty;
3328 return ny -
image()->hoty;
3428QtCanvasItem::chunks()
const
3437 br &= QRect(0, 0,
canvas()->width(),
canvas()->height());
3441 r.resize((br.width() / chunksize + 2) * (br.height() / chunksize + 2));
3443 for (
int j = br.top() / chunksize; j <= br.bottom() / chunksize; j++)
3445 for (
int i = br.left() / chunksize; i <= br.right() / chunksize; i++)
3447 r[
n++] = QPoint(i, j);
3462QtCanvasSprite::addToChunks()
3485QtCanvasSprite::removeFromChunks()
3511 return image()->width();
3522 return image()->height();
3608 m_view->contentsMousePressEvent(e);
3614 m_view->contentsMouseMoveEvent(e);
3620 m_view->contentsMouseReleaseEvent(e);
3626 m_view->contentsMouseDoubleClickEvent(e);
3632 m_view->contentsDragEnterEvent(e);
3638 m_view->contentsDragMoveEvent(e);
3644 m_view->contentsDragLeaveEvent(e);
3650 m_view->contentsDropEvent(e);
3656 m_view->contentsWheelEvent(e);
3662 m_view->contentsContextMenuEvent(e);
3673 if (
m_view->d->highQuality)
3675 p.setRenderHint(QPainter::Antialiasing);
3676 p.setRenderHint(QPainter::SmoothPixmapTransform);
3679 m_view->drawContents(&p, e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
3689 d =
new QtCanvasViewData;
3691 d->highQuality =
false;
3704 d =
new QtCanvasViewData;
3705 d->highQuality =
false;
3735 return d->highQuality;
3741 d->highQuality = enable;
3823 disconnect(viewing);
3824 viewing->removeView(
this);
3831 connect(viewing, SIGNAL(resized()),
this, SLOT(updateContentsSize()));
3832 viewing->addView(
this);
3837 updateContentsSize();
3882 bool ok = wm.isInvertible();
3887 d->ixform = wm.inverted();
3888 updateContentsSize();
3896QtCanvasView::updateContentsSize()
3901 br = d->xform.mapRect(QRect(0, 0, viewing->width(), viewing->height()));
3903 widget()->resize(br.size());
3907 widget()->resize(size());
3924 QPainterPath clipPath;
3925 clipPath.addRect(viewing->rect());
3926 p->setClipPath(d->xform.map(clipPath), Qt::IntersectClip);
3927 viewing->drawViewArea(
this, p, QRect(cx, cy, cw, ch),
false);
3938 return QScrollArea::sizeHint();
3942 return (
canvas()->size() + 2 * QSize(frameWidth(), frameWidth()))
3943 .boundedTo(3 * QApplication::desktop()->size() / 4);
4006 static QPen* dp = 0;
4017defaultPolygonBrush()
4019 static QBrush* db = 0;
4033 QtCanvasItem(canvas), br(defaultPolygonBrush()), pn(defaultPolygonPen())
4114 r.translate(dx, dy);
4121#ifdef QCANVAS_POLYGONS_DEBUG
4122static QWidget* dbg_wid = 0;
4123static QPainter* dbg_ptr = 0;
4131 QRect pixelbounds = pa.boundingRect();
4132 int cs =
canvas->chunkSize();
4133 QRect canvasbounds = pixelbounds.intersected(
canvas->rect());
4134 bounds.setLeft(canvasbounds.left() / cs);
4135 bounds.setRight(canvasbounds.right() / cs);
4136 bounds.setTop(canvasbounds.top() / cs);
4137 bounds.setBottom(canvasbounds.bottom() / cs);
4141#ifdef QCANVAS_POLYGONS_DEBUG
4155#ifdef QCANVAS_POLYGONS_DEBUG
4159 int cs =
canvas->chunkSize();
4160 QRect r(
x * cs +
bounds.x() * cs, y * cs +
bounds.y() * cs, cs - 1, cs - 1);
4161 dbg_ptr->setPen(Qt::blue);
4162 dbg_ptr->drawRect(r);
4169 addBits(
int x1,
int x2, uchar newbits,
int xo,
int yo)
4171 for (
int i = x1; i <= x2; i++)
4172 if (newbits & (1 << i))
4178#ifdef QCANVAS_POLYGONS_DEBUG
4184 dbg_wid =
new QWidget;
4185 dbg_wid->resize(800, 600);
4187 dbg_ptr =
new QPainter(dbg_wid);
4188 dbg_ptr->setBrush(Qt::NoBrush);
4191 dbg_ptr->fillRect(dbg_wid->rect(), Qt::white);
4198 int cs =
canvas->chunkSize();
4200 for (
int j = 0; j < n; j++)
4202 int y = pt[j].y() / cs -
bounds.y();
4204 if (y >=
bitmap.height() || y < 0)
4209 uchar* l =
bitmap.scanLine(y);
4219 int x2 = (
x + w[j]) / cs -
bounds.x();
4226 x2 = qMin(
bounds.width(), x2);
4231#ifdef QCANVAS_POLYGONS_DEBUG
4235 dbg_ptr->setPen(Qt::yellow);
4242 uchar newbits = (~l[x1q]) & (((2 << (x2r - x1r)) - 1) << x1r);
4246#ifdef QCANVAS_POLYGONS_DEBUG
4250 dbg_ptr->setPen(Qt::darkGreen);
4254 addBits(x1r, x2r, newbits, x1q * 8, y);
4260#ifdef QCANVAS_POLYGONS_DEBUG
4264 dbg_ptr->setPen(Qt::blue);
4268 uchar newbits1 = (~l[x1q]) & (0xff << x1r);
4272#ifdef QCANVAS_POLYGONS_DEBUG
4276 dbg_ptr->setPen(Qt::green);
4280 addBits(x1r, 7, newbits1, x1q * 8, y);
4284 for (
int i = x1q + 1; i < x2q; i++)
4288 addBits(0, 7, ~l[i], i * 8, y);
4293 uchar newbits2 = (~l[x2q]) & (0xff >> (7 - x2r));
4297#ifdef QCANVAS_POLYGONS_DEBUG
4301 dbg_ptr->setPen(Qt::red);
4305 addBits(0, x2r, newbits2, x2q * 8, y);
4310#ifdef QCANVAS_POLYGONS_DEBUG
4314 dbg_ptr->drawLine(pt[j], pt[j] + QPoint(w[j], 0));
4331QtCanvasPolygonalItem::chunks()
const
4341 QPolygonalProcessor processor(
canvas(), pa);
4343 scanPolygon(pa, wind, processor);
4345 return processor.result;
4355 return QtCanvasItem::chunks();
4487 p.drawPolygon(
poly);
4501 poly.translate((
int)
x(), (
int)
y());
4514 int idx = int(
x() + dx) - int(
x());
4515 int idy = int(
y() + dy) - int(
y());
4520 poly.translate(idx, idy);
4589 if ((
int)ctrl.count() % 3 != (close ? 0 : 1))
4591 qWarning(
"QtCanvasSpline::setControlPoints(): Number of points doesn't fit.");
4592 int numCurves = (ctrl.count() - (close ? 0 : 1)) / 3;
4593 ctrl.resize(numCurves * 3 + (close ? 0 : 1));
4623QtCanvasSpline::recalcPoly()
4625 if (bez.count() == 0)
4631 path.moveTo(bez[0]);
4633 for (
int i = 1; i < (int)bez.count() - 1; i += 3)
4635 path.cubicTo(bez[i], bez[i + 1], cl ? bez[(i + 2) % bez.size()] : bez[i + 2]);
4638 QPolygon p = path.toFillPolygon().toPolygon();
4661 pa.translate(
int(-
x()),
int(-
y()));
4698 x1 = y1 = x2 = y2 = 0;
4741 if (x1 != xa || x2 != xb || y1 != ya || y2 != yb)
4758 p.drawLine((
int)(
x() + x1), (
int)(
y() + y1), (
int)(
x() + x2), (
int)(
y() + y2));
4773 int pw =
pen().width();
4774 int dx = qAbs(x1 - x2);
4775 int dy = qAbs(y1 - y2);
4776 pw = pw * 4 / 3 + 2;
4777 int px = x1 < x2 ? -pw : pw;
4778 int py = y1 < y2 ? -pw : pw;
4780 if (dx && dy && (dx > dy ? (dx * 2 / dy <= 2) : (dy * 2 / dx <= 2)))
4785 p[0] = QPoint(x1 + xi, y1 + yi + py);
4786 p[1] = QPoint(x2 + xi - px, y2 + yi);
4787 p[2] = QPoint(x2 + xi, y2 + yi - py);
4788 p[3] = QPoint(x1 + xi + px, y1 + yi);
4792 p[0] = QPoint(x1 + xi + px, y1 + yi);
4793 p[1] = QPoint(x2 + xi, y2 + yi - py);
4794 p[2] = QPoint(x2 + xi - px, y2 + yi);
4795 p[3] = QPoint(x1 + xi, y1 + yi + py);
4801 p[0] = QPoint(x1 + xi + px, y1 + yi + py);
4802 p[1] = QPoint(x2 + xi - px, y2 + yi + py);
4803 p[2] = QPoint(x2 + xi - px, y2 + yi - py);
4804 p[3] = QPoint(x1 + xi + px, y1 + yi - py);
4809 p[0] = QPoint(x1 + xi + px, y1 + yi + py);
4810 p[1] = QPoint(x2 + xi + px, y2 + yi - py);
4811 p[2] = QPoint(x2 + xi - px, y2 + yi - py);
4812 p[3] = QPoint(x1 + xi - px, y1 + yi + py);
4940 int pw = (
pen().width() + 1) / 2;
4952 pa[0] = QPoint((
int)
x() - pw, (
int)
y() - pw);
4953 pa[1] = pa[0] + QPoint(w + pw * 2, 0);
4954 pa[2] = pa[1] + QPoint(0, h + pw * 2);
4955 pa[3] = pa[0] + QPoint(0, h + pw * 2);
4965 p.drawRect((
int)
x(), (
int)
y(), w, h);
5109 if (a1 != start || a2 != length)
5126 QRectF(
x() - w / 2.0 + 0.5 - 1,
y() - h / 2.0 + 0.5 - 1, w + 3, h + 3), a1 / 16., a2 / 16.);
5127 return path.toFillPolygon().toPolygon();
5141 if (!a1 && a2 == 360 * 16)
5143 p.drawEllipse(
int(
x() - w / 2.0 + 0.5),
int(
y() - h / 2.0 + 0.5), w, h);
5147 p.drawPie(
int(
x() - w / 2.0 + 0.5),
int(
y() - h / 2.0 + 0.5), w, h, a1, a2);
5216QtCanvasText::setRect()
5218 brect = QFontMetrics(fnt).boundingRect(
int(
x()),
int(
y()), 0, 0, flags, txt);
5334 int idx = int(
x() + dx) - int(
x());
5335 int idy = int(
y() + dy) - int(
y());
5347 brect.translate(idx, idy);
5358 painter.setFont(fnt);
5359 painter.setPen(col);
5361 painter.fontMetrics().boundingRect(
int(
x()),
int(
y()), 0, 0, flags, txt), flags, txt);
5368QtCanvasText::changeChunks()
5374 for (
int j = brect.top() / chunksize; j <= brect.bottom() / chunksize; j++)
5376 for (
int i = brect.left() / chunksize; i <= brect.right() / chunksize; i++)
5388QtCanvasText::addToChunks()
5394 for (
int j = brect.top() / chunksize; j <= brect.bottom() / chunksize; j++)
5396 for (
int i = brect.left() / chunksize; i <= brect.right() / chunksize; i++)
5408QtCanvasText::removeFromChunks()
5414 for (
int j = brect.top() / chunksize; j <= brect.bottom() / chunksize; j++)
5416 for (
int i = brect.left() / chunksize; i <= brect.right() / chunksize; i++)
5572 QtCanvasItem(canvas), frm(0), anim_val(0), anim_state(0), anim_type(0), images(
a)
5588 if (isvisible && images)
5595 if (frm >= (
int)images->count())
5612QtCanvasSprite::changeChunks()
5714 anim_state = !anim_state;
5719 anim_state = !anim_state;
5800 void scan(
const QPolygon& pa,
bool winding,
int index = 0,
int npoints = -1);
5801 void scan(
const QPolygon& pa,
bool winding,
int index,
int npoints,
bool stitchable);
5811 void scan(
const QPolygon& pa,
bool winding,
int index,
int npoints,
Edge edges);
5942#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) \
5958 incr1 = -2 * dx + 2 * (dy) * m1; \
5959 incr2 = -2 * dx + 2 * (dy) * m; \
5960 d = 2 * m * (dy)-2 * dx - 2 * (dy); \
5966 incr1 = 2 * dx - 2 * (dy) * m1; \
5967 incr2 = 2 * dx - 2 * (dy) * m; \
5968 d = -2 * m * (dy) + 2 * dx; \
5973#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) \
6018#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
6019 BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, bres.m, bres.m1, bres.incr1, bres.incr2)
6021#define BRESINCRPGONSTRUCT(bres) \
6022 BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)
6053#define SLLSPERBLOCK 25
6065#define NUMPTSTOBUFFER 200
6080#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) \
6082 if (pAET->ymax == y) \
6084 pPrevAET->next = pAET->next; \
6085 pAET = pPrevAET->next; \
6088 pAET->back = pPrevAET; \
6092 BRESINCRPGONSTRUCT(pAET->bres); \
6094 pAET = pAET->next; \
6106#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) \
6108 if (pAET->ymax == y) \
6110 pPrevAET->next = pAET->next; \
6111 pAET = pPrevAET->next; \
6113 pAET->back = pPrevAET; \
6117 BRESINCRPGONSTRUCT(pAET->bres) \
6119 pAET = pAET->next; \
6171#define MAXINT 0x7fffffff
6172#define MININT -MAXINT
6207 pSLL = pPrevSLL->
next;
6209 while (pSLL && (pSLL->
scanline < scanline))
6218 if ((!pSLL) || (pSLL->
scanline > scanline))
6229 (*SLLBlock)->
next = tmpSLLBlock;
6230 tmpSLLBlock->
next = 0;
6231 *SLLBlock = tmpSLLBlock;
6235 pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
6239 pPrevSLL->
next = pSLL;
6253 start = start->
next;
6297#if defined(Q_OS_MAC)
6315 tmpSLLBlock = pSLLBlock->
next;
6317 pSLLBlock = tmpSLLBlock;
6322miCreateETandAET(
int count,
6354 pSLLBlock->
next = 0;
6356 PrevPt = &pts[count - 1];
6370 if (PrevPt->
y > CurrPt->
y)
6372 bottom = PrevPt, top = CurrPt;
6377 bottom = CurrPt, top = PrevPt;
6384 if (bottom->
y != top->
y)
6386 pETEs->
ymax = bottom->
y - 1;
6391 dy = bottom->
y - top->
y;
6394 if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
6396 miFreeStorage(pSLLBlock->next);
6445 ETEs->
back = pPrevAET;
6446 pPrevAET->
next = ETEs;
6477 register int inside = 1;
6478 register int isInside = 0;
6495 if ((!inside && !isInside) || (inside && isInside))
6523 register int changed = 0;
6534 pETEchase = pETEchase->
back;
6539 if (pETEchase != pETEinsert)
6541 pETEchaseBackTMP = pETEchase->
back;
6549 pETEinsert->
next = pETEchase;
6550 pETEchase->
back->
next = pETEinsert;
6551 pETEchase->
back = pETEinsert;
6552 pETEinsert->
back = pETEchaseBackTMP;
6566 scan(pa, winding,
index, npoints,
true);
6613 register int nPts = 0;
6626 int edge_l = (edges &
Left) ? 1 : 0;
6627 int edge_r = (edges &
Right) ? 1 : 0;
6629 int edge_b = (edges &
Bottom) ? 1 : 0;
6633 npoints = pa.size();
6646 ptsOut = FirstPoint;
6649 if (!miCreateETandAET(npoints, ptsIn, &ET, &AET, pETEs, &SLLBlock))
6662 for (y = ET.
ymin + 1 - edge_t; y < ET.
ymax + edge_b; y++)
6693 ptsOut = FirstPoint;
6702 miInsertionSort(&AET);
6710 for (y = ET.
ymin + 1 - edge_t; y < ET.
ymax + edge_b; y++)
6719 micomputeWAET(&AET);
6750 ptsOut = FirstPoint;
6757 while (pWETE != pAET)
6772 if (miInsertionSort(&AET) || fixWAET)
6774 micomputeWAET(&AET);
6787 miFreeStorage(SLLBlock.
next);
6805 processor.
doSpans(n, point, width);
6810QtCanvasPolygonalItem::scanPolygon(
const QPolygon& pa,
6814 QtCanvasPolygonScanner scanner(process);
struct DDXPointRec * DDXPointPtr
struct _EdgeTableEntry EdgeTableEntry
struct _ScanLineListBlock ScanLineListBlock
struct _ScanLineList ScanLineList
QList< QtCanvasItem * > QtCanvasItemList
struct DDXPointRec * DDXPointPtr
struct _EdgeTableEntry EdgeTableEntry
struct _ScanLineListBlock ScanLineListBlock
struct _ScanLineList ScanLineList
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres)
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
bool qt_testCollision(const QtCanvasSprite *s1, const QtCanvasSprite *s2)
QList< QtCanvasItem * > QtCanvasItemList
void addBits(int x1, int x2, uchar newbits, int xo, int yo)
void doSpans(int n, QPoint *pt, int *w)
QPolygonalProcessor(QtCanvas *c, const QPolygon &pa)
const QtCanvasItemList & list() const
void remove(QtCanvasItem *item)
void add(QtCanvasItem *item)
void add(const QRect &rect)
QtCanvasClusterizer(int maxclusters)
const QRect & operator[](int i) const
void add(int x, int y, int w, int h)
QSet< QtCanvasItem * > itemDict
QSet< QtCanvasItem * > animDict
QList< QtCanvasView * > viewList
void setSize(int w, int h)
void setAngles(int start, int length)
QPolygon areaPoints() const
void drawShape(QPainter &)
bool collidesWith(const QtCanvasItem *) const
bool operator()(const QtCanvasItem *i1, const QtCanvasItem *i2) const
friend class QtCanvasSprite
virtual void setActive(bool yes)
virtual void setVelocity(double vx, double vy)
virtual QRect boundingRect() const =0
friend class QtCanvasRectangle
virtual bool collidesWith(const QtCanvasItem *) const =0
virtual void setEnabled(bool yes)
friend class QtCanvasPolygon
friend class QtCanvasPolygonalItem
friend class QtCanvasText
friend class QtCanvasEllipse
QtCanvas * canvas() const
friend class QtCanvasLine
QtCanvasItem(QtCanvas *canvas)
virtual void setVisible(bool yes)
virtual void setCanvas(QtCanvas *)
virtual void draw(QPainter &)=0
virtual void moveBy(double dx, double dy)
virtual QRect boundingRectAdvanced() const
virtual void advance(int stage)
virtual void setAnimated(bool y)
QtCanvasItemList collisions(bool exact) const
virtual void setSelected(bool yes)
void move(double x, double y)
QPolygon areaPoints() const
void drawShape(QPainter &)
void setPoints(int x1, int y1, int x2, int y2)
void moveBy(double dx, double dy)
bool readPixmaps(const QString &datafilenamepattern, int framecount=0)
bool readCollisionMasks(const QString &filenamepattern)
void setImage(int i, QtCanvasPixmap *p)
QtCanvasPixmap(const QString &datafilename)
void processSpans(int n, QPoint *point, int *width)
QtCanvasPolygonScanner(QPolygonalProcessor &p)
QPolygon areaPoints() const
void drawShape(QPainter &)
void moveBy(double dx, double dy)
virtual void setBrush(QBrush b)
virtual ~QtCanvasPolygonalItem()
virtual QPolygon areaPointsAdvanced() const
bool collidesWith(const QtCanvasItem *) const
virtual void drawShape(QPainter &)=0
virtual QPolygon areaPoints() const =0
QRect boundingRect() const
virtual void setPen(QPen p)
void setSize(int w, int h)
QPolygon areaPoints() const
void drawShape(QPainter &)
bool collidesWith(const QtCanvasItem *) const
void setControlPoints(QPolygon, bool closed=true)
QtCanvasSpline(QtCanvas *canvas)
QPolygon controlPoints() const
virtual ~QtCanvasSprite()
bool collidesWith(const QtCanvasItem *) const
virtual void setFrameAnimation(FrameAnimationType=Cycle, int step=1, int state=0)
void setSequence(QtCanvasPixmapArray *seq)
QtCanvasPixmap * image() const
virtual void advance(int stage)
virtual QtCanvasPixmap * imageAdvanced() const
QRect boundingRect() const
void draw(QPainter &painter)
void move(double x, double y)
void setText(const QString &)
virtual void draw(QPainter &)
bool collidesWith(const QtCanvasItem *) const
void moveBy(double dx, double dy)
QRect boundingRect() const
void setFont(const QFont &)
void setColor(const QColor &)
virtual void drawContents(QPainter *p, int cx, int cy, int cw, int ch)
const QMatrix & worldMatrix() const
virtual void contentsMouseDoubleClickEvent(QMouseEvent *)
void setCanvas(QtCanvas *v)
QtCanvasView(QWidget *parent=0)
bool setWorldMatrix(const QMatrix &)
virtual void contentsMouseReleaseEvent(QMouseEvent *)
virtual void contentsDragEnterEvent(QDragEnterEvent *)
QtCanvas * canvas() const
void setHighQualityRendering(bool enable)
virtual void contentsWheelEvent(QWheelEvent *)
const QMatrix & inverseWorldMatrix() const
virtual void contentsDropEvent(QDropEvent *)
virtual void contentsMouseMoveEvent(QMouseEvent *)
virtual void contentsMousePressEvent(QMouseEvent *)
virtual void contentsDragLeaveEvent(QDragLeaveEvent *)
virtual QSize sizeHint() const
virtual void contentsContextMenuEvent(QContextMenuEvent *)
virtual void contentsDragMoveEvent(QDragMoveEvent *)
bool highQualityRendering
virtual void setAllChanged()
void drawViewArea(QtCanvasView *view, QPainter *p, const QRect &r, bool dbuf)
virtual void setBackgroundColor(const QColor &c)
virtual void setTiles(QPixmap tiles, int h, int v, int tilewidth, int tileheight)
QtCanvas(QObject *parent=0)
int tile(int x, int y) const
QtCanvasItemList collisions(const QPoint &) const
virtual void setAdvancePeriod(int ms)
virtual void setUnchanged(const QRect &area)
virtual void setTile(int x, int y, int tilenum)
int tilesHorizontally() const
virtual void setUpdatePeriod(int ms)
void drawArea(const QRect &, QPainter *p, bool double_buffer=false)
virtual void setChanged(const QRect &area)
virtual void resize(int width, int height)
bool validChunk(int x, int y) const
virtual void addView(QtCanvasView *)
virtual void drawBackground(QPainter &, const QRect &area)
virtual void setBackgroundPixmap(const QPixmap &p)
void removeItemFromChunkContaining(QtCanvasItem *, int x, int y)
virtual void setChangedChunk(int i, int j)
void removeItemFromChunk(QtCanvasItem *, int i, int j)
QPixmap backgroundPixmap() const
virtual void removeItem(QtCanvasItem *)
virtual void removeAnimation(QtCanvasItem *)
virtual void removeView(QtCanvasView *)
void addItemToChunkContaining(QtCanvasItem *, int x, int y)
QColor backgroundColor() const
virtual void addItem(QtCanvasItem *)
virtual void addAnimation(QtCanvasItem *)
void drawCanvasArea(const QRect &, QPainter *p=0, bool double_buffer=true)
QtCanvasItemList allItems()
int tilesVertically() const
void addItemToChunk(QtCanvasItem *, int i, int j)
virtual void setChangedChunkContaining(int x, int y)
virtual void retune(int chunksize, int maxclusters=100)
virtual void drawForeground(QPainter &, const QRect &area)
virtual void processSpans(int n, QPoint *point, int *width)=0
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)
void scan(const QPolygon &pa, bool winding, int index, int npoints, Edge edges)
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
bool contains(const MemoryID &general, const MemoryID &specific)
Indicates whether general is "less specific" than, or equal to, specific, i.e.
double s(double t, double s0, double v0, double a0, double j)
double a(double t, double a0, double j)
double v(double t, double v0, double a0, double j)
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< T > abs(const std::vector< T > &v)
constexpr auto n() noexcept
bool intersects(const Circlef &circle, const Segment2D &segment)
double angle(const Point &a, const Point &b, const Point &c)
struct _EdgeTableEntry * back
struct _EdgeTableEntry * nextWETE
struct _EdgeTableEntry * next
ScanLineList SLLs[SLLSPERBLOCK]
struct _ScanLineListBlock * next
EdgeTableEntry * edgelist
struct _ScanLineList * next