--- /dev/null
+//
+// painter.cpp: Paint abstraction layer between Archtektonas and Qt
+//
+// Part of the Architektonas Project
+// (C) 2011 Underground Software
+// See the README and GPLv3 files for licensing and warranty information
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 09/20/2011 Created this file
+//
+
+#include "painter.h"
+
+#include "mathconstants.h"
+
+
+// Set class variable defaults
+Vector Painter::origin(-10.0, -10.0);
+double Painter::zoom = 1.0;
+Vector Painter::screenSize(200.0, 200.0);
+
+
+Painter::Painter(QPainter * p/*= NULL*/): painter(p)
+{
+}
+
+Painter::~Painter()
+{
+}
+
+Vector Painter::CartesianToQtCoords(Vector v)
+{
+ // Convert regular Cartesian coordinates to the inverted Y-axis Qt coordinates
+ // at the current origin and zoom level.
+ return Vector((v.x - origin.x) * zoom, screenSize.y - ((v.y - origin.y) * zoom));
+}
+
+Vector Painter::QtCoordsToCartesian(Vector v)
+{
+ // Convert screen location, with inverted Y-axis coordinates, to regular
+ // Cartesian coordinates at the current zoom level.
+ return Vector((v.x / zoom) + origin.x, ((screenSize.y - v.y) / zoom) + origin.y);
+/*
+How to do it:
+
+e.g., we have a point on the screen at Qt coords of 10, 10, screenSize is 100, 100.
+origin is -10, -10 and zoom level is 2 (200%)
+
+1st, invert the Y: 10, 10 -> 10, 90
+2nd, add origin: 10, 90 -> 0, 80 (no, not right--err, yes, it is)
+3rd, aply zoom: 0, 80 -> 0, 40
+
+or, is it:
+
+1st, invert the Y: 10, 10 -> 10, 90
+2nd, aply zoom: 10, 90 -> 5, 45
+3rd, add origin: 5, 45 -> -5, 35
+
+it depends on whether or not origin is in Qt coords or cartesian. If Qt, then the 1st
+is correct, otherwise, the 2nd is correct.
+
+The way we calculate the Cartesian to Qt shows the 2nd (origin is cartesian) to be correct.
+*/
+}
+
+void Painter::SetRenderHint(int hint)
+{
+ if (!painter)
+ return;
+
+ painter->setRenderHint((QPainter::RenderHint)hint);
+}
+
+void Painter::SetBrush(QBrush brush)
+{
+ if (!painter)
+ return;
+
+ painter->setBrush(brush);
+}
+
+void Painter::SetFont(QFont font)
+{
+ if (!painter)
+ return;
+
+ painter->setFont(font);
+}
+
+void Painter::SetPen(QPen pen)
+{
+ if (!painter)
+ return;
+
+ painter->setPen(pen);
+}
+
+void Painter::DrawAngledText(Vector center, double angle, QString text)
+{
+ center = CartesianToQtCoords(center);
+
+ // We may need this stuff... If dimension text is large enough.
+// int textWidth = QFontMetrics(painter->font()).width(text);
+// int textHeight = QFontMetrics(painter->font()).height();
+ QRectF textBox(-100, -100, 200, 200); // x, y, w, h; x/y = upper left corner
+
+ // Some things to note here: if angle > 90 degrees, then we need to take the negative
+ // of the angle for our text.
+ painter->save();
+ painter->translate(center.x, center.y);
+ // This is in pixels. Might not render correctly at all zoom levels.
+ // Need to figure out if dimensions are always rendered at one size regardless of zoom,
+ // or if they have a definite size, and are thus zoomable.
+ // If zoomable, this is incorrect:
+ int yOffset = -12;
+
+ //Fix text so it isn't upside down...
+ if ((angle > PI * 0.5) && (angle < PI * 1.5))
+ {
+ angle += PI;
+ yOffset = 12;
+ }
+
+ textBox.translate(0, yOffset);
+ // Angles are backwards in the Qt coord system...
+ painter->rotate(-angle * RADIANS_TO_DEGREES);
+ painter->drawText(textBox, Qt::AlignCenter, text);
+ painter->restore();
+}
+
+void Painter::DrawArc(Vector center, double radius, double startAngle, double span)
+{
+ center = CartesianToQtCoords(center);
+ QRectF rectangle(QPointF(center.x - radius, center.y - radius),
+ QPointF(center.x + radius, center.y + radius));
+ int angle1 = (int)(startAngle * RADIANS_TO_DEGREES * 16.0);
+ int angle2 = (int)(span * RADIANS_TO_DEGREES * 16.0);
+ painter->drawArc(rectangle, angle1, angle2);
+}
+
+void Painter::DrawEllipse(Vector center, double axis1, double axis2)
+{
+ center = CartesianToQtCoords(center);
+ painter->drawEllipse(QPointF(center.x, center.y), axis1, axis2);
+}
+
+void Painter::DrawLine(int x1, int y1, int x2, int y2)
+{
+ if (!painter)
+ return;
+
+ Vector v1 = CartesianToQtCoords(Vector(x1, y1));
+ Vector v2 = CartesianToQtCoords(Vector(x2, y2));
+ painter->drawLine(v1.x, v1.y, v2.x, v2.y);
+}
+
+void Painter::DrawLine(Vector v1, Vector v2)
+{
+ if (!painter)
+ return;
+
+ v1 = CartesianToQtCoords(v1);
+ v2 = CartesianToQtCoords(v2);
+ painter->drawLine(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y));
+}
+
+void Painter::DrawPoint(int x, int y)
+{
+ if (!painter)
+ return;
+
+ Vector v = CartesianToQtCoords(Vector(x, y));
+ painter->drawPoint(v.x, v.y);
+}
+
+void Painter::DrawRoundedRect(QRectF rect, double radiusX, double radiusY)
+{
+ if (!painter)
+ return;
+
+ painter->drawRoundedRect(rect, radiusX, radiusY);
+}
+
+void Painter::DrawText(QRectF rect, int type, QString text)
+{
+ if (!painter)
+ return;
+
+ painter->drawText(rect, (Qt::AlignmentFlag)type, text);
+}
+