[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