[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    Flake Resize
From:       Fredy Yanardi <fyanardi () gmail ! com>
Date:       2007-02-22 17:07:11
Message-ID: 200702230107.11410.fyanardi () gmail ! com
[Download RAW message or body]

Hello,

Currently combined actions for flake are mostly broken (resize only works if 
the shape is not sheared, rotated, mirrored, etc). For few days I've been 
working to fix that. I haven't fixed all issues yet, but what I've done so 
far can be summarized here:

Mirror:
o Mirror + resize : OK
o Mirror + rotate : OK
o Mirror + rotate + resize : OK

Shear
o shear + resize : OK
o shear + rotate : OK
o shear + rotate + resize : OK
o shear + mirror: OK
o shear + mirror + resize : partially works
o shear + mirror + rotate : ---
o shear + mirror + resize + rotate : ---

o Scale From Center doesn't work correctly (haven't looked at that yet)

Also, currently resizing doesn't change shearX or/and shearY components. From 
my observation, in Karbon 1.6, Inkscape, and OpenOffice.org Draw, resize also 
resizes the shear components (the shearX / shearY also become zoomed in / 
out). Which behaviour do we expect from flake? Zooming the shear components 
or just leave the shear components unchanged?

Here I also attach a patch for what I've done so far. Shall I continue to work 
on this? I was working on revision 635012.

Thanks and Best Regards,

Fredy Yanardi

["KoShapeResizeStrategy.diff" (text/x-diff)]

Index: KoShapeResizeStrategy.h
===================================================================
--- KoShapeResizeStrategy.h	(revision 635012)
+++ KoShapeResizeStrategy.h	(working copy)
@@ -57,6 +57,7 @@
     QList<double> m_startScaleXs;
     QList<double> m_startScaleYs;
     bool m_top, m_left, m_bottom, m_right;
+    bool m_selectionCount;    // 0 for 0, 1 for > 1
     QMatrix m_unwindMatrix, m_windMatrix;
     QSizeF m_initialSize;
     QPointF m_initialPosition;
Index: KoShapeResizeStrategy.cpp
===================================================================
--- KoShapeResizeStrategy.cpp	(revision 635012)
+++ KoShapeResizeStrategy.cpp	(working copy)
@@ -46,9 +46,15 @@
 
     KoShape *shp = 0;
     if(canvas->shapeManager()->selection()->count()>1)
-       shp = canvas->shapeManager()->selection();
+    {
+        shp = canvas->shapeManager()->selection();
+        m_selectionCount = true;
+    }
     if(canvas->shapeManager()->selection()->count()==1)
+    {
         shp = canvas->shapeManager()->selection()->firstSelectedShape();
+        m_selectionCount = false;
+    }
 
     m_unwindMatrix = QMatrix();
     if (shp)
@@ -87,67 +93,108 @@
     QPointF newPos = point;
     if(m_canvas->snapToGrid() && (modifiers & Qt::ShiftModifier) == 0)
         applyGrid(newPos);
-    QPointF distance = newPos - m_start;
+    QPointF distance;
 
     bool keepAspect = modifiers & Qt::AltModifier;
-    foreach(KoShape *shape, m_selectedShapes)
-        keepAspect = keepAspect || shape->keepAspectRatio();
 
     double startWidth = m_initialSize.width();
     double startHeight = m_initialSize.height();
-    distance = m_unwindMatrix.map(distance);
 
-    double zoomX=1, zoomY=1;
-    if(keepAspect) {
-        double ratio = startWidth / startHeight;
-        double width = startWidth - distance.x();
-        double height = startHeight - distance.y();
-        int toLargestEdge = (m_bottom?1:0) + (m_top?1:0) + // should be false when \
                only one
-            (m_left?1:0) + (m_right?1:0);                  // of the direction bools \
                is set
-        bool horizontal = m_left || m_right;
+    double zoomX, zoomY;
 
-        if(toLargestEdge != 1) { // one of the corners.
-            if (width < height) // the biggest border is the one in control
-                width = height * ratio;
-            else
-                height = width / ratio;
-        } else {
-            if (horizontal)
-                height = width / ratio;
-            else
-                width = height * ratio;
-        }
-        zoomX = startWidth / width;
-        zoomY = startHeight / height;
-    }
-    else {
-        if(m_left)
-            zoomX = (startWidth - distance.x()) / startWidth;
-        else if(m_right)
-            zoomX = (startWidth + distance.x()) / startWidth;
-        if(m_top)
-            zoomY = (startHeight - distance.y()) / startHeight;
-        else if(m_bottom)
-            zoomY = (startHeight + distance.y()) / startHeight;
-    }
-
     bool scaleFromCenter = modifiers & Qt::ControlModifier;
     QPointF move;
     QMatrix matrix;
 
-    if(scaleFromCenter)
-        move = QPointF(startWidth / 2.0, startHeight / 2.0);
-    else
-        move = QPointF(m_left?startWidth:0, m_top?startHeight:0);
+    double shearX_final;
+    double shearY_final;
 
-    matrix.translate(move.x(), move.y()); // translate to 
-    matrix.scale(zoomX, zoomY);
-    matrix.translate(-move.x(), -move.y()); // and back
+    double rotation;
+    QPointF shapeInitialPosition, pos;
 
