]> Shamusworld >> Repos - architektonas/blob - src/painter.cpp
Added missing files. D'oh!
[architektonas] / src / painter.cpp
1 //
2 // painter.cpp: Paint abstraction layer between Archtektonas and Qt
3 //
4 // Part of the Architektonas Project
5 // (C) 2011 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // WHO  WHEN        WHAT
11 // ---  ----------  ------------------------------------------------------------
12 // JLH  09/20/2011  Created this file
13 //
14
15 #include "painter.h"
16
17 #include "mathconstants.h"
18
19
20 // Set class variable defaults
21 Vector Painter::origin(-10.0, -10.0);
22 double Painter::zoom = 1.0;
23 Vector Painter::screenSize(200.0, 200.0);
24
25
26 Painter::Painter(QPainter * p/*= NULL*/): painter(p)
27 {
28 }
29
30 Painter::~Painter()
31 {
32 }
33
34 Vector Painter::CartesianToQtCoords(Vector v)
35 {
36         // Convert regular Cartesian coordinates to the inverted Y-axis Qt coordinates
37         // at the current origin and zoom level.
38         return Vector((v.x - origin.x) * zoom, screenSize.y - ((v.y - origin.y) * zoom));
39 }
40
41 Vector Painter::QtCoordsToCartesian(Vector v)
42 {
43         // Convert screen location, with inverted Y-axis coordinates, to regular
44         // Cartesian coordinates at the current zoom level.
45         return Vector((v.x / zoom) + origin.x, ((screenSize.y - v.y) / zoom) + origin.y);
46 /*
47 How to do it:
48
49 e.g., we have a point on the screen at Qt coords of 10, 10, screenSize is 100, 100.
50 origin is -10, -10 and zoom level is 2 (200%)
51
52 1st, invert the Y: 10, 10 -> 10, 90
53 2nd, add origin:   10, 90 ->  0, 80 (no, not right--err, yes, it is)
54 3rd, aply zoom:     0, 80 ->  0, 40
55
56 or, is it:
57
58 1st, invert the Y: 10, 10 -> 10, 90
59 2nd, aply zoom:    10, 90 ->  5, 45
60 3rd, add origin:    5, 45 -> -5, 35
61
62 it depends on whether or not origin is in Qt coords or cartesian. If Qt, then the 1st
63 is correct, otherwise, the 2nd is correct.
64
65 The way we calculate the Cartesian to Qt shows the 2nd (origin is cartesian) to be correct.
66 */
67 }
68
69 void Painter::SetRenderHint(int hint)
70 {
71         if (!painter)
72                 return;
73
74         painter->setRenderHint((QPainter::RenderHint)hint);
75 }
76
77 void Painter::SetBrush(QBrush brush)
78 {
79         if (!painter)
80                 return;
81
82         painter->setBrush(brush);
83 }
84
85 void Painter::SetFont(QFont font)
86 {
87         if (!painter)
88                 return;
89
90         painter->setFont(font);
91 }
92
93 void Painter::SetPen(QPen pen)
94 {
95         if (!painter)
96                 return;
97
98         painter->setPen(pen);
99 }
100
101 void Painter::DrawAngledText(Vector center, double angle, QString text)
102 {
103         center = CartesianToQtCoords(center);
104
105         // We may need this stuff... If dimension text is large enough.
106 //      int textWidth = QFontMetrics(painter->font()).width(text);
107 //      int textHeight = QFontMetrics(painter->font()).height();
108         QRectF textBox(-100, -100, 200, 200);   // x, y, w, h; x/y = upper left corner
109
110         // Some things to note here: if angle > 90 degrees, then we need to take the negative
111         // of the angle for our text.
112         painter->save();
113         painter->translate(center.x, center.y);
114         // This is in pixels. Might not render correctly at all zoom levels.
115         // Need to figure out if dimensions are always rendered at one size regardless of zoom,
116         // or if they have a definite size, and are thus zoomable.
117         // If zoomable, this is incorrect:
118         int yOffset = -12;
119
120         //Fix text so it isn't upside down...
121         if ((angle > PI * 0.5) && (angle < PI * 1.5))
122         {
123                 angle += PI;
124                 yOffset = 12;
125         }
126
127         textBox.translate(0, yOffset);
128         // Angles are backwards in the Qt coord system...
129         painter->rotate(-angle * RADIANS_TO_DEGREES);
130         painter->drawText(textBox, Qt::AlignCenter, text);
131         painter->restore();
132 }
133
134 void Painter::DrawArc(Vector center, double radius, double startAngle, double span)
135 {
136         center = CartesianToQtCoords(center);
137         QRectF rectangle(QPointF(center.x - radius, center.y - radius),
138                 QPointF(center.x + radius, center.y + radius));
139         int angle1 = (int)(startAngle * RADIANS_TO_DEGREES * 16.0);
140         int angle2 = (int)(span * RADIANS_TO_DEGREES * 16.0);
141         painter->drawArc(rectangle, angle1, angle2);
142 }
143
144 void Painter::DrawEllipse(Vector center, double axis1, double axis2)
145 {
146         center = CartesianToQtCoords(center);
147         painter->drawEllipse(QPointF(center.x, center.y), axis1, axis2);
148 }
149
150 void Painter::DrawLine(int x1, int y1, int x2, int y2)
151 {
152         if (!painter)
153                 return;
154
155         Vector v1 = CartesianToQtCoords(Vector(x1, y1));
156         Vector v2 = CartesianToQtCoords(Vector(x2, y2));
157         painter->drawLine(v1.x, v1.y, v2.x, v2.y);
158 }
159
160 void Painter::DrawLine(Vector v1, Vector v2)
161 {
162         if (!painter)
163                 return;
164
165         v1 = CartesianToQtCoords(v1);
166         v2 = CartesianToQtCoords(v2);
167         painter->drawLine(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y));
168 }
169
170 void Painter::DrawPoint(int x, int y)
171 {
172         if (!painter)
173                 return;
174
175         Vector v = CartesianToQtCoords(Vector(x, y));
176         painter->drawPoint(v.x, v.y);
177 }
178
179 void Painter::DrawRoundedRect(QRectF rect, double radiusX, double radiusY)
180 {
181         if (!painter)
182                 return;
183
184         painter->drawRoundedRect(rect, radiusX, radiusY);
185 }
186
187 void Painter::DrawText(QRectF rect, int type, QString text)
188 {
189         if (!painter)
190                 return;
191
192         painter->drawText(rect, (Qt::AlignmentFlag)type, text);
193 }
194