3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/28/2010 Added this text. :-)
17 #include "rs_constructionline.h"
19 #include "graphicview.h"
21 #include "paintintf.h"
26 RS_Image::RS_Image(RS_EntityContainer * parent, const RS_ImageData & d):
27 RS_AtomicEntity(parent), data(d)
43 RS_Entity * RS_Image::clone()
45 RS_Image * i = new RS_Image(*this);
46 i->setHandle(getHandle());
52 /** @return RS2::EntityImage */
53 /*virtual*/ RS2::EntityType RS_Image::rtti() const
55 return RS2::EntityImage;
58 void RS_Image::update()
60 RS_DEBUG->print("RS_Image::update");
63 //QImage image = QImage(data.file);
64 img = QImage(data.file);
67 data.size = Vector(img.width(), img.height());
69 RS_DEBUG->print("RS_Image::update: OK");
72 // number of small images:
73 nx = image.width()/100;
74 ny = image.height()/100;
76 // create small images:
77 img = new QImage*[nx];
80 for (int x = 0; x<nx; ++x) {
81 img[x] = new QImage[ny];
82 for (int y = 0; y<ny; ++y) {
87 w = image.width()%100;
94 h = image.height()%100;
98 RS_PainterQt painter(&pm);
99 painter.drawImage(-x*100, -y*100, image);
100 img[x][y] = pm.convertToImage();
106 /** @return Copy of data that defines the image. */
107 RS_ImageData RS_Image::getData() const
112 /** @return Insertion point of the entity */
113 /*virtual*/ Vector RS_Image::getInsertionPoint() const
115 return data.insertionPoint;
118 /** Sets the insertion point for the image. */
119 void RS_Image::setInsertionPoint(Vector ip)
121 data.insertionPoint = ip;
125 /** @return File name of the image. */
126 QString RS_Image::getFile() const
131 /** Sets the file name of the image. */
132 void RS_Image::setFile(const QString & file)
137 /** @return u Vector. Points along bottom, 1 pixel long. */
138 Vector RS_Image::getUVector() const
143 /** @return v Vector. Points along left, 1 pixel long. */
144 Vector RS_Image::getVVector() const
149 /** @return Width of image in pixels. */
150 int RS_Image::getWidth() const
152 return (int)data.size.x;
155 /** @return Height of image in pixels. */
156 int RS_Image::getHeight() const
158 return (int)data.size.y;
161 /** @return Brightness. */
162 int RS_Image::getBrightness() const
164 return data.brightness;
167 /** @return Contrast. */
168 int RS_Image::getContrast() const
170 return data.contrast;
174 int RS_Image::getFade() const
179 /** @return Image definition handle. */
180 int RS_Image::getHandle() const
185 /** Sets the image definition handle. */
186 void RS_Image::setHandle(int h)
191 /** @return The four corners. **/
192 VectorSolutions RS_Image::getCorners()
194 VectorSolutions sol(4);
196 sol.set(0, data.insertionPoint);
198 data.insertionPoint + data.uVector * RS_Math::round(data.size.x));
200 data.insertionPoint + data.vVector * RS_Math::round(data.size.y));
201 sol.set(2, sol.get(3) + data.uVector * RS_Math::round(data.size.x));
207 * @return image with in graphic units.
209 double RS_Image::getImageWidth()
211 return data.size.x * data.uVector.magnitude();
215 * @return image height in graphic units.
217 double RS_Image::getImageHeight()
219 return data.size.y * data.vVector.magnitude();
222 void RS_Image::calculateBorders()
225 VectorSolutions sol = getCorners();
227 for (int i = 0; i < 4; ++i)
229 minV = Vector::minimum(minV, sol.get(i));
230 maxV = Vector::maximum(maxV, sol.get(i));
234 Vector RS_Image::getNearestEndpoint(const Vector & coord, double * dist)
236 VectorSolutions corners = getCorners();
237 return corners.getClosest(coord, dist);
240 Vector RS_Image::getNearestPointOnEntity(const Vector & coord, bool onEntity, double * dist, RS_Entity * * entity)
245 VectorSolutions corners = getCorners();
246 VectorSolutions points(4);
249 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
250 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
251 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
252 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
255 for (int i = 0; i < 4; ++i)
256 points.set(i, l[i].getNearestPointOnEntity(coord, onEntity));
258 return points.getClosest(coord, dist);
261 Vector RS_Image::getNearestCenter(const Vector & coord, double * dist)
263 VectorSolutions points(4);
264 VectorSolutions corners = getCorners();
266 points.set(0, (corners.get(0) + corners.get(1)) / 2.0);
267 points.set(1, (corners.get(1) + corners.get(2)) / 2.0);
268 points.set(2, (corners.get(2) + corners.get(3)) / 2.0);
269 points.set(3, (corners.get(3) + corners.get(0)) / 2.0);
271 return points.getClosest(coord, dist);
274 Vector RS_Image::getNearestMiddle(const Vector & coord, double * dist)
276 return getNearestCenter(coord, dist);
279 Vector RS_Image::getNearestDist(double distance, const Vector & coord, double * dist)
281 VectorSolutions corners = getCorners();
282 VectorSolutions points(4);
286 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
287 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
288 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
289 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
292 for (int i = 0; i < 4; ++i)
293 points.set(i, l[i].getNearestDist(distance, coord, dist));
295 return points.getClosest(coord, dist);
298 double RS_Image::getDistanceToPoint(const Vector & coord, RS_Entity * * entity, RS2::ResolveLevel /*level*/, double /*solidDist*/)
303 VectorSolutions corners = getCorners();
305 double minDist = RS_MAXDOUBLE;
309 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
310 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
311 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
312 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
315 for (int i = 0; i < 4; ++i)
317 dist = l[i].getDistanceToPoint(coord, NULL);
326 /*virtual*/ double RS_Image::getLength()
331 void RS_Image::move(Vector offset)
333 data.insertionPoint.move(offset);
337 void RS_Image::rotate(Vector center, double angle)
339 data.insertionPoint.rotate(center, angle);
340 data.uVector.rotate(angle);
341 data.vVector.rotate(angle);
345 void RS_Image::scale(Vector center, Vector factor)
347 data.insertionPoint.scale(center, factor);
348 data.uVector.scale(factor);
349 data.vVector.scale(factor);
353 void RS_Image::mirror(Vector axisPoint1, Vector axisPoint2)
355 data.insertionPoint.mirror(axisPoint1, axisPoint2);
356 data.uVector.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
357 data.vVector.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
361 void RS_Image::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
363 if (painter == NULL || view == NULL || img.isNull())
367 //if (painter->getPen().getColor()==view->getBackground()) {
368 // VectorSolutions sol = getCorners();
374 int width = view->getWidth();
375 int height = view->getHeight();
377 Vector scale = Vector(view->toGuiDX(data.uVector.magnitude()),
378 view->toGuiDY(data.vVector.magnitude()));
379 double angle = data.uVector.angle();
381 int startX, stopX, startY, stopY;
383 if (data.uVector.x > 1.0e-6 && data.vVector.y > 1.0e-6)
385 startX = (int)((view->toGraphX(ox) - data.insertionPoint.x) / data.uVector.x) - 1;
390 stopX = (int)((view->toGraphX(width) - data.insertionPoint.x) / data.uVector.x) + 1;
392 if (stopX > (int)data.size.x)
393 stopX = (int)data.size.x;
395 startY = -(int)((view->toGraphY(oy) - (data.insertionPoint.y + getImageHeight()))
396 / data.vVector.y) - 1;
401 stopY = -(int)((view->toGraphY(height) - (data.insertionPoint.y + getImageHeight()))
402 / data.vVector.y) + 1;
404 if (stopY > (int)data.size.y)
405 stopY = (int)data.size.y;
415 painter->drawImg(img, view->toGui(data.insertionPoint), angle, scale,
416 startX, startY, stopX - startX, stopY - startY);
420 VectorSolutions sol = getCorners();
422 painter->drawLine(view->toGui(sol.get(0)), view->toGui(sol.get(1)));
423 painter->drawLine(view->toGui(sol.get(1)), view->toGui(sol.get(2)));
424 painter->drawLine(view->toGui(sol.get(2)), view->toGui(sol.get(3)));
425 painter->drawLine(view->toGui(sol.get(3)), view->toGui(sol.get(0)));
430 * Dumps the point's data to stdout.
432 std::ostream & operator<<(std::ostream & os, const RS_Image & i)
434 os << " Image: " << i.getData() << "\n";