From: buliabyak Date: Wed, 22 Mar 2006 23:41:24 +0000 (+0000) Subject: use rotation center in keyboard rotation and transform dialog X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=c89c32714737c143061a055b951c7b3ef6819bdd;p=inkscape.git use rotation center in keyboard rotation and transform dialog --- diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index e7e3ec4a3..851fc3a3b 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1450,7 +1450,7 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) if (selection->isEmpty()) return; - NR::Point const center(selection->bounds().midpoint()); + NR::Point center = selection->center(); sp_selection_rotate_relative(selection, center, angle_degrees); @@ -1470,7 +1470,8 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) return; NR::Rect const bbox(selection->bounds()); - NR::Point const center(bbox.midpoint()); + + NR::Point center = selection->center(); gdouble const zoom = selection->desktop()->current_zoom(); gdouble const zmove = angle / zoom; diff --git a/src/selection.cpp b/src/selection.cpp index 763713c9d..473a7202e 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -339,6 +339,23 @@ NR::Rect Selection::boundsInDocument() const { return NR::Rect(*boundsInDocument(&r)); } +/** Extract the position of the center from the first selected object */ +NR::Point Selection::center() const { + GSList *items = (GSList *) const_cast(this)->itemList(); + NR::Point center; + if (items) { + SPItem *first = reinterpret_cast(g_slist_last(items)->data); // from the first item in selection + if (first->isCenterSet()) { // only if set explicitly + center = first->getCenter(); + } else { + center = bounds().midpoint(); + } + } else { + center = bounds().midpoint(); + } + return center; +} + /** * Compute the list of points in the selection that are to be considered for snapping. */ diff --git a/src/selection.h b/src/selection.h index 6996e3ec8..6d403c426 100644 --- a/src/selection.h +++ b/src/selection.h @@ -241,6 +241,11 @@ public: */ ::NR::Rect boundsInDocument() const; + /** + * @brief Returns the rotation/skew center of the selection + */ + ::NR::Point center() const; + /** * @brief Gets the selection's snap points. * @return Selection's snap points diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 1d4557b90..b41ee1d5c 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -480,18 +480,7 @@ void Inkscape::SelTrans::_updateHandles() } if (!_center_is_set) { - // Extract the position of the center from the first selected object - GSList *items = (GSList *) _desktop->selection->itemList(); - if (items) { - SPItem *first = reinterpret_cast(g_slist_last(items)->data); // from the first item in selection - if (first->isCenterSet()) { // only if set explicitly - _center = first->getCenter(); - } else { - _center = _box.midpoint(); - } - } else { - _center = _box.midpoint(); - } + _center = _desktop->selection->center(); _center_is_set = true; } diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index beefc7640..c2b1a2648 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -28,20 +28,25 @@ static NR::translate inverse(NR::translate const m) void sp_item_rotate_rel(SPItem *item, NR::rotate const &rotation) { - NR::translate const s(sp_item_bbox_desktop(item).midpoint()); - - // Rotate item. - sp_item_set_i2d_affine(item, - sp_item_i2d_affine(item) * inverse(s) * rotation * s); - - // Use each item's own transform writer, consistent with sp_selection_apply_affine() - sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); + NR::Point center = item->getCenter(); + NR::translate const s(item->getCenter()); + NR::Matrix affine = NR::Matrix(inverse(s)) * NR::Matrix(rotation) * NR::Matrix(s); + + // Rotate item. + sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine); + // Use each item's own transform writer, consistent with sp_selection_apply_affine() + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); + + // Restore the center position (it's changed because the bbox center changed) + if (item->isCenterSet()) { + item->setCenter(center * affine); + } } void sp_item_scale_rel (SPItem *item, NR::scale const &scale) { - NR::translate const s(sp_item_bbox_desktop(item).midpoint()); + NR::translate const s(sp_item_bbox_desktop(item).midpoint()); // use getCenter? sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * inverse(s) * scale * s); @@ -51,15 +56,19 @@ sp_item_scale_rel (SPItem *item, NR::scale const &scale) void sp_item_skew_rel (SPItem *item, double skewX, double skewY) { - NR::Rect bbox(sp_item_bbox_desktop(item)); + NR::Point center = item->getCenter(); + NR::translate const s(item->getCenter()); - NR::translate const s(bbox.midpoint()); + NR::Matrix const skew(1, skewY, skewX, 1, 0, 0); + NR::Matrix affine = NR::Matrix(inverse(s)) * skew * NR::Matrix(s); - NR::Matrix const skew(1, skewY, skewX, 1, 0, 0); + sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine); + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); - sp_item_set_i2d_affine(item, - sp_item_i2d_affine(item) * inverse(s) * skew * s); - sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); + // Restore the center position (it's changed because the bbox center changed) + if (item->isCenterSet()) { + item->setCenter(center * affine); + } } void sp_item_move_rel(SPItem *item, NR::translate const &tr) diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 6056e4a2e..92baa7b81 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -613,7 +613,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection) } } else { NR::Rect bbox(selection->bounds()); - NR::Point center(bbox.midpoint()); + NR::Point center(bbox.midpoint()); // use rotation center? NR::scale scale (0,0); // the values are increments! if (_units_scale.isAbsolute()) { @@ -646,13 +646,11 @@ Transformation::applyPageRotate(Inkscape::Selection *selection) sp_item_rotate_rel(item, NR::rotate (angle*M_PI/180.0)); } } else { - NR::Rect bbox = selection->bounds(); - NR::Point center = bbox.midpoint(); + NR::Point center = selection->center(); sp_selection_rotate_relative(selection, center, angle); } sp_document_done(SP_DT_DOCUMENT(selection->desktop())); - } void @@ -685,7 +683,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection) NR::Rect bbox = selection->bounds(); double width = bbox.max()[NR::X] - bbox.min()[NR::X]; double height = bbox.max()[NR::Y] - bbox.min()[NR::Y]; - NR::Point center = bbox.midpoint(); + NR::Point center = selection->center(); if (!_units_skew.isAbsolute()) { // percentage double skewX = _scalar_skew_horizontal.getValue("%");