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;
+      }
+    }
+  }
+}