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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
19 #include "constructionline.h"
21 #include "graphicview.h"
23 #include "paintinterface.h"
28 RS_Image::RS_Image(RS_EntityContainer * parent, const RS_ImageData & d):
29 RS_AtomicEntity(parent), data(d)
45 RS_Entity * RS_Image::clone()
47 RS_Image * i = new RS_Image(*this);
48 i->setHandle(getHandle());
54 /** @return RS2::EntityImage */
55 /*virtual*/ RS2::EntityType RS_Image::rtti() const
57 return RS2::EntityImage;
60 void RS_Image::update()
62 RS_DEBUG->print("RS_Image::update");
65 //QImage image = QImage(data.file);
66 img = QImage(data.file);
69 data.size = Vector(img.width(), img.height());
71 RS_DEBUG->print("RS_Image::update: OK");
74 // number of small images:
75 nx = image.width()/100;
76 ny = image.height()/100;
78 // create small images:
79 img = new QImage*[nx];
82 for (int x = 0; x<nx; ++x) {
83 img[x] = new QImage[ny];
84 for (int y = 0; y<ny; ++y) {
89 w = image.width()%100;
96 h = image.height()%100;
100 RS_PainterQt painter(&pm);
101 painter.drawImage(-x*100, -y*100, image);
102 img[x][y] = pm.convertToImage();
108 /** @return Copy of data that defines the image. */
109 RS_ImageData RS_Image::getData() const
114 /** @return Insertion point of the entity */
115 /*virtual*/ Vector RS_Image::getInsertionPoint() const
117 return data.insertionPoint;
120 /** Sets the insertion point for the image. */
121 void RS_Image::setInsertionPoint(Vector ip)
123 data.insertionPoint = ip;
127 /** @return File name of the image. */
128 QString RS_Image::getFile() const
133 /** Sets the file name of the image. */
134 void RS_Image::setFile(const QString & file)
139 /** @return u Vector. Points along bottom, 1 pixel long. */
140 Vector RS_Image::getUVector() const
145 /** @return v Vector. Points along left, 1 pixel long. */
146 Vector RS_Image::getVVector() const
151 /** @return Width of image in pixels. */
152 int RS_Image::getWidth() const
154 return (int)data.size.x;
157 /** @return Height of image in pixels. */
158 int RS_Image::getHeight() const
160 return (int)data.size.y;
163 /** @return Brightness. */
164 int RS_Image::getBrightness() const
166 return data.brightness;
169 /** @return Contrast. */
170 int RS_Image::getContrast() const
172 return data.contrast;
176 int RS_Image::getFade() const
181 /** @return Image definition handle. */
182 int RS_Image::getHandle() const
187 /** Sets the image definition handle. */
188 void RS_Image::setHandle(int h)
193 /** @return The four corners. **/
194 VectorSolutions RS_Image::getCorners()
196 VectorSolutions sol(4);
198 sol.set(0, data.insertionPoint);
200 data.insertionPoint + data.uVector * RS_Math::round(data.size.x));
202 data.insertionPoint + data.vVector * RS_Math::round(data.size.y));
203 sol.set(2, sol.get(3) + data.uVector * RS_Math::round(data.size.x));
209 * @return image with in graphic units.
211 double RS_Image::getImageWidth()
213 return data.size.x * data.uVector.magnitude();
217 * @return image height in graphic units.
219 double RS_Image::getImageHeight()
221 return data.size.y * data.vVector.magnitude();
224 void RS_Image::calculateBorders()
227 VectorSolutions sol = getCorners();
229 for (int i = 0; i < 4; ++i)
231 minV = Vector::minimum(minV, sol.get(i));
232 maxV = Vector::maximum(maxV, sol.get(i));
236 Vector RS_Image::getNearestEndpoint(const Vector & coord, double * dist)
238 VectorSolutions corners = getCorners();
239 return corners.getClosest(coord, dist);
242 Vector RS_Image::getNearestPointOnEntity(const Vector & coord, bool onEntity, double * dist, RS_Entity * * entity)
247 VectorSolutions corners = getCorners();
248 VectorSolutions points(4);
251 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
252 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
253 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
254 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
257 for (int i = 0; i < 4; ++i)
258 points.set(i, l[i].getNearestPointOnEntity(coord, onEntity));
260 return points.getClosest(coord, dist);
263 Vector RS_Image::getNearestCenter(const Vector & coord, double * dist)
265 VectorSolutions points(4);
266 VectorSolutions corners = getCorners();
268 points.set(0, (corners.get(0) + corners.get(1)) / 2.0);
269 points.set(1, (corners.get(1) + corners.get(2)) / 2.0);
270 points.set(2, (corners.get(2) + corners.get(3)) / 2.0);
271 points.set(3, (corners.get(3) + corners.get(0)) / 2.0);
273 return points.getClosest(coord, dist);
276 Vector RS_Image::getNearestMiddle(const Vector & coord, double * dist)
278 return getNearestCenter(coord, dist);
281 Vector RS_Image::getNearestDist(double distance, const Vector & coord, double * dist)
283 VectorSolutions corners = getCorners();
284 VectorSolutions points(4);
288 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
289 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
290 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
291 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
294 for (int i = 0; i < 4; ++i)
295 points.set(i, l[i].getNearestDist(distance, coord, dist));
297 return points.getClosest(coord, dist);
300 double RS_Image::getDistanceToPoint(const Vector & coord, RS_Entity * * entity, RS2::ResolveLevel /*level*/, double /*solidDist*/)
305 VectorSolutions corners = getCorners();
307 double minDist = RS_MAXDOUBLE;
311 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
312 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
313 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
314 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
317 for (int i = 0; i < 4; ++i)
319 dist = l[i].getDistanceToPoint(coord, NULL);
328 /*virtual*/ double RS_Image::getLength()
333 void RS_Image::move(Vector offset)
335 data.insertionPoint.move(offset);
339 void RS_Image::rotate(Vector center, double angle)
341 data.insertionPoint.rotate(center, angle);
342 data.uVector.rotate(angle);
343 data.vVector.rotate(angle);
347 void RS_Image::scale(Vector center, Vector factor)
349 data.insertionPoint.scale(center, factor);
350 data.uVector.scale(factor);
351 data.vVector.scale(factor);
355 void RS_Image::mirror(Vector axisPoint1, Vector axisPoint2)
357 data.insertionPoint.mirror(axisPoint1, axisPoint2);
358 data.uVector.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
359 data.vVector.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
363 void RS_Image::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
365 if (painter == NULL || view == NULL || img.isNull())
369 //if (painter->getPen().getColor()==view->getBackground()) {
370 // VectorSolutions sol = getCorners();
376 int width = view->getWidth();
377 int height = view->getHeight();
379 Vector scale = Vector(view->toGuiDX(data.uVector.magnitude()),
380 view->toGuiDY(data.vVector.magnitude()));
381 double angle = data.uVector.angle();
383 int startX, stopX, startY, stopY;
385 if (data.uVector.x > 1.0e-6 && data.vVector.y > 1.0e-6)
387 startX = (int)((view->toGraphX(ox) - data.insertionPoint.x) / data.uVector.x) - 1;
392 stopX = (int)((view->toGraphX(width) - data.insertionPoint.x) / data.uVector.x) + 1;
394 if (stopX > (int)data.size.x)
395 stopX = (int)data.size.x;
397 startY = -(int)((view->toGraphY(oy) - (data.insertionPoint.y + getImageHeight()))
398 / data.vVector.y) - 1;
403 stopY = -(int)((view->toGraphY(height) - (data.insertionPoint.y + getImageHeight()))
404 / data.vVector.y) + 1;
406 if (stopY > (int)data.size.y)
407 stopY = (int)data.size.y;
417 painter->drawImg(img, view->toGui(data.insertionPoint), angle, scale,
418 startX, startY, stopX - startX, stopY - startY);
422 VectorSolutions sol = getCorners();
424 painter->drawLine(view->toGui(sol.get(0)), view->toGui(sol.get(1)));
425 painter->drawLine(view->toGui(sol.get(1)), view->toGui(sol.get(2)));
426 painter->drawLine(view->toGui(sol.get(2)), view->toGui(sol.get(3)));
427 painter->drawLine(view->toGui(sol.get(3)), view->toGui(sol.get(0)));
432 * Dumps the point's data to stdout.
434 std::ostream & operator<<(std::ostream & os, const RS_Image & i)
436 os << " Image: " << i.getData() << "\n";