1 /****************************************************************************
2 ** $Id: rs_painterqt.cpp 2244 2005-03-14 23:00:19Z andrew $
4 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
6 ** This file is part of the qcadlib Library project.
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.
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.
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.
20 ** See http://www.ribbonsoft.com for further details.
22 ** Contact info@ribbonsoft.com if any conditions of this licensing are
25 **********************************************************************/
27 #include "rs_painterqt.h"
30 //#include <q3paintdevicemetrics.h>
32 #include "rs_application.h"
38 //WAS: RS_PainterQt::RS_PainterQt(const QPaintDevice * pd)
39 RS_PainterQt::RS_PainterQt(QPaintDevice * pd): QPainter(pd), RS_Painter()
46 RS_PainterQt::~RS_PainterQt()
51 // These two look like bogus crap to me...
52 void RS_PainterQt::moveTo(int x, int y)
54 // QPainter::moveTo(x, y);
55 cursorX = x, cursorY = y;
58 void RS_PainterQt::lineTo(int x, int y)
60 // QPainter::lineTo(x, y);
61 QPainter::drawLine(cursorX, cursorY, x, y);
62 cursorX = x, cursorY = y;
67 * Draws a grid point at (x1, y1).
69 void RS_PainterQt::drawGridPoint(const Vector & p)
71 QPainter::drawPoint(toScreenX(p.x), toScreenY(p.y));
75 * Draws a point at (x1, y1).
77 void RS_PainterQt::drawPoint(const Vector & p)
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));
84 * Draws a line from (x1, y1) to (x2, y2).
86 void RS_PainterQt::drawLine(const Vector & p1, const Vector & p2)
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));
93 QPainter::drawLine(toScreenX(p1.x), toScreenY(p1.y), toScreenX(p2.x), toScreenY(p2.y));
98 * Draws a rectangle with corners p1, p2.
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));
115 * Draws an arc which starts / ends exactly at the given coordinates.
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
128 void RS_PainterQt::drawArc(const Vector & cp, double radius,
129 double a1, double a2, const Vector & p1, const Vector & p2,
133 QPainter::drawArc(cx-radius, cy-radius,
143 drawArcMac(cp, radius, a1, a2, reversed);
145 int cix; // Next point on circle
147 double aStep; // Angle Step (rad)
148 double a; // Current Angle (rad)
149 double linStep; // linear step (pixels)
151 if (drawingMode == RS2::ModePreview)
156 if (fabs(linStep / radius) <= 1.0)
157 aStep = asin(linStep / radius);
166 // Arc Counterclockwise:
167 if (a1 > a2 - 1.0e-10)
170 #ifdef __USE_DEPRECATED_QT3__
171 //moveTo(toScreenX(p1.x), toScreenY(p1.y));
175 pa.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
177 for(a=a1+aStep; a<=a2; a+=aStep)
179 cix = toScreenX(cp.x + cos(a) * radius);
180 ciy = toScreenY(cp.y - sin(a) * radius);
183 pa.setPoint(i++, cix, ciy);
186 //lineTo(toScreenX(p2.x), toScreenY(p2.y));
188 pa.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
194 poly.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
196 for(a=a1+aStep; a<=a2; a+=aStep)
198 cix = toScreenX(cp.x + cos(a) * radius);
199 ciy = toScreenY(cp.y - sin(a) * radius);
202 poly.setPoint(i++, cix, ciy);
205 //lineTo(toScreenX(p2.x), toScreenY(p2.y));
207 poly.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
214 if (a1 < a2 + 1.0e-10)
217 #ifdef __USE_DEPRECATED_QT3__
221 pa.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
222 //moveTo(toScreenX(p1.x), toScreenY(p1.y));
224 for(a=a1-aStep; a>=a2; a-=aStep)
226 cix = toScreenX(cp.x + cos(a) * radius);
227 ciy = toScreenY(cp.y - sin(a) * radius);
230 pa.setPoint(i++, cix, ciy);
233 //lineTo(toScreenX(p2.x), toScreenY(p2.y));
235 pa.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
240 poly.setPoint(i++, toScreenX(p1.x), toScreenY(p1.y));
242 for(a=a1-aStep; a>=a2; a-=aStep)
244 cix = toScreenX(cp.x + cos(a) * radius);
245 ciy = toScreenY(cp.y - sin(a) * radius);
246 poly.setPoint(i++, cix, ciy);
249 poly.setPoint(i++, toScreenX(p2.x), toScreenY(p2.y));
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
267 void RS_PainterQt::drawArc(const Vector & cp, double radius, double a1, double a2, bool reversed)
274 drawArcMac(cp, radius, a1, a2, reversed);
277 createArc(pa, cp, radius, a1, a2, reversed);
284 * Draws an arc on apple.
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
293 void RS_PainterQt::drawArcMac(const Vector& cp, double radius, double a1, double a2, bool reversed)
295 RS_DEBUG->print("RS_PainterQt::drawArcMac");
300 double cix; // Next point on circle
302 double aStep; // Angle Step (rad)
303 double a; // Current Angle (rad)
307 if (2.0 / radius <= 1.0)
308 aStep = asin(2.0 / radius);
315 ox = cp.x + cos(a1) * radius;
316 oy = cp.y - sin(a1) * radius;
320 // Arc Counterclockwise:
321 if (a1 > a2 - 1.0e-10)
324 for(a=a1+aStep; a<=a2; a+=aStep)
326 cix = cp.x + cos(a) * radius;
327 ciy = cp.y - sin(a) * radius;
328 drawLine(Vector(ox, oy), Vector(cix, ciy));
336 if (a1 < a2 + 1.0e-10)
339 for(a=a1-aStep; a>=a2; a-=aStep)
341 cix = cp.x + cos(a) * radius;
342 ciy = cp.y - sin(a) * radius;
343 drawLine(Vector(ox, oy), Vector(cix, ciy));
349 drawLine(Vector(ox, oy), Vector(cp.x + cos(a2) * radius, cp.y - sin(a2) * radius));
355 * @param cx center in x
356 * @param cy center in y
357 * @param radius Radius
359 void RS_PainterQt::drawCircle(const Vector & cp, double radius)
361 if (drawingMode == RS2::ModeXOR && radius < 500)
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));
369 drawArcMac(cp, radius, 0.0, 2 * M_PI, false);
371 drawArc(cp, radius, 0.0, 2 * M_PI, cp + Vector(radius, 0.0), cp + Vector(radius, 0.0), false);
377 * Draws a rotated ellipse arc.
379 void RS_PainterQt::drawEllipse(const Vector & cp, double radius1, double radius2,
380 double angle, double a1, double a2, bool reversed)
382 double aStep; // Angle Step (rad)
383 double a; // Current Angle (rad)
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));
396 // Arc Counterclockwise:
397 if (a1 > a2 - RS_TOLERANCE)
400 for(a=a1+aStep; a<=a2; a+=aStep)
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)));
413 if (a1 < a2 + RS_TOLERANCE)
416 for(a=a1-aStep; a>=a2; a-=aStep)
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)));
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)));
439 void RS_PainterQt::drawImg(QImage & img, const Vector & pos,
440 double angle, const Vector & factor, int sx, int sy, int sw, int sh)
445 wm.translate(pos.x, pos.y);
446 wm.scale(factor.x, factor.y);
447 wm.rotate(RS_Math::rad2deg(-angle));
450 if (fabs(angle) < 1.0e-4)
451 drawImage(0 + sx, -img.height() + sy, img, sx, sy, sw, sh);
453 drawImage(0, -img.height(), img);
459 void RS_PainterQt::drawTextH(int x1, int y1, int x2, int y2, const QString & text)
461 drawText(x1, y1, x2, y2, Qt::AlignRight | Qt::AlignVCenter, text);
464 void RS_PainterQt::drawTextV(int x1, int y1, int x2, int y2, const QString & text)
467 QMatrix wm = worldMatrix();
471 drawText(x1, y1, x2, y2, Qt::AlignRight | Qt::AlignVCenter, text);
476 void RS_PainterQt::fillRect(int x1, int y1, int w, int h, const RS_Color & col)
478 QPainter::fillRect(x1, y1, w, h, col);
481 void RS_PainterQt::fillTriangle(const Vector & p1, const Vector & p2, const Vector & p3)
483 #if __USE_DEPRECATED_QT3__
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());
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());
496 void RS_PainterQt::erase()
498 QPainter::eraseRect(0, 0, getWidth(), getHeight());
501 int RS_PainterQt::getWidth()
503 // Q3PaintDeviceMetrics m(device());
505 return device()->width();
508 int RS_PainterQt::getHeight()
510 // Q3PaintDeviceMetrics m(device());
511 // return m.height();
512 return device()->height();
515 void RS_PainterQt::setPreviewPen()
517 // setPen(QColor(0, 255, 255));
518 setPen(RS_Color(0, 255, 255));
521 RS_Pen RS_PainterQt::getPen()
524 //RS_Pen p(pen().color(),
525 // RS2::qw(pen().width()),
526 // RS2::qw(pen().style()));
527 //return QPainter::pen();
531 void RS_PainterQt::setPen(const RS_Pen & pen)
535 //#warning "!!! Removing B/W restriction in RS_PainterQt::setPen()... !!!"
536 if (drawingMode == RS2::ModeBW)
537 lpen.setColor(RS_Color(0, 0, 0));
539 QPen p(lpen.getColor(), RS_Math::round(lpen.getScreenWidth()), RS2::rsToQtLineType(lpen.getLineType()));
540 p.setJoinStyle(Qt::RoundJoin);
541 p.setCapStyle(Qt::RoundCap);
545 void RS_PainterQt::setPen(const RS_Color & color)
547 if (drawingMode == RS2::ModeBW)
549 lpen.setColor(RS_Color(0, 0, 0));
550 QPainter::setPen(RS_Color(0, 0, 0));
554 lpen.setColor(color);
555 QPainter::setPen(color);
559 void RS_PainterQt::setPen(int r, int g, int b)
561 if (drawingMode == RS2::ModeBW)
562 setPen(QColor(0, 0, 0));
564 setPen(QColor(r, g, b));
567 void RS_PainterQt::disablePen()
569 lpen = RS_Pen(RS2::FlagInvalid);
570 QPainter::setPen(Qt::NoPen);
573 void RS_PainterQt::setBrush(const RS_Color & color)
575 if (drawingMode == RS2::ModeBW)
576 QPainter::setBrush(QColor(0, 0, 0));
578 QPainter::setBrush(color);
581 void RS_PainterQt::drawPolygon(const Q3PointArray & a)
583 QPainter::drawPolygon(a);
586 //void RS_PainterQt::setColor(const QColor& color) {
590 void RS_PainterQt::setXORMode()
592 //WAS: setRasterOp(XorROP);
593 setCompositionMode(QPainter::CompositionMode_Xor);
596 void RS_PainterQt::setNormalMode()
598 //WAS: setRasterOp(CopyROP);
599 setCompositionMode(QPainter::CompositionMode_SourceOver);
602 void RS_PainterQt::setClipRect(int x, int y, int w, int h)
604 QPainter::setClipRect(x, y, w, h);
608 void RS_PainterQt::resetClipping()