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

List:       kde-commits
Subject:    Re: koffice/plugins/pathshapes/enhancedpath
From:       Carlos Licea <carlos_licea () hotmail ! com>
Date:       2010-03-10 1:27:21
Message-ID: BLU0-SMTP16A6C91DA10DE3A494C0CBF2330 () phx ! gbl
[Download RAW message or body]

On Tuesday 09 March 2010 15:43:02 Jan Hambrecht escribió:
>SVN commit 1101341 by jaham:
>
>make viewbox transformation more robust and also enable mirroring
>
>
>
> M  +18 -23    EnhancedPathCommand.cpp
> M  +52 -57    EnhancedPathShape.cpp
> M  +17 -13    EnhancedPathShape.h
>
>
>--- trunk/koffice/plugins/pathshapes/enhancedpath/EnhancedPathCommand.cpp
>#1101340:1101341 @@ -58,22 +58,20 @@
>     case 'M':
>         if (!pointsCount)
>             return false;
>-        m_parent->moveTo(m_parent->viewboxToShape(points[0]));
>+        m_parent->moveTo(points[0]);
>         if (pointsCount > 1)
>             for (int i = 1; i < pointsCount; i++)
>-                m_parent->lineTo(m_parent->viewboxToShape(points[i]));
>+                m_parent->lineTo(points[i]);
>         break;
>     // line from current point (x y) +
>     case 'L':
>         foreach(const QPointF &point, points)
>-            m_parent->lineTo(m_parent->viewboxToShape(point));
>+            m_parent->lineTo(point);
>         break;
>     // cubic bezier curve from current point (x1 y1 x2 y2 x y) +
>     case 'C':
>         for (int i = 0; i < pointsCount; i+=3)
>-            m_parent->curveTo(m_parent->viewboxToShape(points[i]),
>-                               m_parent->viewboxToShape(points[i+1]),
>-                               m_parent->viewboxToShape(points[i+2]));
>+            m_parent->curveTo(points[i], points[i+1], points[i+2]);
>         break;
>     // closes the current subpath
>     case 'Z':
>@@ -98,16 +96,16 @@
>         bool lineTo = m_command.unicode() == 'T';
>
>         for (int i = 0; i < pointsCount; i+=3) {
>-            const QPointF &radii = m_parent->viewboxToShape(points[i+1]);
>+            const QPointF &radii = points[i+1];
>             const QPointF &angles = points[i+2] / rad2deg;
>             // compute the ellipses starting point
>             QPointF start(radii.x() * cos(angles.x()), radii.y() *
>sin(angles.x())); qreal sweepAngle = degSweepAngle(points[i+2].x(),
>points[i+2].y(), false);
>
>             if (lineTo)
>-                m_parent->lineTo(m_parent->viewboxToShape(points[i]) +
>start); +                m_parent->lineTo(points[i] + start);
>             else
>-                m_parent->moveTo(m_parent->viewboxToShape(points[i]) +
>start); +                m_parent->moveTo(points[i] + start);
>
>             m_parent->arcTo(radii.x(), radii.y(), points[i+2].x(),
>sweepAngle); }
>@@ -122,8 +120,8 @@
>         for (int i = 0; i < pointsCount; i+=4) {
>             QRectF bbox = rectFromPoints(points[i], points[i+1]);
>             QPointF center = bbox.center();
>-            qreal rx = 0.5 * m_parent->viewboxToShape(bbox.width());
>-            qreal ry = 0.5 * m_parent->viewboxToShape(bbox.height());
>+            qreal rx = 0.5 * bbox.width();
>+            qreal ry = 0.5 * bbox.height();
>             qreal startAngle = angleFromPoint(points[i+2] - center);
>             qreal stopAngle = angleFromPoint(points[i+3] - center);
>             // we are moving counter-clockwise to the end angle
>@@ -132,9 +130,9 @@
>             QPointF startPoint(rx * cos(startAngle), ry * sin(2*M_PI -
>startAngle));
>
>             if (lineTo)
>-                m_parent->lineTo(m_parent->viewboxToShape(center) +
>startPoint); +                m_parent->lineTo(center + startPoint);
>             else
>-                m_parent->moveTo(m_parent->viewboxToShape(center) +
>startPoint); +                m_parent->moveTo(center + startPoint);
>
>             m_parent->arcTo(rx, ry, startAngle * rad2deg, sweepAngle *
>rad2deg); }
>@@ -149,17 +147,17 @@
>         for (int i = 0; i < pointsCount; i+=4) {
>             QRectF bbox = rectFromPoints(points[i], points[i+1]);
>             QPointF center = bbox.center();
>-            qreal rx = 0.5 * m_parent->viewboxToShape(bbox.width());
>-            qreal ry = 0.5 * m_parent->viewboxToShape(bbox.height());
>+            qreal rx = 0.5 * bbox.width();
>+            qreal ry = 0.5 * bbox.height();
>             qreal startAngle = angleFromPoint(points[i+2] - center);
>             qreal stopAngle = angleFromPoint(points[i+3] - center);
>             // we are moving clockwise to the end angle
>             qreal sweepAngle = radSweepAngle(startAngle, stopAngle, true);
>
>             if (lineTo)
>-                m_parent->lineTo(m_parent->viewboxToShape(points[i+2]));
>+                m_parent->lineTo(points[i+2]);
>             else
>-                m_parent->moveTo(m_parent->viewboxToShape(points[i+2]));
>+                m_parent->moveTo(points[i+2]);
>
>             m_parent->arcTo(rx, ry, startAngle * rad2deg, sweepAngle *
>rad2deg); }
>@@ -168,8 +166,7 @@
>     // elliptical quadrant (initial segment tangential to x-axis) (x y) +
>     case 'X': {
>         KoPathPoint * lastPoint = lastPathPoint();
>-        foreach (QPointF point, points) {
>-            point = m_parent->viewboxToShape(point);
>+        foreach (const QPointF &point, points) {
>             qreal rx = point.x() - lastPoint->point().x();
>             qreal ry = point.y() - lastPoint->point().y();
>             qreal startAngle = ry > 0.0 ? 90.0 : 270.0;
>@@ -181,8 +178,7 @@
>     // elliptical quadrant (initial segment tangential to y-axis) (x y) +
>     case 'Y': {
>         KoPathPoint * lastPoint = lastPathPoint();
>-        foreach (QPointF point, points) {
>-            point = m_parent->viewboxToShape(point);
>+        foreach (const QPointF &point, points) {
>             qreal rx = point.x() - lastPoint->point().x();
>             qreal ry = point.y() - lastPoint->point().y();
>             qreal startAngle = rx < 0.0 ? 0.0 : 180.0;
>@@ -194,8 +190,7 @@
>     // quadratic bezier curve (x1 y1 x y)+
>     case 'Q':
>         for (int i = 0; i < pointsCount; i+=2)
>-            m_parent->curveTo(m_parent->viewboxToShape(points[i]),
>-                               m_parent->viewboxToShape(points[i+1]));
>+            m_parent->curveTo(points[i], points[i+1]);
>         break;
>     default:
>         break;
>--- trunk/koffice/plugins/pathshapes/enhancedpath/EnhancedPathShape.cpp
>#1101340:1101341 @@ -1,5 +1,5 @@
> /* This file is part of the KDE project
>- * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
>+ * Copyright (C) 2007,2010 Jan Hambrecht <jaham@gmx.net>
>  * Copyright (C) 2009-2010 Thomas Zander <zander@kde.org>
>  *
>  * This library is free software; you can redistribute it and/or
>@@ -30,6 +30,7 @@
> #include <KoShapeSavingContext.h>
> #include <KoUnit.h>
> #include <KoOdfWorkaround.h>
>+#include <KoPathPoint.h>
>
> EnhancedPathShape::EnhancedPathShape(const QRectF &viewBox)
>
> : m_viewBox(viewBox), m_viewBoxOffset(0.0, 0.0),
> : m_mirrorVertically(false), m_mirrorHorizontally(false)
>
>@@ -64,7 +65,6 @@
>     EnhancedPathHandle *handle = m_enhancedHandles[ handleId ];
>     if (handle) {
>         handle->changePosition(shapeToViewbox(point));
>-        evaluateHandles();
>     }
> }
>
>@@ -75,42 +75,73 @@
>     foreach (EnhancedPathCommand *cmd, m_commands)
>         cmd->execute();
>
>+    m_viewBound = outline().boundingRect();
>+
>+    QMatrix matrix;
>+    matrix.translate(m_viewBoxOffset.x(), m_viewBoxOffset.y());
>+    matrix = m_viewMatrix * matrix;
>+
>+    KoSubpathList::const_iterator pathIt(m_subpaths.constBegin());
>+    for (; pathIt != m_subpaths.constEnd(); ++pathIt) {
>+        KoSubpath::const_iterator it((*pathIt)->constBegin());
>+        for (; it != (*pathIt)->constEnd(); ++it) {
>+            (*it)->map(matrix);
>+        }
>+    }
>+    const int handleCount = m_enhancedHandles.count();
>+    QList<QPointF> handles;
>+    for (int i = 0; i < handleCount; ++i)
>+        handles.append(matrix.map(m_enhancedHandles[i]->position()));
>+    setHandles(handles);
>+
>     normalize();
> }
>
> void EnhancedPathShape::setSize(const QSizeF &newSize)
> {
>-    QMatrix matrix(resizeMatrix(newSize));
>-
>     KoParameterShape::setSize(newSize);
>
>-    qreal scaleX = matrix.m11();
>-    qreal scaleY = matrix.m22();
>-    m_viewBoxOffset.rx() *= scaleX;
>-    m_viewBoxOffset.ry() *= scaleY;
>-    m_viewMatrix.scale(scaleX, scaleY);
>+    // calculate scaling factors from viewbox size to shape size
>+    qreal xScale = newSize.width()/m_viewBound.width();
>+    qreal yScale = newSize.height()/m_viewBound.height();
>
>-    setMirroring();
>+    // create view matrix, take mirroring into account
>+    m_viewMatrix.reset();
>+    m_viewMatrix.translate(m_viewBound.center().x(),
>m_viewBound.center().y()); +    m_viewMatrix.scale(m_mirrorHorizontally ?
>-xScale : xScale, m_mirrorVertically ? -yScale : yScale); +   
>m_viewMatrix.translate(-m_viewBound.center().x(),
>-m_viewBound.center().y()); +
>+    updatePath(newSize);
> }
>
>-
> QPointF EnhancedPathShape::normalize()
> {
>-    QPointF offset = KoPathShape::normalize();
>+    QPointF offset = KoParameterShape::normalize();
>+
>     m_viewBoxOffset -= offset;
>
>     return offset;
> }
>
>+QPointF EnhancedPathShape::shapeToViewbox(const QPointF &point) const
>+{
>+    return m_viewMatrix.inverted().map( point-m_viewBoxOffset );
>+}
>+
> void EnhancedPathShape::evaluateHandles()
> {
>     const int handleCount = m_enhancedHandles.count();
>     QList<QPointF> handles;
>     for (int i = 0; i < handleCount; ++i)
>-        handles.append(viewboxToShape(m_enhancedHandles[i]->position()));
>+        handles.append(m_enhancedHandles[i]->position());
>     setHandles(handles);
> }
>
>+QRectF EnhancedPathShape::viewBox() const
>+{
>+    return m_viewBox;
>+}
>+
> qreal EnhancedPathShape::evaluateReference(const QString &reference)
> {
>     if (reference.isEmpty())
>@@ -290,27 +321,6 @@
>         updatePath(size());
> }
>
>-const QRectF & EnhancedPathShape::viewBox() const
>-{
>-    return m_viewBox;
>-}
>-
>-QPointF EnhancedPathShape::shapeToViewbox(const QPointF &point) const
>-{
>-    //NOTE: m_flipMatrix doesn't need to be inverted since when we flip
>twice the efect of the flip is inverted. -    return
>m_viewMatrix.inverted().map( m_flipMatrix.map(point)-m_viewBoxOffset ); -}
>-
>-QPointF EnhancedPathShape::viewboxToShape(const QPointF &point) const
>-{
>-    return m_flipMatrix.map(m_viewMatrix.map(point) + m_viewBoxOffset);
>-}
>-
>-qreal EnhancedPathShape::viewboxToShape(qreal value) const
>-{
>-    return m_flipMatrix.map(m_viewMatrix.map(QPointF(value, value))).x();
>-}
>-
> void EnhancedPathShape::saveOdf(KoShapeSavingContext &context) const
> {
>     if (isParametricShape()) {
>@@ -367,9 +377,6 @@
>                 addModifiers(modifiers);
>             }
>
>-            setMirrorHorizontally( child.attributeNS(KoXmlNS::draw,
>"mirror-horizontal") == "true"); -            setMirrorVertically(
>child.attributeNS(KoXmlNS::draw, "mirror-vertical") == "true"); -
>             KoXmlElement grandChild;
>             forEachElement(grandChild, child) {
>                 if (grandChild.namespaceURI() != KoXmlNS::draw)
>@@ -397,21 +404,22 @@
>             if (!path.isEmpty()) {
>                 parsePathData(path);
>             }
>+
>+            setMirrorHorizontally( child.attributeNS(KoXmlNS::draw,
>"mirror-horizontal") == "true"); +            setMirrorVertically(
>child.attributeNS(KoXmlNS::draw, "mirror-vertical") == "true"); }
>     }
>
>-    QPointF pos;
>-    pos.setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x",
>QString()))); -   
>pos.setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y",
>QString()))); -    setPosition(pos);
>-    normalize();
>-
>     QSizeF size;
>     size.setWidth(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg,
>"width", QString())));
>size.setHeight(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg,
>"height", QString()))); -
>     setSize(size);
>
>+    QPointF pos;
>+    pos.setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x",
>QString()))); +   
>pos.setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y",
>QString()))); +    setPosition(pos);
>+
>     loadOdfAttributes(element, context, OdfMandatories | OdfTransformation
>| OdfAdditionalAttributes | OdfCommonChildElements);
>
>     return true;
>@@ -451,7 +459,6 @@
> {
>     if( m_mirrorHorizontally != mirrorHorizontally) {
>         m_mirrorHorizontally = mirrorHorizontally;
>-//         setMirroring();
>     }
> }
>
>@@ -459,17 +466,5 @@
> {
>     if( m_mirrorVertically != mirrorVertically) {
>         m_mirrorVertically = mirrorVertically;
>-//         setMirroring();
>     }
> }
>-
>-void EnhancedPathShape::setMirroring()
>-{
>-    qreal centerX = size().width() * 0.5;
>-    qreal centerY = size().height() * 0.5;
>-
>-    m_flipMatrix.reset();
>-    m_flipMatrix.translate(centerX, centerY);
>-    m_flipMatrix.scale(m_mirrorHorizontally? -1.0 : 1.0,
>m_mirrorVertically? -1.0 : 1.0); -    m_flipMatrix.translate(-centerX,
>-centerY);
>-}
>--- trunk/koffice/plugins/pathshapes/enhancedpath/EnhancedPathShape.h
>#1101340:1101341 @@ -1,5 +1,5 @@
> /* This file is part of the KDE project
>- * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
>+ * Copyright (C) 2007,2010 Jan Hambrecht <jaham@gmx.net>
>  *
>  * This library is free software; you can redistribute it and/or
>  * modify it under the terms of the GNU Library General Public
>@@ -47,7 +47,7 @@
> {
> public:
>     explicit EnhancedPathShape(const QRectF &viewBox);
>-    ~EnhancedPathShape();
>+    virtual ~EnhancedPathShape();
>
>     /**
>      * Evaluates the given reference to a identifier, modifier or formula.
>@@ -73,17 +73,21 @@
>
>     /// Add formula with given name and textual represenation
>     void addFormula(const QString &name, const QString &formula);
>+
>     /// Add a single handle with format: x y minX maxX minY maxY
>     void addHandle(const QMap<QString,QVariant> &handle);
>+
>     /// Add modifiers with format: modifier0 modifier1 modifier2 ...
>     void addModifiers(const QString &modifiers);
>+
>     /// Add command for instance "M 0 0"
>     void addCommand(const QString &command);
>+
>     /// Returns the viewbox of the enhanced path shape
>-    const QRectF & viewBox() const;
>+    QRectF viewBox() const;
>+
>+    /// Converts from shape coordinates to viewbox coordinates
>     QPointF shapeToViewbox(const QPointF &point) const;
>-    QPointF viewboxToShape(const QPointF &point) const;
>-    qreal viewboxToShape(qreal value) const;
>
>     /// Sets if the shape is to be mirrored horizontally before aplying
>any other transformations //NOTE: in the standard nothing is mentioned
>about the priorities of the transformations" @@ -99,12 +103,14 @@
>     EnhancedPathParameter *parameter(const QString &text);
>
> protected:
>-    void saveOdf(KoShapeSavingContext &context) const;
>+    // from KoShape
>+    virtual void saveOdf(KoShapeSavingContext &context) const;
>+    // from KoShape
>     virtual bool loadOdf(const KoXmlElement &element,
>KoShapeLoadingContext &context); // from KoParameterShape
>-    void moveHandleAction(int handleId, const QPointF &point,
>Qt::KeyboardModifiers modifiers = Qt::NoModifier); +    virtual void
>moveHandleAction(int handleId, const QPointF &point, Qt::KeyboardModifiers
>modifiers = Qt::NoModifier); // from KoParameterShape
>-    void updatePath(const QSizeF &size);
>+    virtual void updatePath(const QSizeF &size);
> private:
>
>     void evaluateHandles();
>@@ -116,15 +122,13 @@
>     /// Adds a new command
>     void addCommand(const QString &command, bool triggerUpdate);
>
>-    void setMirroring();
>-
>     typedef QMap<QString, EnhancedPathFormula*> FormulaStore;
>     typedef QList<qreal> ModifierStore;
>     typedef QMap<QString, EnhancedPathParameter*> ParameterStore;
>
>-    QRectF m_viewBox;
>-    QMatrix m_viewMatrix;
>-    QMatrix m_flipMatrix;
>+    QRectF m_viewBox;     ///< the viewbox rectangle
>+    QRectF m_viewBound;   ///< the bounding box of the path in viewbox
>coordinates +    QMatrix m_viewMatrix; ///< matrix to convert from viewbox
>coordinates to shape coordinates QPointF m_viewBoxOffset;
>     QList<EnhancedPathCommand*> m_commands; ///< the commands creating the
>outline QList<EnhancedPathHandle*> m_enhancedHandles; ///< the handles for
>modifiying the shape
OMG, you did it?!… were the points being mapped twice?!

Carlos Licea


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

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