-    matrix = m_unwindMatrix * matrix * m_windMatrix;
     int i=0;
     foreach(KoShape *shape, m_selectedShapes) {
-        QPointF pos(m_startAbsolutePositions[i] - m_initialPosition);
+        keepAspect = keepAspect || shape->keepAspectRatio();
+        distance = newPos - m_start;
+
+        if(scaleFromCenter)
+            move = QPointF(startWidth / 2.0, startHeight / 2.0);
+        else
+            move = QPointF(m_left?startWidth:0, m_top?startHeight:0);
+
+        if (m_startShearXs[i] < 0)
+            distance -= QPointF(distance.x() * -1 * m_startShearXs[i] * startHeight \
/ (2 * startWidth - m_startShearXs[i] * startHeight), 0); +        else if \
(m_startShearXs[i] > 0) +            distance -= QPointF(distance.x() * \
m_startShearXs[i] * startHeight / (2 * startWidth + m_startShearXs[i] * startHeight), \
0); +
+        if (m_startShearYs[i] < 0)
+            distance -= QPointF(0, distance.y() * -1 * m_startShearYs[i] * \
startWidth / (2 * startHeight - m_startShearYs[i] * startWidth)); +        else if \
(m_startShearYs[i] > 0) +            distance -= QPointF(0, distance.y() * \
m_startShearYs[0] * startWidth / (2 * startHeight + m_startShearYs[i] * startWidth)); \
+ +        distance = m_unwindMatrix.map(distance);
+
+        zoomX=1;
+        zoomY=1;
+
+        if(keepAspect) {
+            double ratio = startWidth / startHeight;
+            double width = startWidth - distance.x();
+            double height = startHeight - distance.y();
+            int toLargestEdge = (m_bottom?1:0) + (m_top?1:0) + // should be false \
when only one +                (m_left?1:0) + (m_right?1:0);                  // of \
the direction bools is set +            bool horizontal = m_left || m_right;
+
+            if(toLargestEdge != 1) { // one of the corners.
+                if (width < height) // the biggest border is the one in control
+                    width = height * ratio;
+                else
+                    height = width / ratio;
+            } else {
+                if (horizontal)
+                    height = width / ratio;
+                else
+                    width = height * ratio;
+            }
+            zoomX = startWidth / width;
+            zoomY = startHeight / height;
+        }
+        else {
+            if(m_left)
+                zoomX = (startWidth - distance.x()) / startWidth;
+            else if(m_right)
+                zoomX = (startWidth + distance.x()) / startWidth;
+            if(m_top)
+                zoomY = (startHeight - distance.y()) / startHeight;
+            else if(m_bottom)
+                zoomY = (startHeight + distance.y()) / startHeight;
+        }
+
+        if (m_right && m_startShearXs[i] < 0)
+            move += QPointF(m_startShearXs[i] * startHeight, 0);
+        else if (m_left && m_startShearXs[i] > 0)
+            move += QPointF(m_startShearXs[i] * startHeight, 0);
+
+        if (m_bottom && m_startShearYs[i] < 0)
+            move += QPointF(0, m_startShearYs[i] * startWidth);
+        if (m_top && m_startShearYs[0] > 0)
+            move += QPointF(0, m_startShearYs[i] * startWidth);
+
+        matrix.translate(move.x(), move.y()); // translate to 
+        matrix.scale(zoomX, zoomY);
+        matrix.translate(-move.x(), -move.y()); // and back
+        matrix = m_unwindMatrix * matrix * m_windMatrix;
+
+        shapeInitialPosition = m_initialPosition;
+        rotation = shape->rotation() * M_PI / 180;
+        // if the scale if negative (mirror), we need to calculate the corrent \
initial position +        // plus considering the rotation of the shape
+        if (!m_selectionCount && m_startScaleXs[i] < 0)
+            shapeInitialPosition -= QPointF(m_startSizes[i].width() * cos(rotation), \
m_startSizes[i].width() * sin(rotation)); +        if (!m_selectionCount && \
m_startScaleYs[i] < 0) +            shapeInitialPosition -= \
QPointF(m_startSizes[i].height() * -1 * sin(rotation), m_startSizes[i].height() * \
cos(rotation)); +
+        pos = m_startAbsolutePositions[i] - shapeInitialPosition;
         pos = matrix.map(pos);
 
         // construct the matrix tranformation we apply to the shape
@@ -171,8 +218,13 @@
         shape->scale(x, y);
 
         shape->resize( size );
-        shape->shear(m_startShearXs[i] + m.m12() / m.m22(), m_startShearYs[i] + \
                m.m21() / m.m11());
-        shape->setAbsolutePosition( pos + m_initialPosition );
+
+        shearX_final = (m_startShearXs[i] * startHeight * zoomX) / (startHeight * \
zoomY); +        shearY_final = (m_startShearYs[i] * startWidth * zoomY) / \
(startWidth * zoomX); +
+        shape->shear(shearX_final + m.m12() / m.m22(), shearY_final + m.m21() / \
m.m11()); +        shape->setAbsolutePosition( pos + shapeInitialPosition );
+        qDebug() << "m_startShearXs[0]: " << m_startShearXs[0] << " \
m_startShearYs[0]: " << m_startShearYs[0];  shape->repaint();
         i++;
     }



_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic