Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/vaclgui/agrect.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anagram/vaclgui/agrect.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,151 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1997-2002 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * agrect.cpp + */ + +#include "agrect.hpp" + + +AgQuadrant opposite(AgQuadrant corner) { + return (AgQuadrant) ((int) corner ^ 3); +} + +AgRectangle::AgRectangle(RECT r) { + pos = cint(r.left, r.top); + sz = cint(r.right - r.left, r.bottom - r.top); +} + +AgRectangle::AgRectangle(IWindow *w) : anchor(upperLeft) { + pos = w->position(); + sz = w->size(); +} + +AgRectangle::AgRectangle(cint size_) + : pos(0,0) + , sz(size_) + , anchor(upperLeft) +{} + +AgRectangle::AgRectangle(cint loc, cint size_, AgQuadrant whichQuadrant) + : pos(loc) + , sz(size_) + , anchor(whichQuadrant) +{ + switch (anchor) { + case upperRight: pos.y -= sz.y; break; + case upperLeft: pos.y -= sz.y; /* fallthrough */ + case lowerLeft: pos.x -= sz.x; break; + } +} + +cint AgRectangle::position(AgQuadrant whichCorner) { + cint where = pos; + switch (whichCorner) { + case lowerLeft: where.y += sz.y; break; + case lowerRight: where.y += sz.y; /* fallthrough */ + case upperRight: where.x += sz.x; break; + } + return where; +} + +AgRectangle &AgRectangle::setSize(cint s) { + cint pos = position(anchor); + sz = s; + switch (anchor) { + case upperRight: pos.y -= sz.y; break; + case upperLeft: pos.y -= sz.y; /* fallthrough */ + case lowerLeft: pos.x -= sz.x; break; + } + return *this; +} + +AgRectangle AgRectangle::intersection(AgRectangle &r) { + cint loc = lrci(pos, r.pos); + cint lr = ulci(pos+sz, r.pos + r.sz); + lr = lrci(loc,lr); + return AgRectangle(loc, lr - loc); +} + +AgRectangle &AgRectangle::limit(cint size) { + sz = ulci(sz, size); + pos = ulci(pos, size - sz); + pos = lrci(pos, cint(0, 0)); + return *this; +} + +AgRectangle AgRectangle::desktop() { + RECT r; + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + AgRectangle rect(r); + return rect; +} + +int AgRectangle::operator < (const AgRectangle &r) const { + if (pos < r.pos) { + return 1; + } + if (r.pos > pos) { + return 0; + } + return sz < r.sz; +} + +LayoutRef::LayoutRef(AgRectangle &r) { + int i; + for (i = upperLeft; i <= lowerRight; i++) { + AgQuadrant ic = (AgQuadrant) i; + corner[ic] = r.position(ic); + } + stack.push(r); +} + +int LayoutRef::overlap(AgRectangle &r) { + int n = stack.size(); + int area = 0; + while (n--) { + area += r.intersection(stack[n]).area(); + } + return area; +} + +void LayoutRef::merge(AgRectangle &r) { + stack.push(r); + int i; + for (i = upperLeft; i <= lowerRight; i++) { + AgQuadrant ic = (AgQuadrant) i; + cint rCorner = r.position(ic); + switch (ic) { + case upperLeft: { + if (rCorner.y < corner[ic].y + || rCorner.y == corner[ic].y && rCorner.x < corner[ic].x) { + corner[ic] = rCorner; + } + break; + } + case upperRight: { + if (rCorner.y < corner[ic].y + || rCorner.y == corner[ic].y && rCorner.x > corner[ic].x) { + corner[ic] = rCorner; + } + break; + } + case lowerLeft: { + if (rCorner.y > corner[ic].y + || rCorner.y == corner[ic].y && rCorner.x > corner[ic].x) { + corner[ic] = rCorner; + } + break; + } + case lowerRight: { + if (rCorner.y > corner[ic].y + || rCorner.y == corner[ic].y && rCorner.x > corner[ic].x) { + corner[ic] = rCorner; + } + break; + } + } + } +}