summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDiederik van Lierop <mail@diedenrezi.nl>2014-08-14 20:09:10 +0000
committerDiederik van Lierop <mail@diedenrezi.nl>2014-08-14 20:09:10 +0000
commit9fdd8f25ee0f04d337864c7ec5e3216dae727e3c (patch)
treed073668ec1fc35d95c1f59fe766411ef71915916 /src
parentRevert unintentional changes (diff)
downloadinkscape-9fdd8f25ee0f04d337864c7ec5e3216dae727e3c.tar.gz
inkscape-9fdd8f25ee0f04d337864c7ec5e3216dae727e3c.zip
Fix some transformation center regressions, related to the viewbox/units changes
(bzr r13512)
Diffstat (limited to 'src')
-rw-r--r--src/selection-chemistry.cpp7
-rw-r--r--src/sp-item-group.cpp8
-rw-r--r--src/sp-item.cpp26
-rw-r--r--src/ui/dialog/document-properties.cpp7
4 files changed, 28 insertions, 20 deletions
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index f058189d3..868a9d743 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1621,13 +1621,10 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate);
}
- // if we're transforming the actual object, not just updating the repr, we can transform the
+ // if we're moving the actual object, not just updating the repr, we can transform the
// center by the same matrix (only necessary for non-translations)
if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) {
- // If there's a viewbox, we might have an affine with a translation component;
- // we will only apply the scaling/skewing components, not the translations
- // because otherwise the center will move relative to the item
- item->setCenter(old_center * affine.withoutTranslation());
+ item->setCenter(old_center * affine);
item->updateRepr();
}
}
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 657aca692..bb52b0c55 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -660,12 +660,6 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p)
Geom::Translate const s(p);
Geom::Affine final = s.inverse() * sc * s;
- Geom::Point old_center(0,0);
- if (item->isCenterSet()) {
- item->scaleCenter(sc.inverse()); // Convert the old relative center position to the new coordinates already now
- old_center = item->getCenter(); // because getCenter() will use the bbox midpoint, which is also already in the new coordinates
- }
-
gchar const *conn_type = NULL;
if (SP_IS_TEXT_TEXTPATH(item)) {
SP_TEXT(item)->optimizeTextpathText();
@@ -710,7 +704,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p)
}
if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) {
- item->setCenter(old_center * final);
+ item->scaleCenter(sc); // All coordinates have been scaled, so also the center must be scaled
item->updateRepr();
}
}
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 0cacc86b1..428f9555e 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -228,18 +228,25 @@ void SPItem::setExplicitlyHidden(bool val) {
}
/**
- * Sets the transform_center_x and transform_center_y properties to retain the rotation centre
- */
+ * Sets the transform_center_x and transform_center_y properties to retain the rotation center
+*/
void SPItem::setCenter(Geom::Point const &object_centre) {
document->ensureUpToDate();
+ // Copied from DocumentProperties::onDocUnitChange()
+ gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width();
+ gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height();
+ gdouble viewscale = std::min(viewscale_h, viewscale_w);
+
// FIXME this is seriously wrong
Geom::OptRect bbox = desktopGeometricBounds();
if (bbox) {
- transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X];
+ // object centre is document coordinates (i.e. in pixels), so we need to consider the viewbox
+ // to translate to user units; transform_center_x/y is in user units
+ transform_center_x = (object_centre[Geom::X] - bbox->midpoint()[Geom::X])/viewscale;
if (Geom::are_near(transform_center_x, 0)) // rounding error
transform_center_x = 0;
- transform_center_y = object_centre[Geom::Y] - bbox->midpoint()[Geom::Y];
+ transform_center_y = (object_centre[Geom::Y] - bbox->midpoint()[Geom::Y])/viewscale;
if (Geom::are_near(transform_center_y, 0)) // rounding error
transform_center_y = 0;
}
@@ -255,16 +262,25 @@ bool SPItem::isCenterSet() const {
return (transform_center_x != 0 || transform_center_y != 0);
}
+// Get the item's transformation center in document coordinates (i.e. in pixels)
Geom::Point SPItem::getCenter() const {
document->ensureUpToDate();
+ // Copied from DocumentProperties::onDocUnitChange()
+ gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width();
+ gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height();
+ gdouble viewscale = std::min(viewscale_h, viewscale_w);
+
// FIXME this is seriously wrong
Geom::OptRect bbox = desktopGeometricBounds();
if (bbox) {
- return bbox->midpoint() + Geom::Point (transform_center_x, transform_center_y);
+ // transform_center_x/y are stored in user units, so we have to take the viewbox into account to translate to document coordinates
+ return bbox->midpoint() + Geom::Point (transform_center_x*viewscale, transform_center_y*viewscale);
+
} else {
return Geom::Point(0, 0); // something's wrong!
}
+
}
void
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 9141b2268..4e4616724 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -45,6 +45,7 @@
#include "widgets/icon.h"
#include "xml/node-event-vector.h"
#include "xml/repr.h"
+#include <algorithm> // std::min
#include "rdf.h"
#include "ui/widget/entity-entry.h"
@@ -1735,9 +1736,9 @@ void DocumentProperties::onDocUnitChange()
prefs->setBool("/options/transform/gradient", true);
{
ShapeEditor::blockSetItem(true);
- gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width();
- if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale)
- viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height();
+ gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width();
+ gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height();
+ gdouble viewscale = std::min(viewscale_h, viewscale_w);
gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit);
doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] +
(doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2,