diff --git a/rtengine/coord.h b/rtengine/coord.h index 0b134ce21..359fb3a96 100644 --- a/rtengine/coord.h +++ b/rtengine/coord.h @@ -187,23 +187,23 @@ public: { radius *= scale; } - PolarCoord operator+(PolarCoord & rhs) + PolarCoord operator+ (const PolarCoord& rhs) const { + PolarCoord result; Coord thisCoord, rhsCoord; thisCoord.setFromPolar(*this); rhsCoord.setFromPolar(rhs); thisCoord += rhsCoord; - PolarCoord result; result.setFromCartesian(thisCoord); return result; } - PolarCoord operator-(PolarCoord & rhs) + PolarCoord operator- (const PolarCoord& rhs) const { + PolarCoord result; Coord thisCoord, rhsCoord; thisCoord.setFromPolar(*this); rhsCoord.setFromPolar(rhs); thisCoord -= rhsCoord; - PolarCoord result; result.setFromCartesian(thisCoord); return result; } diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 8979a68ea..89e39c1da 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1151,11 +1151,9 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte } EditType editType = ET_PIPETTE; - EditDataProvider *editProvider = PipetteBuffer::getDataProvider(); - if (editProvider) { - EditSubscriber *editSubscriber = editProvider->getCurrSubscriber(); - if (editSubscriber) { - editType = editSubscriber->getEditingType(); + if (const auto editProvider = PipetteBuffer::getDataProvider ()) { + if (const auto editSubscriber = editProvider->getCurrSubscriber ()) { + editType = editSubscriber->getEditingType (); } } @@ -1241,12 +1239,7 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte trafx = orx; trafy = ory; - if (settings->verbose) { - if (changed) { - printf("new crop size: cropx=%d, cropy=%d, cropw=%d, croph=%d / rqcropx=%d, rqcropy=%d, rqcropw=%d, rqcroph=%d / leftBorder=%d, upperBorder=%d\n", - cropx, cropy, cropw, croph, rqcropx, rqcropy, rqcropw, rqcroph, leftBorder, upperBorder); - } printf ("setsizes ends\n"); } diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 864bf7e9a..f1230bf01 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -92,7 +92,7 @@ public: return cropImageListener; } void update (int todo); - void setWindow (int cropX, int cropY, int cropW, int cropH, int canvasX, int canvasY, int canvasW, int canvasH, int skip) + void setWindow (int cropX, int cropY, int cropW, int cropH, int skip) { setCropSizes (cropX, cropY, cropW, cropH, skip, false); } diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 44c29fd97..898f1397c 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -80,7 +80,8 @@ inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) } template -inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) { +inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) +{ // calculate a * b + (1 - a) * c // following is valid: // intp(a, b+x, c+x) = intp(a, b, c) + x @@ -88,5 +89,23 @@ inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) { return a * (b-c) + c; } +template +T norm1(const T& x, const T& y) +{ + return std::abs(x) + std::abs(y); +} + +template +T norm2(const T& x, const T& y) +{ + return std::sqrt(x * x + y * y); +} + +template< typename T > +T norminf(const T& x, const T& y) +{ + return std::max(std::abs(x), std::abs(y)); +} + } #endif diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 12635839f..33d700c3a 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -211,6 +211,7 @@ void CropWindow::setSize (int w, int h, bool norefresh) } if (!norefresh) { + ObjectMOBuffer::resize(imgAreaW, imgAreaH); cropHandler.setWSize (imgAreaW, imgAreaH); } @@ -1543,8 +1544,7 @@ void CropWindow::expose (Cairo::RefPtr cr) } EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); - - if (editSubscriber && bufferCreated()) { + if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS && bufferCreated()) { if (this != iarea->mainCropWindow) { cr->set_line_width (0.); @@ -1569,75 +1569,31 @@ void CropWindow::expose (Cairo::RefPtr cr) } // drawing to the "mouse over" channel - if (editSubscriber->getEditingType() == ET_OBJECTS) { - const std::vector mouseOverGeom = editSubscriber->getMouseOverGeometry(); + const auto mouseOverGeom = editSubscriber->getMouseOverGeometry(); + if (mouseOverGeom.size()) { + if (mouseOverGeom.size() > 65534) { + // once it has been switched to OM_65535, it won't return back to OM_255 + // to avoid constant memory allocations in some particular situation. + // It will return to OM_255 on a new editing session + setObjectMode(OM_65535); + } - if (mouseOverGeom.size()) { - //printf("ObjectMap (%d x %d)\n", ObjectMOBuffer::getObjectMap()->get_width(), ObjectMOBuffer::getObjectMap()->get_height()); - Cairo::RefPtr crMO = Cairo::Context::create(ObjectMOBuffer::getObjectMap()); - crMO->set_antialias(Cairo::ANTIALIAS_NONE); - crMO->set_line_cap(Cairo::LINE_CAP_SQUARE); - crMO->set_line_join(Cairo::LINE_JOIN_ROUND); - crMO->set_operator(Cairo::OPERATOR_SOURCE); + Cairo::RefPtr crMO = Cairo::Context::create(ObjectMOBuffer::getObjectMap()); + crMO->set_antialias(Cairo::ANTIALIAS_NONE); + crMO->set_line_cap(Cairo::LINE_CAP_SQUARE); + crMO->set_line_join(Cairo::LINE_JOIN_ROUND); + crMO->set_operator(Cairo::OPERATOR_SOURCE); - // clear the bitmap - crMO->set_source_rgba(0., 0., 0., 0.); - crMO->rectangle(0., 0., ObjectMOBuffer::getObjectMap()->get_width(), ObjectMOBuffer::getObjectMap()->get_height()); - crMO->set_line_width(0.); - crMO->fill(); + // clear the bitmap + crMO->set_source_rgba(0., 0., 0., 0.); + crMO->rectangle(0., 0., ObjectMOBuffer::getObjectMap()->get_width(), ObjectMOBuffer::getObjectMap()->get_height()); + crMO->set_line_width(0.); + crMO->fill(); - Cairo::RefPtr crMO2; - - if (ObjectMOBuffer::getObjectMode() > OM_255) { - crMO2 = Cairo::Context::create(ObjectMOBuffer::getObjectMap2()); - crMO2->set_antialias(Cairo::ANTIALIAS_NONE); - crMO2->set_line_cap(Cairo::LINE_CAP_SQUARE); - crMO2->set_line_join(Cairo::LINE_JOIN_ROUND); - crMO2->set_operator(Cairo::OPERATOR_SOURCE); - - // clear the bitmap - crMO2->set_source_rgba(0., 0., 0., 0.); - crMO2->rectangle(0., 0., ObjectMOBuffer::getObjectMap2()->get_width(), ObjectMOBuffer::getObjectMap2()->get_height()); - crMO2->set_line_width(0.); - crMO2->fill(); - } - - std::vector::const_iterator i; - int a=0; - - for (auto moGeom : mouseOverGeom) { - moGeom->drawToMOChannel(crMO, crMO2, a, this, *this); - ++a; - } - - // Debug code: save the "mouse over" image to a new file at each occurrence -#if 0 - { - static unsigned int count = 0; - int w = ObjectMOBuffer::getObjectMap()->get_width(); - int h = ObjectMOBuffer::getObjectMap()->get_height(); - Glib::RefPtr img = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, false, 8, w, h); - guint8 *dst = img->get_pixels(); - unsigned char *src1 = ObjectMOBuffer::getObjectMap()->get_data(); - unsigned char *src2 = ObjectMOBuffer::getObjectMode() > OM_255 ? ObjectMOBuffer::getObjectMap()->get_data() : NULL; - memcpy(dst, src1, w * h); - - for (int n = 0, n3 = 0; n < w * h;) { - dst[n3++] = src1[n]; - - if (src2) { - dst[n3++] = src2[n]; - } else { - dst[n3++] = 0; - } - - dst[n3++] = 0; - ++n; - } - - img->save(Glib::ustring::compose("mouseOverImage-%1.png", count++), "png"); - } -#endif + int a=0; + for (auto moGeom : mouseOverGeom) { + moGeom->drawToMOChannel(crMO, a, this, *this); + ++a; } } if (this != iarea->mainCropWindow) { @@ -1685,7 +1641,11 @@ void CropWindow::expose (Cairo::RefPtr cr) void CropWindow::setEditSubscriber (EditSubscriber* newSubscriber) { // Delete, create, update all buffers based upon newSubscriber's type - ObjectMOBuffer::resize(imgAreaW, imgAreaH, newSubscriber); + if (newSubscriber) { + ObjectMOBuffer::resize (imgAreaW, imgAreaH); + } else { + ObjectMOBuffer::flush (); + } cropHandler.setEditSubscriber(newSubscriber); } diff --git a/rtgui/edit.cc b/rtgui/edit.cc index d88e2bcb3..598ee8da5 100644 --- a/rtgui/edit.cc +++ b/rtgui/edit.cc @@ -20,7 +20,7 @@ #include "edit.h" #include "rtimage.h" -ObjectMOBuffer::ObjectMOBuffer(EditDataProvider *dataProvider) : objectMap(NULL), objectMap2(NULL), objectMode(OM_255), dataProvider(dataProvider) {} +ObjectMOBuffer::ObjectMOBuffer(EditDataProvider *dataProvider) : objectMap(NULL), objectMode(OM_255), dataProvider(dataProvider) {} ObjectMOBuffer::~ObjectMOBuffer() { @@ -28,26 +28,34 @@ ObjectMOBuffer::~ObjectMOBuffer() } -/* Upgrade or downgrade the objectModeType; we're assuming that objectMap has been allocated */ +/* Upgrade or downgrade the objectModeType */ void ObjectMOBuffer::setObjectMode(ObjectMode newType) { - switch (newType) { - case (OM_255): - if (objectMap2) { - objectMap2->unreference(); - } - - objectMode = OM_255; - break; - - case (OM_65535): - if (!objectMap2) { - objectMap2 = Cairo::ImageSurface::create(Cairo::FORMAT_A8, objectMap->get_width(), objectMap->get_height()); - } - - objectMode = OM_65535; - break; + if (!objectMap) { + objectMode = newType; + return; } + + int w = objectMap->get_width (); + int h = objectMap->get_height (); + if (w && h) { + switch (newType) { + case (OM_255): + if (objectMode==OM_65535) { + objectMap->unreference(); + objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_A8, w, h); + } + break; + + case (OM_65535): + if (objectMode==OM_255) { + objectMap->unreference(); + objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_RGB16_565, w, h); + } + break; + } + } + objectMode = newType; } void ObjectMOBuffer::flush() @@ -55,10 +63,6 @@ void ObjectMOBuffer::flush() if (objectMap ) { objectMap.clear(); } - - if (objectMap2) { - objectMap2.clear(); - } } EditSubscriber *ObjectMOBuffer::getEditSubscriber () { @@ -71,32 +75,22 @@ EditSubscriber *ObjectMOBuffer::getEditSubscriber () { // Resize buffers if they already exist -void ObjectMOBuffer::resize(int newWidth, int newHeight, EditSubscriber* newSubscriber) +void ObjectMOBuffer::resize(int newWidth, int newHeight) { - if (newSubscriber) { - if (newSubscriber->getEditingType() == ET_OBJECTS) { + if (!dataProvider) { + return; + } + + if (const auto currSubscriber = dataProvider->getCurrSubscriber ()) { + if (currSubscriber->getEditingType() == ET_OBJECTS) { if (objectMap && (objectMap->get_width() != newWidth || objectMap->get_height() != newHeight)) { objectMap.clear(); } if (!objectMap && newWidth>0 && newHeight>0) { - objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_A8, newWidth, newHeight); + objectMap = Cairo::ImageSurface::create(objectMode==OM_255?Cairo::FORMAT_A8:Cairo::FORMAT_RGB16_565, newWidth, newHeight); } - if (objectMode == OM_65535) { - if (objectMap2) { - if (objectMap2->get_width() != newWidth || objectMap2->get_height() != newHeight) { - objectMap2.clear(); - } - } - - if (!objectMap2 && newWidth>0 && newHeight>0) { - objectMap2 = Cairo::ImageSurface::create(Cairo::FORMAT_A8, newWidth, newHeight); - } - } else if (objectMap2) { - // OM_255 -> deleting objectMap2, if any - objectMap2.clear(); - } } else { flush(); } @@ -109,12 +103,14 @@ int ObjectMOBuffer::getObjectID(const rtengine::Coord& location) { int id = 0; - if (objectMap && location.x > 0 && location.y > 0 && location.x < objectMap->get_width() && location.y < objectMap->get_height()) { - id = (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )); + if (!objectMap || location.x < 0 || location.y < 0 || location.x >= objectMap->get_width() || location.y >= objectMap->get_height()) { + return -1; + } - if (objectMap2) { - id |= (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )) << 8; - } + if (objectMode == OM_255) { + id = (unsigned char)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )); + } else { + id = (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )); } return id - 1; @@ -257,7 +253,7 @@ void Circle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuffer } } -void Circle::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void Circle::drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if (flags & F_HOVERABLE) { cr->set_line_width( getMouseOverLineWidth() ); @@ -272,9 +268,12 @@ void Circle::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtrgetDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen; } - // drawing the lower byte's value - unsigned short a = (id + 1) & 0xFF; - cr->set_source_rgba (0., 0., 0., double(a) / 255.); + // setting the color to the objet's ID + if (objectBuffer->getObjectMode() == OM_255) { + cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.); + } else { + cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.); + } cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0, 2.*M_PI); if (filled) { @@ -287,24 +286,6 @@ void Circle::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtrstroke(); } - - // drawing the higher byte's value - if (objectBuffer->getObjectMode() == OM_65535) { - a = (id + 1) >> 8; - cr2->set_source_rgba (0., 0., 0., double(a) / 255.); - cr2->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0, 2.*M_PI); - - if (filled) { - if (innerLineWidth > 0.) { - cr2->fill_preserve(); - cr2->stroke(); - } else { - cr2->fill(); - } - } else { - cr2->stroke(); - } - } } } @@ -392,9 +373,7 @@ void Line::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuffer * } } -void Line::drawToMOChannel(Cairo::RefPtr &cr, - Cairo::RefPtr &cr2, unsigned short id, - ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void Line::drawToMOChannel(Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if (flags & F_HOVERABLE) { cr->set_line_width( getMouseOverLineWidth() ); @@ -412,21 +391,15 @@ void Line::drawToMOChannel(Cairo::RefPtr &cr, end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen; } - // drawing the lower byte's value - unsigned short a = (id + 1) & 0xFF; - cr->set_source_rgba (0., 0., 0., double(a) / 255.); + // setting the color to the objet's ID + if (objectBuffer->getObjectMode() == OM_255) { + cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.); + } else { + cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.); + } cr->move_to(begin_.x + 0.5, begin_.y + 0.5); cr->line_to(end_.x + 0.5, end_.y + 0.5); cr->stroke(); - - // drawing the higher byte's value - if (objectBuffer->getObjectMode() == OM_65535) { - a = (id + 1) >> 8; - cr2->set_source_rgba (0., 0., 0., double(a) / 255.); - cr2->move_to(begin_.x + 0.5, begin_.y + 0.5); - cr2->line_to(end_.x + 0.5, end_.y + 0.5); - cr2->stroke(); - } } } @@ -555,14 +528,17 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuff } } -void Polyline::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void Polyline::drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if ((flags & F_HOVERABLE) && points.size() > 1) { rtengine::Coord currPos; - // drawing the lower byte's value - unsigned short a = (id + 1) & 0xFF; - cr->set_source_rgba (0., 0., 0., double(a) / 255.); + // setting the color to the objet's ID + if (objectBuffer->getObjectMode() == OM_255) { + cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.); + } else { + cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.); + } for (unsigned int i = 0; i < points.size(); ++i) { cr->set_line_width( getMouseOverLineWidth() ); @@ -593,42 +569,6 @@ void Polyline::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr } else { cr->stroke(); } - - // drawing the higher byte's value - if (objectBuffer->getObjectMode() == OM_65535) { - a = (id + 1) >> 8; - cr2->set_source_rgba (0., 0., 0., double(a) / 255.); - - for (unsigned int i = 0; i < points.size(); ++i) { - cr2->set_line_width( getMouseOverLineWidth() ); - currPos = points.at(i); - - if (datum == IMAGE) { - coordSystem.imageCoordToCropCanvas (points.at(i).x, points.at(i).y, currPos.x, currPos.y); - } else if (datum == CLICKED_POINT) { - currPos += objectBuffer->getDataProvider()->posScreen; - } else if (datum == CURSOR) { - currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen; - } - - if (!i) { - cr2->move_to(currPos.x + 0.5, currPos.y + 0.5); - } else { - cr2->line_to(currPos.x + 0.5, currPos.y + 0.5); - } - } - - if (filled) { - if (innerLineWidth > 0.) { - cr2->fill_preserve(); - cr2->stroke(); - } else { - cr2->fill(); - } - } else { - cr2->stroke(); - } - } } } @@ -763,7 +703,7 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuf } } -void Rectangle::drawToMOChannel(Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void Rectangle::drawToMOChannel(Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if (flags & F_HOVERABLE) { cr->set_line_width( getMouseOverLineWidth() ); @@ -786,9 +726,12 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr &cr, Cairo::RefPtr br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen; } - // drawing the lower byte's value - unsigned short a = (id + 1) & 0xFF; - cr->set_source_rgba (0., 0., 0., double(a) / 255.); + // setting the color to the objet's ID + if (objectBuffer->getObjectMode() == OM_255) { + cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.); + } else { + cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.); + } cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y); if (filled) { @@ -801,24 +744,6 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr &cr, Cairo::RefPtr } else { cr->stroke(); } - - // drawing the higher byte's value - if (objectBuffer->getObjectMode() == OM_65535) { - a = (id + 1) >> 8; - cr2->set_source_rgba (0., 0., 0., double(a) / 255.); - cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y); - - if (filled) { - if (innerLineWidth > 0.) { - cr2->fill_preserve(); - cr2->stroke(); - } else { - cr2->fill(); - } - } else { - cr2->stroke(); - } - } } } diff --git a/rtgui/edit.h b/rtgui/edit.h index b1acf7e15..5268e82e5 100644 --- a/rtgui/edit.h +++ b/rtgui/edit.h @@ -153,8 +153,6 @@ private: // Used to draw the objects where the color correspond to the object's ID, in order to find the correct object when hovering Cairo::RefPtr objectMap; - // If more than 254 objects has to be handled, objectMap2 contains the "upper part" of the 16 bit int value. objectMap2 will be NULL otherwise. - Cairo::RefPtr objectMap2; ObjectMode objectMode; protected: @@ -164,32 +162,19 @@ protected: EditDataProvider* dataProvider; void createBuffer(int width, int height); - void resize(int newWidth, int newHeight, EditSubscriber* newSubscriber); + void resize(int newWidth, int newHeight); void flush(); EditSubscriber *getEditSubscriber (); public: - ObjectMOBuffer(EditDataProvider *dataProvider); + explicit ObjectMOBuffer (EditDataProvider *dataProvider); ~ObjectMOBuffer(); - EditDataProvider* getDataProvider() - { - return dataProvider; - } - void setObjectMode(ObjectMode newType); - ObjectMode getObjectMode() - { - return objectMode; - } + EditDataProvider* getDataProvider (); + void setObjectMode (ObjectMode newType); + ObjectMode getObjectMode (); - Cairo::RefPtr &getObjectMap () - { - return objectMap; - } - Cairo::RefPtr &getObjectMap2() - { - return objectMap2; - } + Cairo::RefPtr& getObjectMap (); // return true if the buffer has been allocated bool bufferCreated(); @@ -238,36 +223,16 @@ class RGBColor double b; public: - RGBColor () : r(0.), g(0.), b(0.) {} - explicit RGBColor (double r, double g, double b) : r(r), g(g), b(b) {} - explicit RGBColor (char r, char g, char b) : r(double(r) / 255.), g(double(g) / 255.), b(double(b) / 255.) {} + RGBColor (); + explicit RGBColor (double r, double g, double b); + explicit RGBColor (char r, char g, char b); - void setColor(double r, double g, double b) - { - this->r = r; - this->g = g; - this->b = b; - } + void setColor (double r, double g, double b); + void setColor (char r, char g, char b); - void setColor(char r, char g, char b) - { - this->r = double(r) / 255.; - this->g = double(g) / 255.; - this->b = double(b) / 255.; - } - - double getR() - { - return r; - } - double getG() - { - return g; - } - double getB() - { - return b; - } + double getR (); + double getG (); + double getB (); }; class RGBAColor : public RGBColor @@ -275,26 +240,14 @@ class RGBAColor : public RGBColor double a; public: - RGBAColor () : RGBColor(0., 0., 0.), a(0.) {} - explicit RGBAColor (double r, double g, double b, double a) : RGBColor(r, g, b), a(a) {} - explicit RGBAColor (char r, char g, char b, char a) : RGBColor(r, g, b), a(double(a) / 255.) {} + RGBAColor (); + explicit RGBAColor (double r, double g, double b, double a); + explicit RGBAColor (char r, char g, char b, char a); - void setColor(double r, double g, double b, double a) - { - RGBColor::setColor(r, g, b); - this->a = a; - } + void setColor (double r, double g, double b, double a); + void setColor (char r, char g, char b, char a); - void setColor(char r, char g, char b, char a) - { - RGBColor::setColor(r, g, b); - this->a = double(a) / 255.; - } - - double getA() - { - return a; - } + double getA (); }; /// @brief Displayable and MouseOver geometry base class @@ -345,85 +298,29 @@ public: Datum datum; State state; // set by the Subscriber - Geometry () : innerLineColor(char(255), char(255), char(255)), outerLineColor(char(0), char(0), char(0)), flags(F_VISIBLE | F_HOVERABLE | F_AUTO_COLOR), innerLineWidth(1.5f), datum(IMAGE), state(NORMAL) {} + Geometry (); virtual ~Geometry() {} - void setInnerLineColor (double r, double g, double b) - { - innerLineColor.setColor(r, g, b); - flags &= ~F_AUTO_COLOR; - } - void setInnerLineColor (char r, char g, char b) - { - innerLineColor.setColor(r, g, b); - flags &= ~F_AUTO_COLOR; - } - RGBColor getInnerLineColor (); - void setOuterLineColor (double r, double g, double b) - { - outerLineColor.setColor(r, g, b); - flags &= ~F_AUTO_COLOR; - } - void setOuterLineColor (char r, char g, char b) - { - outerLineColor.setColor(r, g, b); - flags &= ~F_AUTO_COLOR; - } - RGBColor getOuterLineColor (); - double getOuterLineWidth () - { - return double(innerLineWidth) + 2.; - } - double getMouseOverLineWidth () - { - return getOuterLineWidth() + 2.; - } - void setAutoColor (bool aColor) - { - if (aColor) { - flags |= F_AUTO_COLOR; - } else { - flags &= ~F_AUTO_COLOR; - } - } - bool isVisible () - { - return flags & F_VISIBLE; - } - void setVisible (bool visible) - { - if (visible) { - flags |= F_VISIBLE; - } else { - flags &= ~F_VISIBLE; - } - } - bool isHoverable () - { - return flags & F_HOVERABLE; - } - void setHoverable (bool visible) - { - if (visible) { - flags |= F_HOVERABLE; - } else { - flags &= ~F_HOVERABLE; - } - } + void setInnerLineColor (double r, double g, double b); + void setInnerLineColor (char r, char g, char b); + RGBColor getInnerLineColor (); + void setOuterLineColor (double r, double g, double b); + void setOuterLineColor (char r, char g, char b); + RGBColor getOuterLineColor (); + double getOuterLineWidth (); + double getMouseOverLineWidth (); + void setAutoColor (bool aColor); + bool isVisible (); + void setVisible (bool visible); + bool isHoverable (); + void setHoverable (bool visible); // setActive will enable/disable the visible and hoverable flags in one shot! - void setActive (bool active) - { - if (active) { - flags |= (F_VISIBLE | F_HOVERABLE); - } else { - flags &= ~(F_VISIBLE | F_HOVERABLE); - } - } + void setActive (bool active); virtual void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *parent, EditCoordSystem &coordSystem) = 0; virtual void drawInnerGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *parent, EditCoordSystem &coordSystem) = 0; - virtual void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem) = 0; + virtual void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem) = 0; }; class Circle : public Geometry @@ -434,13 +331,13 @@ public: bool filled; bool radiusInImageSpace; /// If true, the radius depend on the image scale; if false, it is a fixed 'screen' size - Circle () : center(100, 100), radius(10), filled(false), radiusInImageSpace(false) {} - Circle (rtengine::Coord ¢er, int radius, bool filled = false, bool radiusInImageSpace = false) : center(center), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {} - Circle (int centerX, int centerY, int radius, bool filled = false, bool radiusInImageSpace = false) : center(centerX, centerY), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {} + Circle (); + Circle (rtengine::Coord& center, int radius, bool filled = false, bool radiusInImageSpace = false); + Circle (int centerX, int centerY, int radius, bool filled = false, bool radiusInImageSpace = false); void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); void drawInnerGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); - void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); }; class Line : public Geometry @@ -449,13 +346,13 @@ public: rtengine::Coord begin; rtengine::Coord end; - Line () : begin(10, 10), end(100, 100) {} - Line (rtengine::Coord &begin, rtengine::Coord &end) : begin(begin), end(end) {} - Line (int beginX, int beginY, int endX, int endY) : begin(beginX, beginY), end(endX, endY) {} + Line (); + Line (rtengine::Coord& begin, rtengine::Coord& end); + Line (int beginX, int beginY, int endX, int endY); void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); void drawInnerGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); - void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); }; class Polyline : public Geometry @@ -464,11 +361,11 @@ public: std::vector points; bool filled; - Polyline() : filled(false) {} + Polyline (); void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); void drawInnerGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); - void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); }; class Rectangle : public Geometry @@ -478,7 +375,7 @@ public: rtengine::Coord bottomRight; bool filled; - Rectangle() : topLeft(0, 0), bottomRight(10, 10), filled(false) {} + Rectangle (); void setXYWH(int left, int top, int width, int height); void setXYXY(int left, int top, int right, int bottom); @@ -486,7 +383,7 @@ public: void setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight); void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); void drawInnerGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); - void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem); }; /// @brief Method for client tools needing Edit information @@ -511,10 +408,7 @@ public: virtual ~EditSubscriber () {} void setEditProvider(EditDataProvider *provider); - EditDataProvider* getEditProvider() - { - return provider; - } + EditDataProvider* getEditProvider (); void setEditID(EditUniqueID ID, BufferType buffType); bool isCurrentSubscriber(); virtual void subscribe(); @@ -527,103 +421,64 @@ public: /** @brief Get the cursor to be displayed when above handles @param objectID object currently "hovered" */ - virtual CursorShape getCursor(int objectID) - { - return CSOpenHand; - } + virtual CursorShape getCursor (int objectID); /** @brief Triggered when the mouse is moving over an object This method is also triggered when the cursor is moving over the image in ET_PIPETTE mode @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool mouseOver(int modifierKey) - { - return false; - } + virtual bool mouseOver (int modifierKey); /** @brief Triggered when mouse button 1 is pressed, together with the CTRL modifier key if the subscriber is of type ET_PIPETTE Once the key is pressed, RT will enter in drag1 mode on subsequent mouse movements @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool button1Pressed(int modifierKey) - { - return false; - } + virtual bool button1Pressed (int modifierKey); /** @brief Triggered when mouse button 1 is released @return true if the preview has to be redrawn, false otherwise */ - virtual bool button1Released() - { - return false; - } + virtual bool button1Released (); /** @brief Triggered when mouse button 2 is pressed (middle button) Once the key is pressed, RT will enter in drag2 mode on subsequent mouse movements @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool button2Pressed(int modifierKey) - { - return false; - } + virtual bool button2Pressed (int modifierKey); /** @brief Triggered when mouse button 2 is released (middle button) @return true if the preview has to be redrawn, false otherwise */ - virtual bool button2Released() - { - return false; - } + virtual bool button2Released (); /** @brief Triggered when mouse button 3 is pressed (right button) Once the key is pressed, RT will enter in drag3 mode on subsequent mouse movements @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool button3Pressed(int modifierKey) - { - return false; - } + virtual bool button3Pressed (int modifierKey); /** @brief Triggered when mouse button 3 is released (right button) @return true if the preview has to be redrawn, false otherwise */ - virtual bool button3Released() - { - return false; - } + virtual bool button3Released (); /** @brief Triggered when the user is moving while holding down mouse button 1 @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool drag1(int modifierKey) - { - return false; - } + virtual bool drag1 (int modifierKey); /** @brief Triggered when the user is moving while holding down mouse button 2 @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool drag2(int modifierKey) - { - return false; - } + virtual bool drag2 (int modifierKey); /** @brief Triggered when the user is moving while holding down mouse button 3 @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) @return true if the preview has to be redrawn, false otherwise */ - virtual bool drag3(int modifierKey) - { - return false; - } + virtual bool drag3 (int modifierKey); /** @brief Get the geometry to be shown to the user */ - const std::vector & getVisibleGeometry() - { - return visibleGeometry; - } + const std::vector& getVisibleGeometry (); /** @brief Get the geometry to be drawn in the "mouse over" channel, hidden from the user */ - const std::vector & getMouseOverGeometry() - { - return mouseOverGeometry; - } + const std::vector& getMouseOverGeometry (); }; /** @brief Class to handle the furniture of data to the subscribers. @@ -655,12 +510,255 @@ public: virtual void unsubscribe(); /// Occurs when the subscriber has been switched off first virtual void switchOffEditMode (); /// Occurs when the user want to stop the editing mode virtual CursorShape getCursor(int objectID); - int getPipetteRectSize() - { - return 8; // TODO: make a GUI - } + int getPipetteRectSize (); EditSubscriber* getCurrSubscriber(); virtual void getImageSize (int &w, int&h) = 0; }; +inline EditDataProvider* ObjectMOBuffer::getDataProvider () { + return dataProvider; +} + +inline ObjectMode ObjectMOBuffer::getObjectMode () { + return objectMode; +} + +inline Cairo::RefPtr& ObjectMOBuffer::getObjectMap () { + return objectMap; +} + +inline void RGBColor::setColor (double r, double g, double b) { + this->r = r; + this->g = g; + this->b = b; +} + +inline void RGBColor::setColor (char r, char g, char b) { + this->r = double (r) / 255.; + this->g = double (g) / 255.; + this->b = double (b) / 255.; +} + +inline double RGBColor::getR () { + return r; +} + +inline double RGBColor::getG () { + return g; +} + +inline double RGBColor::getB () { + return b; +} + +inline void RGBAColor::setColor (double r, double g, double b, double a) { + RGBColor::setColor (r, g, b); + this->a = a; +} + +inline void RGBAColor::setColor (char r, char g, char b, char a) { + RGBColor::setColor (r, g, b); + this->a = double (a) / 255.; +} + +inline double RGBAColor::getA () { + return a; +} + +inline void Geometry::setInnerLineColor (double r, double g, double b) { + innerLineColor.setColor (r, g, b); + flags &= ~F_AUTO_COLOR; +} + +inline void Geometry::setInnerLineColor (char r, char g, char b) { + innerLineColor.setColor (r, g, b); + flags &= ~F_AUTO_COLOR; +} + +inline void Geometry::setOuterLineColor (double r, double g, double b) { + outerLineColor.setColor (r, g, b); + flags &= ~F_AUTO_COLOR; +} + +inline double Geometry::getOuterLineWidth () { + return double (innerLineWidth) + 2.; +} + +inline void Geometry::setOuterLineColor (char r, char g, char b) { + outerLineColor.setColor (r, g, b); + flags &= ~F_AUTO_COLOR; +} + +inline double Geometry::getMouseOverLineWidth () { + return getOuterLineWidth () + 2.; +} + +inline void Geometry::setAutoColor (bool aColor) { + if (aColor) { + flags |= F_AUTO_COLOR; + } else { + flags &= ~F_AUTO_COLOR; + } +} + +inline bool Geometry::isVisible () { + return flags & F_VISIBLE; +} + +inline void Geometry::setVisible (bool visible) { + if (visible) { + flags |= F_VISIBLE; + } else { + flags &= ~F_VISIBLE; + } +} + +inline bool Geometry::isHoverable () { + return flags & F_HOVERABLE; +} + +inline void Geometry::setHoverable (bool visible) { + if (visible) { + flags |= F_HOVERABLE; + } else { + flags &= ~F_HOVERABLE; + } +} + +inline void Geometry::setActive (bool active) { + if (active) { + flags |= (F_VISIBLE | F_HOVERABLE); + } else { + flags &= ~(F_VISIBLE | F_HOVERABLE); + } +} + +inline EditDataProvider* EditSubscriber::getEditProvider () { + return provider; +} + +inline CursorShape EditSubscriber::getCursor (int objectID) { + return CSOpenHand; +} + +inline bool EditSubscriber::mouseOver (int modifierKey) { + return false; +} + +inline bool EditSubscriber::button1Pressed (int modifierKey) { + return false; +} + +inline bool EditSubscriber::button1Released () { + return false; +} + +inline bool EditSubscriber::button2Pressed (int modifierKey) { + return false; +} + +inline bool EditSubscriber::button2Released () { + return false; +} + +inline bool EditSubscriber::button3Pressed (int modifierKey) { + return false; +} + +inline bool EditSubscriber::button3Released () { + return false; +} + +inline bool EditSubscriber::drag1 (int modifierKey) { + return false; +} + +inline bool EditSubscriber::drag2 (int modifierKey) { + return false; +} + +inline bool EditSubscriber::drag3 (int modifierKey) { + return false; +} + +inline const std::vector& EditSubscriber::getVisibleGeometry () { + return visibleGeometry; +} + +inline const std::vector& EditSubscriber::getMouseOverGeometry () { + return mouseOverGeometry; +} + +inline int EditDataProvider::getPipetteRectSize () { + return 8; // TODO: make a GUI +} + +inline Geometry::Geometry () : + innerLineColor (char (255), char (255), char (255)), outerLineColor ( + char (0), char (0), char (0)), flags ( + F_VISIBLE | F_HOVERABLE | F_AUTO_COLOR), innerLineWidth (1.5f), datum ( + IMAGE), state (NORMAL) { +} + +inline Circle::Circle () : + center (100, 100), radius (10), filled (false), radiusInImageSpace ( + false) { +} + +inline Rectangle::Rectangle () : + topLeft (0, 0), bottomRight (10, 10), filled (false) { +} + +inline Polyline::Polyline () : + filled (false) { +} + +inline Line::Line () : + begin (10, 10), end (100, 100) { +} + +inline RGBAColor::RGBAColor () : + RGBColor (0., 0., 0.), a (0.) { +} + +inline RGBColor::RGBColor () : + r (0.), g (0.), b (0.) { +} + +inline RGBColor::RGBColor (double r, double g, double b) : + r (r), g (g), b (b) { +} + +inline RGBColor::RGBColor (char r, char g, char b) : + r (double (r) / 255.), g (double (g) / 255.), b (double (b) / 255.) { +} + +inline RGBAColor::RGBAColor (double r, double g, double b, double a) : + RGBColor (r, g, b), a (a) { +} + +inline RGBAColor::RGBAColor (char r, char g, char b, char a) : + RGBColor (r, g, b), a (double (a) / 255.) { +} + +inline Circle::Circle (rtengine::Coord& center, int radius, bool filled, + bool radiusInImageSpace) : + center (center), radius (radius), filled (filled), radiusInImageSpace ( + radiusInImageSpace) { +} + +inline Circle::Circle (int centerX, int centerY, int radius, bool filled, + bool radiusInImageSpace) : + center (centerX, centerY), radius (radius), filled (filled), radiusInImageSpace ( + radiusInImageSpace) { +} + +inline Line::Line (rtengine::Coord& begin, rtengine::Coord& end) : + begin (begin), end (end) { +} + +inline Line::Line (int beginX, int beginY, int endX, int endY) : + begin (beginX, beginY), end (endX, endY) { +} + #endif diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index 352183d18..93011f55b 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -136,7 +136,7 @@ void Gradient::read (const ProcParams* pp, const ParamsEdited* pedited) enableListener (); } -void Gradient::updateGeometry(const int centerX_, const int centerY_, const double feather_, const double degree_, const int fullWidth, const int fullHeight) +void Gradient::updateGeometry(const int centerX, const int centerY, const double feather, const double degree, const int fullWidth, const int fullHeight) { EditDataProvider* dataProvider = getEditProvider(); @@ -144,7 +144,8 @@ void Gradient::updateGeometry(const int centerX_, const int centerY_, const doub return; } - int imW, imH; + int imW=0; + int imH=0; if (fullWidth != -1 && fullHeight != -1) { imW = fullWidth; imH = fullHeight; @@ -156,79 +157,56 @@ void Gradient::updateGeometry(const int centerX_, const int centerY_, const doub } PolarCoord polCoord1, polCoord2; - double decay = feather_ * sqrt(double(imW) * double(imW) + double(imH) * double(imH)) / 200.; + double decay = feather * rtengine::norm2(imW, imH) / 200.; - rtengine::Coord origin(imW / 2 + centerX_ * imW / 200.f, imH / 2 + centerY_ * imH / 200.f); + rtengine::Coord origin(imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200); Line *currLine; Circle *currCircle; + + const auto updateLine = [&](Geometry* geometry, const float radius, const float begin, const float end) + { + const auto line = static_cast(geometry); + line->begin.setFromPolar(PolarCoord(radius, -degree + begin)); + line->begin += origin; + line->end.setFromPolar(PolarCoord(radius, -degree + end)); + line->end += origin; + }; + + const auto updateLineWithDecay = [&](Geometry* geometry, const float radius, const float offSetAngle) + { + const auto line = static_cast(geometry); + line->begin.setFromPolar(PolarCoord(radius, -degree + 180.) + PolarCoord(decay, -degree + offSetAngle)); + line->begin += origin; + line->end.setFromPolar(PolarCoord(radius, -degree) + PolarCoord(decay, -degree + offSetAngle)); + line->end += origin; + }; + + const auto updateCircle = [&](Geometry* geometry) + { + const auto circle = static_cast(geometry); + circle->center = origin; + }; + // update horizontal line - currLine = static_cast(visibleGeometry.at(0)); - polCoord1.set(1500.f, float(-degree_ + 180)); - currLine->begin.setFromPolar(polCoord1); - currLine->begin += origin; - polCoord1.set(1500.f, float(-degree_ )); - currLine->end.setFromPolar (polCoord1); - currLine->end += origin; - currLine = static_cast(mouseOverGeometry.at(0)); - polCoord1.set(1500.f, float(-degree_ + 180)); - currLine->begin.setFromPolar(polCoord1); - currLine->begin += origin; - polCoord1.set(1500.f, float(-degree_ )); - currLine->end.setFromPolar (polCoord1); - currLine->end += origin; + updateLine (visibleGeometry.at(0), 1500., 0., 180.); + updateLine (mouseOverGeometry.at(0), 1500., 0., 180.); + // update vertical line - currLine = static_cast(visibleGeometry.at(1)); - polCoord1.set( 700.f, float(-degree_ + 90 )); - currLine->begin.setFromPolar(polCoord1); - currLine->begin += origin; - polCoord1.set( 700.f, float(-degree_ + 270)); - currLine->end.setFromPolar (polCoord1); - currLine->end += origin; - currLine = static_cast(mouseOverGeometry.at(1)); - polCoord1.set( 700.f, float(-degree_ + 90 )); - currLine->begin.setFromPolar(polCoord1); - currLine->begin += origin; - polCoord1.set( 700.f, float(-degree_ + 270)); - currLine->end.setFromPolar (polCoord1); - currLine->end += origin; + updateLine (visibleGeometry.at(1), 700., 90., 270.); + updateLine (mouseOverGeometry.at(1), 700., 90., 270.); + // update upper feather line - currLine = static_cast(visibleGeometry.at(2)); - polCoord2.set(decay, float(-degree_ + 270)); - polCoord1.set(350.f, float(-degree_ + 180)); - currLine->begin.setFromPolar(polCoord1 + polCoord2); - currLine->begin += origin; - polCoord1.set(350.f, float(-degree_ )); - currLine->end.setFromPolar (polCoord1 + polCoord2); - currLine->end += origin; - currLine = static_cast(mouseOverGeometry.at(2)); - polCoord1.set(350.f, float(-degree_ + 180)); - currLine->begin.setFromPolar(polCoord1 + polCoord2); - currLine->begin += origin; - polCoord1.set(350.f, float(-degree_ )); - currLine->end.setFromPolar (polCoord1 + polCoord2); - currLine->end += origin; + updateLineWithDecay (visibleGeometry.at(2), 350., 270.); + updateLineWithDecay (mouseOverGeometry.at(2), 350., 270.); + // update lower feather line - currLine = static_cast(visibleGeometry.at(3)); - polCoord2.set(decay, float(-degree_ + 90)); - polCoord1.set(350.f, float(-degree_ + 180)); - currLine->begin.setFromPolar(polCoord1 + polCoord2); - currLine->begin += origin; - polCoord1.set(350.f, float(-degree_ )); - currLine->end.setFromPolar (polCoord1 + polCoord2); - currLine->end += origin; - currLine = static_cast(mouseOverGeometry.at(3)); - polCoord1.set(350.f, float(-degree_ + 180)); - currLine->begin.setFromPolar(polCoord1 + polCoord2); - currLine->begin += origin; - polCoord1.set(350.f, float(-degree_ )); - currLine->end.setFromPolar (polCoord1 + polCoord2); - currLine->end += origin; + updateLineWithDecay (visibleGeometry.at(3), 350., 90.); + updateLineWithDecay (mouseOverGeometry.at(3), 350., 90.); + // update circle's position - currCircle = static_cast(visibleGeometry.at(4)); - currCircle->center = origin; - currCircle = static_cast(mouseOverGeometry.at(4)); - currCircle->center = origin; + updateCircle (visibleGeometry.at(4)); + updateCircle (mouseOverGeometry.at(4)); } void Gradient::write (ProcParams* pp, ParamsEdited* pedited) @@ -408,9 +386,13 @@ bool Gradient::mouseOver(int modifierKey) bool Gradient::button1Pressed(int modifierKey) { + if (lastObject < 0) { + return false; + } + EditDataProvider *provider = getEditProvider(); - if (!(modifierKey & GDK_CONTROL_MASK) && lastObject > -1) { + if (!(modifierKey & GDK_CONTROL_MASK)) { // button press is valid (no modifier key) PolarCoord pCoord; int imW, imH; @@ -458,7 +440,7 @@ bool Gradient::button1Pressed(int modifierKey) EditSubscriber::dragging = true; return false; - } else if (lastObject > -1) { // should theoretically always be true + } else { // should theoretically always be true // this will let this class ignore further drag events if (lastObject == 2 || lastObject == 3) { EditSubscriber::visibleGeometry.at(2)->state = Geometry::NORMAL; diff --git a/rtgui/gradient.h b/rtgui/gradient.h index 67cb5b2fc..f59fb07e5 100644 --- a/rtgui/gradient.h +++ b/rtgui/gradient.h @@ -46,7 +46,7 @@ public: void enabledChanged (); void setAdjusterBehavior (bool degreeadd, bool featheradd, bool strengthadd, bool centeradd); void trimValues (rtengine::procparams::ProcParams* pp); - void updateGeometry (const int centerX_, const int centerY_, const double feather_, const double degree_, const int fullWidth=-1, const int fullHeight=-1); + void updateGeometry (const int centerX, const int centerY, const double feather, const double degree, const int fullWidth=-1, const int fullHeight=-1); void setEditProvider (EditDataProvider* provider); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 15ef36078..ce0699664 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -96,10 +96,10 @@ void ImageArea::on_resized (Gtk::Allocation& req) mainCropWindow->setPointerMotionListener (pmlistener); mainCropWindow->setPointerMotionHListener (pmhlistener); mainCropWindow->setPosition (0, 0); - mainCropWindow->setSize (get_width(), get_height(), false); // this execute the refresh itself + mainCropWindow->setSize (get_width(), get_height()); // this execute the refresh itself mainCropWindow->enable(); // start processing ! } else { - mainCropWindow->setSize (get_width(), get_height()); + mainCropWindow->setSize (get_width(), get_height()); // this execute the refresh itself } parent->syncBeforeAfterViews(); @@ -326,14 +326,13 @@ bool ImageArea::on_leave_notify_event (GdkEventCrossing* event) void ImageArea::subscribe(EditSubscriber *subscriber) { - mainCropWindow->setEditSubscriber(subscriber); + EditDataProvider::subscribe(subscriber); + mainCropWindow->setEditSubscriber(subscriber); for (auto cropWin : cropWins) { cropWin->setEditSubscriber(subscriber); } - EditDataProvider::subscribe(subscriber); - if (listener && listener->getToolBar()) { listener->getToolBar()->startEditMode (); } @@ -354,11 +353,11 @@ void ImageArea::unsubscribe() } EditDataProvider::unsubscribe(); - // Ask the Crops to free-up edit mode buffers - mainCropWindow->cropHandler.setEditSubscriber(NULL); + // Ask the Crops to free-up edit mode buffers + mainCropWindow->setEditSubscriber(NULL); for (auto cropWin : cropWins) { - cropWin->cropHandler.setEditSubscriber(NULL); + cropWin->setEditSubscriber(NULL); } setToolHand(); @@ -619,10 +618,7 @@ void ImageArea::initialImageArrived (CropWindow* cw) mainCropWindow->cropHandler.getFullImageSize(w, h); if(w != fullImageWidth || h != fullImageHeight) { - printf("zoomFit !\n"); mainCropWindow->zoomFit (); - } else { - printf("no-zoomFit\n"); } fullImageWidth = w; diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc index aedd2e800..9ba62230f 100644 --- a/rtgui/previewhandler.cc +++ b/rtgui/previewhandler.cc @@ -207,13 +207,8 @@ Glib::RefPtr PreviewHandler::getRoughImage (int x, int y, int w, in x *= zoom; y *= zoom; - if ((x + w) / totalZoom > previewImg->get_width()) { - w = previewImg->get_width() * totalZoom - x; - } - - if ((y + h) / totalZoom > previewImg->get_height()) { - h = previewImg->get_height() * totalZoom - y; - } + w = rtengine::LIM(w, 0, int(previewImg->get_width() * totalZoom) - x); + h = rtengine::LIM(h, 0, int(previewImg->get_height() * totalZoom) - y); resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h); previewImg->scale (resPixbuf, 0, 0, w, h, -x, -y, totalZoom, totalZoom, Gdk::INTERP_NEAREST); diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc index c9bc080e3..ea419427b 100644 --- a/rtgui/previewwindow.cc +++ b/rtgui/previewwindow.cc @@ -100,48 +100,50 @@ void PreviewWindow::on_resized (Gtk::Allocation& req) bool PreviewWindow::on_expose_event (GdkEventExpose* event) { - if (backBuffer) { - Glib::RefPtr window = get_window(); + if (!backBuffer) { + return true; + } - int bufferW, bufferH; - backBuffer->get_size (bufferW, bufferH); + Glib::RefPtr window = get_window(); - if (!mainCropWin && imageArea) { - mainCropWin = imageArea->getMainCropWindow (); + int bufferW, bufferH; + backBuffer->get_size (bufferW, bufferH); - if (mainCropWin) { - mainCropWin->addCropWindowListener (this); - } + if (!mainCropWin && imageArea) { + mainCropWin = imageArea->getMainCropWindow (); + + if (mainCropWin) { + mainCropWin->addCropWindowListener (this); } + } - if ((get_width() != bufferW && get_height() != bufferH) || needsUpdate) { - needsUpdate = false; - updatePreviewImage (); - } + if ((get_width() != bufferW && get_height() != bufferH) || needsUpdate) { + needsUpdate = false; + updatePreviewImage (); + } - window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1); + window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1); - if (mainCropWin && zoom > 0.0) { - if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) { - Cairo::RefPtr cr = get_window()->create_cairo_context(); - int x, y, w, h; - getObservedFrameArea (x, y, w, h); - double rectX = x + 0.5; - double rectY = y + 0.5; - double rectW = std::min(w, (int)(imgW - (x - imgX) - 1)); - double rectH = std::min(h, (int)(imgH - (y - imgY) - 1)); + if (mainCropWin && zoom > 0.0) { + Cairo::RefPtr cr = get_window()->create_cairo_context(); + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + if (x>imgX || y>imgY || w < imgW || h < imgH) { + double rectX = x + 0.5; + double rectY = y + 0.5; + double rectW = std::min(w, (int)(imgW - (x - imgX) - 1)); + double rectH = std::min(h, (int)(imgH - (y - imgY) - 1)); - // draw a black "shadow" line - cr->set_source_rgba (0.0, 0.0, 0.0, 0.65); - cr->set_line_width (1); - cr->rectangle (rectX + 1., rectY + 1, rectW, rectH); - cr->stroke (); + // draw a black "shadow" line + cr->set_source_rgba (0.0, 0.0, 0.0, 0.65); + cr->set_line_width (1); + cr->rectangle (rectX + 1., rectY + 1, rectW, rectH); + cr->stroke (); - // draw a "frame" line. Color of frame line can be set in preferences - cr->set_source_rgba(options.navGuideBrush[0], options.navGuideBrush[1], options.navGuideBrush[2], options.navGuideBrush[3]); //( 1.0, 1.0, 1.0, 1.0); - cr->rectangle (rectX, rectY, rectW, rectH); - cr->stroke (); - } + // draw a "frame" line. Color of frame line can be set in preferences + cr->set_source_rgba(options.navGuideBrush[0], options.navGuideBrush[1], options.navGuideBrush[2], options.navGuideBrush[3]); //( 1.0, 1.0, 1.0, 1.0); + cr->rectangle (rectX, rectY, rectW, rectH); + cr->stroke (); } } @@ -191,9 +193,9 @@ bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) return true; } - if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) { - int x, y, w, h; - getObservedFrameArea (x, y, w, h); + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + if (x>imgX || y>imgY || w < imgW || h < imgH) { bool inside = event->x > x - 6 && event->x < x + w - 1 + 6 && event->y > y - 6 && event->y < y + h - 1 + 6; bool moreInside = event->x > x + 6 && event->x < x + w - 1 - 6 && event->y > y + 6 && event->y < y + h - 1 - 6; @@ -207,7 +209,7 @@ bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) cursorManager.setCursor (get_window(), CSArrow); } } - + return true; } @@ -218,9 +220,9 @@ bool PreviewWindow::on_button_press_event (GdkEventButton* event) return true; } - if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) { - int x, y, w, h; - getObservedFrameArea (x, y, w, h); + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + if (x>imgX || y>imgY || w < imgW || h < imgH) { bool inside = event->x > x - 6 && event->x < x + w - 1 + 6 && event->y > y - 6 && event->y < y + h - 1 + 6; bool moreInside = event->x > x + 6 && event->x < x + w - 1 - 6 && event->y > y + 6 && event->y < y + h - 1 - 6; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 8a37772f1..e6c2e8251 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -349,8 +349,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib:: if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged || event == rtengine::EvHistoryBrowsed || event == rtengine::EvCTRotate) { // updating the "on preview" geometry int fw, fh; - rtengine::ImageSource *ii = (rtengine::ImageSource*)ipc->getInitialImage(); - ii->getFullSize (fw, fh, tr); + ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr); gradient->updateGeometry (params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh); } @@ -430,8 +429,7 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi } // trimming overflowing cropped area - rtengine::ImageSource *ii = (rtengine::ImageSource*)ipc->getInitialImage(); - ii->getFullSize (fw, fh, tr); + ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr); crop->trim(params, fw, fh); // updating the GUI with updated values