]> Shamusworld >> Repos - architektonas/blob - src/base/rs_painterqt.cpp.old
Changed RS_Graphic to Drawing; this is less confusing as a drawing is
[architektonas] / src / base / rs_painterqt.cpp.old
1 /****************************************************************************
2 ** $Id: rs_painterqt.cpp 2244 2005-03-14 23:00:19Z andrew $
3 **
4 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
5 **
6 ** This file is part of the qcadlib Library project.
7 **
8 ** This file may be distributed and/or modified under the terms of the
9 ** GNU General Public License version 2 as published by the Free Software
10 ** Foundation and appearing in the file LICENSE.GPL included in the
11 ** packaging of this file.
12 **
13 ** Licensees holding valid qcadlib Professional Edition licenses may use
14 ** this file in accordance with the qcadlib Commercial License
15 ** Agreement provided with the Software.
16 **
17 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 **
20 ** See http://www.ribbonsoft.com for further details.
21 **
22 ** Contact info@ribbonsoft.com if any conditions of this licensing are
23 ** not clear to you.
24 **
25 **********************************************************************/
26
27 #include "rs_painterqt.h"
28
29 #include <stdio.h>
30 //#include <q3paintdevicemetrics.h>
31 #include "rs_math.h"
32 #include "rs_application.h"
33 #include "rs_color.h"
34
35 /**
36  * Constructor.
37  */
38 //WAS: RS_PainterQt::RS_PainterQt(const QPaintDevice * pd)
39 RS_PainterQt::RS_PainterQt(QPaintDevice * pd): QPainter(pd), RS_Painter()
40 {
41 }
42
43 /**
44  * Destructor
45  */
46 RS_PainterQt::~RS_PainterQt()
47 {
48 }
49
50 #if 0
51 // These two look like bogus crap to me...
52 void RS_PainterQt::moveTo(int x, int y)
53 {
54 //      QPainter::moveTo(x, y);
55         cursorX = x, cursorY = y;
56 }
57
58 void RS_PainterQt::lineTo(int x, int y)
59 {
60 //      QPainter::lineTo(x, y);
61         QPainter::drawLine(cursorX, cursorY, x, y);
62         cursorX = x, cursorY = y;
63 }
64 #endif
65
66 /**
67  * Draws a grid point at (x1, y1).
68  */
69 void RS_PainterQt::drawGridPoint(const Vector & p)
70 {
71         QPainter::drawPoint(toScreenX(p.x), toScreenY(p.y));
72 }
73
74 /**
75  * Draws a point at (x1, y1).
76  */
77 void RS_PainterQt::drawPoint(const Vector & p)
78 {
79     QPainter::drawLine(toScreenX(p.x - 1), toScreenY(p.y), toScreenX(p.x + 1), toScreenY(p.y));
80     QPainter::drawLine(toScreenX(p.x), toScreenY(p.y - 1), toScreenX(p.x), toScreenY(p.y + 1));
81 }
82
83 /**
84  * Draws a line from (x1, y1) to (x2, y2).
85  */
86 void RS_PainterQt::drawLine(const Vector & p1, const Vector & p2)
87 {
88 #ifdef __APPLE__
89         int w2 = (int)getPen().getScreenWidth() / 2;
90         QPainter::drawLine(toScreenX(p1.x - w2), toScreenY(p1.y - w2),
91                 toScreenX(p2.x - w2), toScreenY(p2.y - w2));
92 #else
93         QPainter::drawLine(toScreenX(p1.x), toScreenY(p1.y), toScreenX(p2.x), toScreenY(p2.y));
94 #endif
95 }
96
97 /**
98  * Draws a rectangle with corners p1, p2.
99  */
100 /*void RS_PainterQt::drawRect(const Vector& p1, const Vector& p2) {
101         / *QPainter::drawRect(toScreenX(p1.x), toScreenY(p1.y),
102                                            abs(toScreenX(p2.x) - toScreenX(p1.x)),
103                                            abs(toScreenY(p2.y) - toScreenY(p1.y)));* /
104         QPainter::drawLine(toScreenX(p1.x), toScreenY(p1.y),
105                        toScreenX(p2.x), toScreenY(p1.y));
106     QPainter::drawLine(toScreenX(p2.x), toScreenY(p1.y),
107                        toScreenX(p2.x), toScreenY(p2.y));
108     QPainter::drawLine(toScreenX(p2.x), toScreenY(p2.y),
109                        toScreenX(p1.x), toScreenY(p2.y));
110     QPainter::drawLine(toScreenX(p1.x), toScreenY(p2.y),
111                        toScreenX(p1.x), toScreenY(p1.y));
112 }*/
113
114 /**
115  * Draws an arc which starts / ends exactly at the given coordinates.
116  *
117  * @param cx center in x
118  * @param cy center in y
119  * @param radius Radius
120  * @param a1 Angle 1 in rad
121  * @param a2 Angle 2 in rad
122  * @param x1 startpoint x
123  * @param y1 startpoint y
124  * @param x2 endpoint x
125  * @param y2 endpoint y
126  * @param reversed true: clockwise, false: counterclockwise
127  */
128 void RS_PainterQt::drawArc(const Vector & cp, double radius,
129         double a1, double a2, const Vector & p1, const Vector & p2,
130         bool reversed)
131 {
132         /*
133         QPainter::drawArc(cx-radius, cy-radius,
134                                         2*radius, 2*radius,
135                                         a1*16, (a2-a1)*16);
136         */
137
138         if (radius <= 0.5)
139                 drawGridPoint(cp);
140         else
141         {
142 #ifdef __APPLE__
143                 drawArcMac(cp, radius, a1, a2, reversed);
144 #else
145                 int   cix;            // Next point on circle
146                 int   ciy;            //
147                 double aStep;         // Angle Step (rad)
148                 double a;             // Current Angle (rad)
149                 double linStep;       // linear step (pixels)
150
151                 if (drawingMode == RS2::ModePreview)
152                         linStep = 20.0;
153                 else
154                         linStep = 6.0;
155
156                 if (fabs(linStep / radius) <= 1.0)
157                         aStep = asin(linStep / radius);
158                 else
159                         aStep = 1.0;
160
161                 if (aStep < 0.05)
162                         aStep = 0.05;
163
164                 if (!reversed)
165                 {
166                         // Arc Counterclockwise:
167                         if (a1 > a2 - 1.0e-10)
168                                 a2 += 2 * M_PI;
169
170 #ifdef __USE_DEPRECATED_QT3__
171                         //moveTo(toScreenX(p1.x), toScreenY(p1.y));
172                         Q3PointArray pa;
173                         int i = 0;
174                         pa.resize(i + 1);
175                         pa.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
176
177                         for(a=a1+aStep; a<=a2; a+=aStep)
178                         {
179                                 cix = toScreenX(cp.x + cos(a) * radius);
180                                 ciy = toScreenY(cp.y - sin(a) * radius);
181                                 //lineTo(cix, ciy);
182                                 pa.resize(i + 1);
183                                 pa.setPoint(i++, cix, ciy);
184                         }
185
186                         //lineTo(toScreenX(p2.x), toScreenY(p2.y));
187                         pa.resize(i + 1);
188                         pa.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
189                         drawPolyline(pa);
190 #else
191                         QPolygon poly;
192                         int i = 0;
193 //                      pa.resize(i + 1);
194                         poly.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
195
196                         for(a=a1+aStep; a<=a2; a+=aStep)
197                         {
198                                 cix = toScreenX(cp.x + cos(a) * radius);
199                                 ciy = toScreenY(cp.y - sin(a) * radius);
200                                 //lineTo(cix, ciy);
201 //                              pa.resize(i + 1);
202                                 poly.setPoint(i++, cix, ciy);
203                         }
204
205                         //lineTo(toScreenX(p2.x), toScreenY(p2.y));
206 //                      pa.resize(i + 1);
207                         poly.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
208                         drawPolygon(poly);
209 #endif
210                 }
211                 else
212                 {
213                         // Arc Clockwise:
214                         if (a1 < a2 + 1.0e-10)
215                                 a2 -= 2 * M_PI;
216
217 #ifdef __USE_DEPRECATED_QT3__
218                         Q3PointArray pa;
219                         int i = 0;
220                         pa.resize(i + 1);
221                         pa.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
222                         //moveTo(toScreenX(p1.x), toScreenY(p1.y));
223
224                         for(a=a1-aStep; a>=a2; a-=aStep)
225                         {
226                                 cix = toScreenX(cp.x + cos(a) * radius);
227                                 ciy = toScreenY(cp.y - sin(a) * radius);
228                                 //lineTo(cix, ciy);
229                                 pa.resize(i + 1);
230                                 pa.setPoint(i++, cix, ciy);
231                         }
232
233                         //lineTo(toScreenX(p2.x), toScreenY(p2.y));
234                         pa.resize(i + 1);
235                         pa.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
236                         drawPolyline(pa);
237 #else
238                         QPolygon poly;
239                         int i = 0;
240                         poly.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
241
242                         for(a=a1-aStep; a>=a2; a-=aStep)
243                         {
244                                 cix = toScreenX(cp.x + cos(a) * radius);
245                                 ciy = toScreenY(cp.y - sin(a) * radius);
246                                 poly.setPoint(i++, cix, ciy);
247                         }
248
249                         poly.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
250                         drawPolygon(poly);
251 #endif
252                 }
253 #endif
254         }
255 }
256
257 /**
258  * Draws an arc.
259  *
260  * @param cx center in x
261  * @param cy center in y
262  * @param radius Radius
263  * @param a1 Angle 1 in rad
264  * @param a2 Angle 2 in rad
265  * @param reversed true: clockwise, false: counterclockwise
266  */
267 void RS_PainterQt::drawArc(const Vector & cp, double radius, double a1, double a2, bool reversed)
268 {
269     if (radius <= 0.5)
270         drawGridPoint(cp);
271     else
272         {
273 #ifdef __APPLE__
274                 drawArcMac(cp, radius, a1, a2, reversed);
275 #else
276         Q3PointArray pa;
277         createArc(pa, cp, radius, a1, a2, reversed);
278         drawPolyline(pa);
279 #endif
280     }
281 }
282
283 /**
284  * Draws an arc on apple.
285  *
286  * @param cx center in x
287  * @param cy center in y
288  * @param radius Radius
289  * @param a1 Angle 1 in rad
290  * @param a2 Angle 2 in rad
291  * @param reversed true: clockwise, false: counterclockwise
292  */
293 void RS_PainterQt::drawArcMac(const Vector& cp, double radius, double a1, double a2, bool reversed)
294 {
295         RS_DEBUG->print("RS_PainterQt::drawArcMac");
296         if (radius <= 0.5)
297                 drawGridPoint(cp);
298         else
299         {
300                 double cix;            // Next point on circle
301                 double ciy;            //
302                 double aStep;         // Angle Step (rad)
303                 double a;             // Current Angle (rad)
304                 double ox;
305                 double oy;
306
307                 if (2.0 / radius <= 1.0)
308                         aStep = asin(2.0 / radius);
309                 else
310                         aStep = 1.0;
311
312                 if (aStep < 0.05)
313                         aStep = 0.05;
314
315                 ox = cp.x + cos(a1) * radius;
316                 oy = cp.y - sin(a1) * radius;
317
318                 if (!reversed)
319                 {
320                         // Arc Counterclockwise:
321                         if (a1 > a2 - 1.0e-10)
322                                 a2 += 2 * M_PI;
323
324                         for(a=a1+aStep; a<=a2; a+=aStep)
325                         {
326                                 cix = cp.x + cos(a) * radius;
327                                 ciy = cp.y - sin(a) * radius;
328                                 drawLine(Vector(ox, oy), Vector(cix, ciy));
329                                 ox = cix;
330                                 oy = ciy;
331                         }
332                 }
333                 else
334                 {
335                         // Arc Clockwise:
336                         if (a1 < a2 + 1.0e-10)
337                                 a2 -= 2 * M_PI;
338
339                         for(a=a1-aStep; a>=a2; a-=aStep)
340                         {
341                                 cix = cp.x + cos(a) * radius;
342                                 ciy = cp.y - sin(a) * radius;
343                                 drawLine(Vector(ox, oy), Vector(cix, ciy));
344                                 ox = cix;
345                                 oy = ciy;
346                         }
347                 }
348
349                 drawLine(Vector(ox, oy), Vector(cp.x + cos(a2) * radius, cp.y - sin(a2) * radius));
350         }
351 }
352
353 /**
354  * Draws a circle.
355  * @param cx center in x
356  * @param cy center in y
357  * @param radius Radius
358  */
359 void RS_PainterQt::drawCircle(const Vector & cp, double radius)
360 {
361         if (drawingMode == RS2::ModeXOR && radius < 500)
362         {
363                 // This is _very_ slow for large arcs:
364                 QPainter::drawEllipse(toScreenX(cp.x - radius), toScreenY(cp.y - radius), RS_Math::round(2.0 * radius), RS_Math::round(2.0 * radius));
365         }
366         else
367         {
368 #ifdef __APPLE__
369                 drawArcMac(cp, radius, 0.0, 2 * M_PI, false);
370 #else
371                 drawArc(cp, radius, 0.0, 2 * M_PI, cp + Vector(radius, 0.0), cp + Vector(radius, 0.0), false);
372 #endif
373         }
374 }
375
376 /**
377  * Draws a rotated ellipse arc.
378  */
379 void RS_PainterQt::drawEllipse(const Vector & cp, double radius1, double radius2,
380         double angle, double a1, double a2, bool reversed)
381 {
382         double aStep;         // Angle Step (rad)
383         double a;             // Current Angle (rad)
384
385         // Angle step in rad
386         aStep = 0.01;
387
388         Vector vp;
389         Vector vc(cp.x, cp.y);
390         vp.set(cp.x + cos(a1) * radius1, cp.y - sin(a1) * radius2);
391         vp.rotate(vc, -angle);
392 //    moveTo(toScreenX(vp.x), toScreenY(vp.y));
393
394         if (!reversed)
395         {
396                 // Arc Counterclockwise:
397                 if (a1 > a2 - RS_TOLERANCE)
398                         a2 += 2 * M_PI;
399
400                 for(a=a1+aStep; a<=a2; a+=aStep)
401                 {
402                         Vector last = vp;
403                         vp.set(cp.x + cos(a) * radius1, cp.y - sin(a) * radius2);
404                         vp.rotate(vc, -angle);
405 //            lineTo(toScreenX(vp.x), toScreenY(vp.y));
406                         drawLine(Vector(toScreenX(last.x), toScreenY(last.y)),
407                                 Vector(toScreenX(vp.x), toScreenY(vp.y)));
408                 }
409         }
410         else
411         {
412                 // Arc Clockwise:
413                 if (a1 < a2 + RS_TOLERANCE)
414                         a2 -= 2 * M_PI;
415
416                 for(a=a1-aStep; a>=a2; a-=aStep)
417                 {
418                         Vector last = vp;
419                         vp.set(cp.x + cos(a) * radius1, cp.y - sin(a) * radius2);
420                         vp.rotate(vc, -angle);
421 //            lineTo(toScreenX(vp.x), toScreenY(vp.y));
422                         drawLine(Vector(toScreenX(last.x), toScreenY(last.y)),
423                                 Vector(toScreenX(vp.x), toScreenY(vp.y)));
424                 }
425         }
426
427         Vector last = vp;
428         vp.set(cp.x + cos(a2) * radius1, cp.y - sin(a2) * radius2);
429         vp.rotate(vc, -angle);
430 //    lineTo(toScreenX(vp.x), toScreenY(vp.y));
431         drawLine(Vector(toScreenX(last.x), toScreenY(last.y)),
432                 Vector(toScreenX(vp.x), toScreenY(vp.y)));
433         //}
434 }
435
436 /**
437  * Draws image.
438  */
439 void RS_PainterQt::drawImg(QImage & img, const Vector & pos,
440         double angle, const Vector & factor, int sx, int sy, int sw, int sh)
441 {
442         save();
443
444         QMatrix wm;
445         wm.translate(pos.x, pos.y);
446         wm.scale(factor.x, factor.y);
447         wm.rotate(RS_Math::rad2deg(-angle));
448         setWorldMatrix(wm);
449
450         if (fabs(angle) < 1.0e-4)
451                 drawImage(0 + sx, -img.height() + sy, img, sx, sy, sw, sh);
452         else
453                 drawImage(0, -img.height(), img);
454
455         restore();
456 }
457
458 #if 0
459 void RS_PainterQt::drawTextH(int x1, int y1, int x2, int y2, const QString & text)
460 {
461     drawText(x1, y1, x2, y2, Qt::AlignRight | Qt::AlignVCenter, text);
462 }
463
464 void RS_PainterQt::drawTextV(int x1, int y1, int x2, int y2, const QString & text)
465 {
466         save();
467         QMatrix wm = worldMatrix();
468         wm.rotate(-90.0);
469         setWorldMatrix(wm);
470         //rotate(-90.0);
471         drawText(x1, y1, x2, y2, Qt::AlignRight | Qt::AlignVCenter, text);
472         restore();
473 }
474 #endif
475
476 void RS_PainterQt::fillRect(int x1, int y1, int w, int h, const RS_Color & col)
477 {
478         QPainter::fillRect(x1, y1, w, h, col);
479 }
480
481 void RS_PainterQt::fillTriangle(const Vector & p1, const Vector & p2, const Vector & p3)
482 {
483 #if __USE_DEPRECATED_QT3__
484         Q3PointArray arr(3);
485         arr.putPoints(0, 3, toScreenX(p1.x),toScreenY(p1.y), toScreenX(p2.x),toScreenY(p2.y), toScreenX(p3.x),toScreenY(p3.y));
486         setBrush(pen().color());
487         drawPolygon(arr);
488 #else
489         QPolygon poly(3);
490         poly.putPoints(0, 3, toScreenX(p1.x),toScreenY(p1.y), toScreenX(p2.x),toScreenY(p2.y), toScreenX(p3.x),toScreenY(p3.y));
491         setBrush(pen().color());
492         drawPolygon(poly);
493 #endif
494 }
495
496 void RS_PainterQt::erase()
497 {
498         QPainter::eraseRect(0, 0, getWidth(), getHeight());
499 }
500
501 int RS_PainterQt::getWidth()
502 {
503 //      Q3PaintDeviceMetrics m(device());
504 //      return m.width();
505         return device()->width();
506 }
507
508 int RS_PainterQt::getHeight()
509 {
510 //      Q3PaintDeviceMetrics m(device());
511 //      return m.height();
512         return device()->height();
513 }
514
515 void RS_PainterQt::setPreviewPen()
516 {
517 //      setPen(QColor(0, 255, 255));
518         setPen(RS_Color(0, 255, 255));
519 }
520
521 RS_Pen RS_PainterQt::getPen()
522 {
523         return lpen;
524         //RS_Pen p(pen().color(),
525         //         RS2::qw(pen().width()),
526         //         RS2::qw(pen().style()));
527         //return QPainter::pen();
528         //return p;
529 }
530
531 void RS_PainterQt::setPen(const RS_Pen & pen)
532 {
533         lpen = pen;
534
535 //#warning "!!! Removing B/W restriction in RS_PainterQt::setPen()... !!!"
536         if (drawingMode == RS2::ModeBW)
537                 lpen.setColor(RS_Color(0, 0, 0));
538
539         QPen p(lpen.getColor(), RS_Math::round(lpen.getScreenWidth()), RS2::rsToQtLineType(lpen.getLineType()));
540         p.setJoinStyle(Qt::RoundJoin);
541         p.setCapStyle(Qt::RoundCap);
542         QPainter::setPen(p);
543 }
544
545 void RS_PainterQt::setPen(const RS_Color & color)
546 {
547         if (drawingMode == RS2::ModeBW)
548         {
549                 lpen.setColor(RS_Color(0, 0, 0));
550                 QPainter::setPen(RS_Color(0, 0, 0));
551         }
552         else
553         {
554                 lpen.setColor(color);
555                 QPainter::setPen(color);
556         }
557 }
558
559 void RS_PainterQt::setPen(int r, int g, int b)
560 {
561         if (drawingMode == RS2::ModeBW)
562                 setPen(QColor(0, 0, 0));
563         else
564                 setPen(QColor(r, g, b));
565 }
566
567 void RS_PainterQt::disablePen()
568 {
569         lpen = RS_Pen(RS2::FlagInvalid);
570         QPainter::setPen(Qt::NoPen);
571 }
572
573 void RS_PainterQt::setBrush(const RS_Color & color)
574 {
575         if (drawingMode == RS2::ModeBW)
576                 QPainter::setBrush(QColor(0, 0, 0));
577         else
578                 QPainter::setBrush(color);
579 }
580
581 void RS_PainterQt::drawPolygon(const Q3PointArray & a)
582 {
583         QPainter::drawPolygon(a);
584 }
585
586 //void RS_PainterQt::setColor(const QColor& color) {
587 //      setPen(color);
588 //}
589
590 void RS_PainterQt::setXORMode()
591 {
592 //WAS:    setRasterOp(XorROP);
593         setCompositionMode(QPainter::CompositionMode_Xor);
594 }
595
596 void RS_PainterQt::setNormalMode()
597 {
598 //WAS:    setRasterOp(CopyROP);
599         setCompositionMode(QPainter::CompositionMode_SourceOver);
600 }
601
602 void RS_PainterQt::setClipRect(int x, int y, int w, int h)
603 {
604         QPainter::setClipRect(x, y, w, h);
605         setClipping(true);
606 }
607
608 void RS_PainterQt::resetClipping()
609 {
610         setClipping(false);
611 }
612