[aseprite] 161/196: Add scaling from center/pivot (fix #576) and with flipping (fix #579)

Tobias Hansen thansen at moszumanska.debian.org
Wed Apr 20 18:50:15 UTC 2016


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 8a5de088e2f222fea69526aca28b70772090901d
Author: David Capello <davidcapello at gmail.com>
Date:   Fri Apr 8 11:55:40 2016 -0300

    Add scaling from center/pivot (fix #576) and with flipping (fix #579)
---
 data/gui.xml                              |   4 +
 src/app/ui/editor/moving_pixels_state.cpp |   5 +-
 src/app/ui/editor/pixels_movement.cpp     | 184 +++++++++++++-----------------
 src/app/ui/editor/pixels_movement.h       |   5 +-
 src/app/ui/keyboard_shortcuts.cpp         |   2 +
 src/app/ui/keyboard_shortcuts.h           |   1 +
 6 files changed, 94 insertions(+), 107 deletions(-)

diff --git a/data/gui.xml b/data/gui.xml
index 1d1cb01..a0d4d4a 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -473,6 +473,10 @@
            keyboard shortcut you maintain aspect ratio -->
       <key action="MaintainAspectRatio" shortcut="Shift" />
 
+      <!-- When you scale the selection, pressing this key the
+           selectino will be scaled from the pivot point -->
+      <key action="ScaleFromCenter" shortcut="Alt" />
+
       <!-- Modifiers for selection tool -->
       <key action="AddSelection" shortcut="Shift" />
       <key action="SubtractSelection" shortcut="Shift+Alt" />
diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp
index 9f3e03f..0be8360 100644
--- a/src/app/ui/editor/moving_pixels_state.cpp
+++ b/src/app/ui/editor/moving_pixels_state.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -355,6 +355,9 @@ bool MovingPixelsState::onMouseMove(Editor* editor, MouseMessage* msg)
     if (int(action & KeyAction::MaintainAspectRatio))
       moveModifier |= PixelsMovement::MaintainAspectRatioMovement;
 
+    if (int(action & KeyAction::ScaleFromCenter))
+      moveModifier |= PixelsMovement::ScaleFromPivot;
+
     if (int(action & KeyAction::LockAxis))
       moveModifier |= PixelsMovement::LockAxisMovement;
 
diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp
index 81afc82..e21a1fa 100644
--- a/src/app/ui/editor/pixels_movement.cpp
+++ b/src/app/ui/editor/pixels_movement.cpp
@@ -228,147 +228,123 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
   m_currentData.transformBox(oldCorners);
 
   ContextWriter writer(m_reader, 1000);
-  int x1, y1, x2, y2;
-
-  x1 = m_initialData.bounds().x;
-  y1 = m_initialData.bounds().y;
-  x2 = m_initialData.bounds().x + m_initialData.bounds().w;
-  y2 = m_initialData.bounds().y + m_initialData.bounds().h;
-
+  gfx::Rect bounds = m_initialData.bounds();
   bool updateBounds = false;
-  int dx, dy;
+  double dx, dy;
 
-  dx = int((pos.x - m_catchPos.x) *  cos(m_currentData.angle()) +
-           (pos.y - m_catchPos.y) * -sin(m_currentData.angle()));
-  dy = int((pos.x - m_catchPos.x) *  sin(m_currentData.angle()) +
-           (pos.y - m_catchPos.y) *  cos(m_currentData.angle()));
+  dx = ((pos.x - m_catchPos.x) *  cos(m_currentData.angle()) +
+        (pos.y - m_catchPos.y) * -sin(m_currentData.angle()));
+  dy = ((pos.x - m_catchPos.x) *  sin(m_currentData.angle()) +
+        (pos.y - m_catchPos.y) *  cos(m_currentData.angle()));
 
   switch (m_handle) {
 
     case MoveHandle:
-      x1 += dx;
-      y1 += dy;
-      x2 += dx;
-      y2 += dy;
-      updateBounds = true;
-
       if ((moveModifier & LockAxisMovement) == LockAxisMovement) {
-        if (ABS(dx) < ABS(dy)) {
-          x1 -= dx;
-          x2 -= dx;
-        }
-        else {
-          y1 -= dy;
-          y2 -= dy;
-        }
+        if (ABS(dx) < ABS(dy))
+          dx = 0.0;
+        else
+          dy = 0.0;
       }
 
+      bounds.offset(int(dx), int(dy));
+      updateBounds = true;
+
       if ((moveModifier & SnapToGridMovement) == SnapToGridMovement) {
         // Snap the x1,y1 point to the grid.
         gfx::Rect gridBounds = App::instance()
           ->preferences().document(m_document).grid.bounds();
-        gfx::Point gridOffset(x1, y1);
+        gfx::Point gridOffset(bounds.origin());
         gridOffset = snap_to_grid(gridBounds, gridOffset,
                                   PreferSnapTo::ClosestGridVertex);
 
         // Now we calculate the difference from x1,y1 point and we can
         // use it to adjust all coordinates (x1, y1, x2, y2).
-        gridOffset -= gfx::Point(x1, y1);
-
-        x1 += gridOffset.x;
-        y1 += gridOffset.y;
-        x2 += gridOffset.x;
-        y2 += gridOffset.y;
+        gridOffset -= bounds.origin();
+        bounds.offset(gridOffset);
       }
       break;
 
     case ScaleNWHandle:
-      x1 = MIN(x1+dx, x2-1);
-      y1 = MIN(y1+dy, y2-1);
-
-      if ((moveModifier & MaintainAspectRatioMovement) == MaintainAspectRatioMovement) {
-        if (1000 * (x2-x1) / getInitialImageSize().w >
-            1000 * (y2-y1) / getInitialImageSize().h) {
-          y1 = y2 - getInitialImageSize().h * (x2-x1) / getInitialImageSize().w;
-        }
-        else {
-          x1 = x2 - getInitialImageSize().w * (y2-y1) / getInitialImageSize().h;
-        }
-      }
-
-      updateBounds = true;
-      break;
-
     case ScaleNHandle:
-      y1 = MIN(y1+dy, y2-1);
-      updateBounds = true;
-      break;
-
     case ScaleNEHandle:
-      x2 = MAX(x2+dx, x1+1);
-      y1 = MIN(y1+dy, y2-1);
-
-      if ((moveModifier & MaintainAspectRatioMovement) == MaintainAspectRatioMovement) {
-        if (1000 * (x2-x1) / getInitialImageSize().w >
-            1000 * (y2-y1) / getInitialImageSize().h) {
-          y1 = y2 - getInitialImageSize().h * (x2-x1) / getInitialImageSize().w;
-        }
-        else {
-          x2 = x1 + getInitialImageSize().w * (y2-y1) / getInitialImageSize().h;
-        }
-      }
-
-      updateBounds = true;
-      break;
-
     case ScaleWHandle:
-      x1 = MIN(x1+dx, x2-1);
-      updateBounds = true;
-      break;
-
     case ScaleEHandle:
-      x2 = MAX(x2+dx, x1+1);
-      updateBounds = true;
-      break;
-
     case ScaleSWHandle:
-      x1 = MIN(x1+dx, x2-1);
-      y2 = MAX(y2+dy, y1+1);
-
-      if ((moveModifier & MaintainAspectRatioMovement) == MaintainAspectRatioMovement) {
-        if (1000 * (x2-x1) / getInitialImageSize().w >
-            1000 * (y2-y1) / getInitialImageSize().h) {
-          y2 = y1 + getInitialImageSize().h * (x2-x1) / getInitialImageSize().w;
-        }
-        else {
-          x1 = x2 - getInitialImageSize().w * (y2-y1) / getInitialImageSize().h;
-        }
+    case ScaleSHandle:
+    case ScaleSEHandle: {
+      static double handles[][2] = {
+        { 0.0, 0.0 }, { 0.5, 0.0 }, { 1.0, 0.0 },
+        { 0.0, 0.5 },               { 1.0, 0.5 },
+        { 0.0, 1.0 }, { 0.5, 1.0 }, { 1.0, 1.0 }
+      };
+      gfx::PointT<double> pivot;
+      gfx::PointT<double> handle(
+        handles[m_handle-ScaleNWHandle][0],
+        handles[m_handle-ScaleNWHandle][1]);
+
+      if ((moveModifier & ScaleFromPivot) == ScaleFromPivot) {
+        pivot.x = m_currentData.pivot().x;
+        pivot.y = m_currentData.pivot().y;
+      }
+      else {
+        pivot.x = 1.0 - handle.x;
+        pivot.y = 1.0 - handle.y;
+        pivot.x = bounds.x + bounds.w*pivot.x;
+        pivot.y = bounds.y + bounds.h*pivot.y;
       }
 
-      updateBounds = true;
-      break;
+      gfx::Point a = bounds.origin();
+      gfx::Point b = bounds.point2();
 
-    case ScaleSHandle:
-      y2 = MAX(y2+dy, y1+1);
-      updateBounds = true;
-      break;
+      if ((moveModifier & MaintainAspectRatioMovement) == MaintainAspectRatioMovement) {
+        auto u = point2Vector(gfx::PointT<double>(m_catchPos) - pivot);
+        auto v = point2Vector(gfx::PointT<double>(pos) - pivot);
+        auto w = v.projectOn(u);
+        double scale = u.magnitude();
+        if (scale != 0.0)
+          scale = (std::fabs(w.angle()-u.angle()) < PI/2.0 ? 1.0: -1.0) * w.magnitude() / scale;
+        else
+          scale = 1.0;
+
+        a.x = int((a.x-pivot.x)*scale + pivot.x);
+        a.y = int((a.y-pivot.y)*scale + pivot.y);
+        b.x = int((b.x-pivot.x)*scale + pivot.x);
+        b.y = int((b.y-pivot.y)*scale + pivot.y);
+      }
+      else {
+        handle.x = bounds.x + bounds.w*handle.x;
+        handle.y = bounds.y + bounds.h*handle.y;
 
-    case ScaleSEHandle:
-      x2 = MAX(x2+dx, x1+1);
-      y2 = MAX(y2+dy, y1+1);
+        double w = (handle.x-pivot.x);
+        double h = (handle.y-pivot.y);
 
-      if ((moveModifier & MaintainAspectRatioMovement) == MaintainAspectRatioMovement) {
-        if (1000 * (x2-x1) / getInitialImageSize().w >
-            1000 * (y2-y1) / getInitialImageSize().h) {
-          y2 = y1 + getInitialImageSize().h * (x2-x1) / getInitialImageSize().w;
+        if (m_handle == ScaleNHandle || m_handle == ScaleSHandle) {
+          dx = 0.0;
+          w = 1.0;              // Any value != 0.0 to avoid div by zero
         }
-        else {
-          x2 = x1 + getInitialImageSize().w * (y2-y1) / getInitialImageSize().h;
+        else if (m_handle == ScaleWHandle || m_handle == ScaleEHandle) {
+          dy = 0.0;
+          h = 1.0;
         }
+
+        a.x = (a.x-pivot.x)*(1.0+dx/w) + pivot.x;
+        a.y = (a.y-pivot.y)*(1.0+dy/h) + pivot.y;
+        b.x = (b.x-pivot.x)*(1.0+dx/w) + pivot.x;
+        b.y = (b.y-pivot.y)*(1.0+dy/h) + pivot.y;
       }
 
+      // Do not use "gfx::Rect(a, b)" here because if a > b we want to
+      // keep a rectangle with negative width or height (to know that
+      // it was flipped).
+      bounds.x = a.x;
+      bounds.y = a.y;
+      bounds.w = b.x - a.x;
+      bounds.h = b.y - a.y;
+
       updateBounds = true;
       break;
+    }
 
     case RotateNWHandle:
     case RotateNHandle:
@@ -432,7 +408,7 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
   }
 
   if (updateBounds) {
-    m_currentData.bounds(gfx::Rect(x1, y1, x2 - x1, y2 - y1));
+    m_currentData.bounds(bounds);
     m_adjustPivot = true;
   }
 
diff --git a/src/app/ui/editor/pixels_movement.h b/src/app/ui/editor/pixels_movement.h
index 7490ac7..84c74f4 100644
--- a/src/app/ui/editor/pixels_movement.h
+++ b/src/app/ui/editor/pixels_movement.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -44,7 +44,8 @@ namespace app {
       SnapToGridMovement = 2,
       AngleSnapMovement = 4,
       MaintainAspectRatioMovement = 8,
-      LockAxisMovement = 16
+      LockAxisMovement = 16,
+      ScaleFromPivot = 32,
     };
 
     PixelsMovement(Context* context,
diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp
index d9f895c..53c6f77 100644
--- a/src/app/ui/keyboard_shortcuts.cpp
+++ b/src/app/ui/keyboard_shortcuts.cpp
@@ -39,6 +39,7 @@ namespace {
     { "SnapToGrid"          , "Snap To Grid"       , app::KeyAction::SnapToGrid },
     { "AngleSnap"           , "Angle Snap"         , app::KeyAction::AngleSnap },
     { "MaintainAspectRatio" , "Maintain Aspect Ratio", app::KeyAction::MaintainAspectRatio },
+    { "ScaleFromCenter"     , "Scale From Center"   , app::KeyAction::ScaleFromCenter },
     { "LockAxis"            , "Lock Axis"          , app::KeyAction::LockAxis },
     { "AddSelection"        , "Add Selection"      , app::KeyAction::AddSelection },
     { "SubtractSelection"   , "Subtract Selection" , app::KeyAction::SubtractSelection },
@@ -147,6 +148,7 @@ Key::Key(KeyAction action)
       m_keycontext = KeyContext::RotatingSelection;
       break;
     case KeyAction::MaintainAspectRatio:
+    case KeyAction::ScaleFromCenter:
       m_keycontext = KeyContext::ScalingSelection;
       break;
     case KeyAction::AddSelection:
diff --git a/src/app/ui/keyboard_shortcuts.h b/src/app/ui/keyboard_shortcuts.h
index bd53a4c..ed6cd49 100644
--- a/src/app/ui/keyboard_shortcuts.h
+++ b/src/app/ui/keyboard_shortcuts.h
@@ -71,6 +71,7 @@ namespace app {
     MoveOrigin                = 0x00000800,
     SquareAspect              = 0x00001000,
     DrawFromCenter            = 0x00002000,
+    ScaleFromCenter           = 0x00004000,
   };
 
   inline KeyAction operator&(KeyAction a, KeyAction b) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list