Subversion Repositories Scribus

Rev

Rev 18114 | Rev 19067 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
11006 fschmid 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
/***************************************************************************
8
*   Copyright (C) 2007 by Franz Schmid                                     *
9
*   franz.schmid@altmuehlnet.de                                            *
10
*                                                                          *
11
*   This program is free software; you can redistribute it and/or modify   *
12
*   it under the terms of the GNU General Public License as published by   *
13
*   the Free Software Foundation; either version 2 of the License, or      *
14
*   (at your option) any later version.                                    *
15
*                                                                          *
16
*   This program is distributed in the hope that it will be useful,        *
17
*   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
18
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
19
*   GNU General Public License for more details.                           *
20
*                                                                          *
21
*   You should have received a copy of the GNU General Public License      *
22
*   along with this program; if not, write to the                          *
23
*   Free Software Foundation, Inc.,                                        *
18122 mrdocs 24
*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.              *
11006 fschmid 25
****************************************************************************/
26
 
17539 jghali 27
#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
14170 jghali 28
#define _USE_MATH_DEFINES
29
#endif
30
#include <cmath>
11006 fschmid 31
#include "pathstroker.h"
12920 fschmid 32
#include "pageitem_polygon.h"
33
#include "commonstrings.h"
11006 fschmid 34
#include "scribuscore.h"
13805 jghali 35
#include "scribusdoc.h"
11027 fschmid 36
#include "scribusstructs.h"
13805 jghali 37
#include "selection.h"
11006 fschmid 38
#include "util.h"
39
#include <QPainterPathStroker>
40
 
41
int pathstroker_getPluginAPIVersion()
42
{
43
        return PLUGIN_API_VERSION;
44
}
45
 
46
ScPlugin* pathstroker_getPlugin()
47
{
48
        PathStrokerPlugin* plug = new PathStrokerPlugin();
49
        Q_CHECK_PTR(plug);
50
        return plug;
51
}
52
 
53
void pathstroker_freePlugin(ScPlugin* plugin)
54
{
55
        PathStrokerPlugin* plug = dynamic_cast<PathStrokerPlugin*>(plugin);
56
        Q_ASSERT(plug);
57
        delete plug;
58
}
59
 
60
PathStrokerPlugin::PathStrokerPlugin() : ScActionPlugin()
61
{
62
        // Set action info in languageChange, so we only have to do
63
        // it in one place.
64
        languageChange();
65
}
66
 
67
PathStrokerPlugin::~PathStrokerPlugin() {};
68
 
69
void PathStrokerPlugin::languageChange()
70
{
71
        // Note that we leave the unused members unset. They'll be initialised
72
        // with their default ctors during construction.
73
        // Action name
74
        m_actionInfo.name = "PathStroker";
75
        // Action text for menu, including accel
76
        m_actionInfo.text = tr("Create Path from Stroke");
77
        // Menu
11037 fschmid 78
        m_actionInfo.menu = "ItemPathOps";
11050 fschmid 79
        m_actionInfo.parentMenu = "Item";
80
        m_actionInfo.subMenuName = tr("Path Tools");
12566 cbradney 81
        m_actionInfo.enabledOnStartup = false;
11006 fschmid 82
        m_actionInfo.notSuitableFor.append(PageItem::Line);
83
        m_actionInfo.notSuitableFor.append(PageItem::TextFrame);
84
        m_actionInfo.notSuitableFor.append(PageItem::ImageFrame);
85
        m_actionInfo.notSuitableFor.append(PageItem::PathText);
86
        m_actionInfo.notSuitableFor.append(PageItem::LatexFrame);
15060 fschmid 87
        m_actionInfo.notSuitableFor.append(PageItem::Symbol);
16191 fschmid 88
        m_actionInfo.notSuitableFor.append(PageItem::RegularPolygon);
16215 fschmid 89
        m_actionInfo.notSuitableFor.append(PageItem::Arc);
16311 fschmid 90
        m_actionInfo.notSuitableFor.append(PageItem::Spiral);
11027 fschmid 91
        m_actionInfo.forAppMode.append(modeNormal);
11006 fschmid 92
        m_actionInfo.needsNumObjects = 1;
93
}
94
 
95
const QString PathStrokerPlugin::fullTrName() const
96
{
11024 fschmid 97
        return QObject::tr("PathStroker");
11006 fschmid 98
}
99
 
100
const ScActionPlugin::AboutData* PathStrokerPlugin::getAboutData() const
101
{
102
        AboutData* about = new AboutData;
103
        Q_CHECK_PTR(about);
104
        about->authors = QString::fromUtf8("Franz Schmid <Franz.Schmid@altmuehlnet.de>");
105
        about->shortDescription = tr("Create Path from Stroke");
11018 fschmid 106
        about->description = tr("Converts the stroke of a Path to a filled Path.");
11006 fschmid 107
        // about->version
108
        // about->releaseDate
109
        // about->copyright
110
        about->license = "GPL";
111
        return about;
112
}
113
 
114
void PathStrokerPlugin::deleteAboutData(const AboutData* about) const
115
{
116
        Q_ASSERT(about);
117
        delete about;
118
}
119
 
120
bool PathStrokerPlugin::run(ScribusDoc* doc, QString)
121
{
122
        ScribusDoc* currDoc = doc;
123
        if (currDoc == 0)
124
                currDoc = ScCore->primaryMainWindow()->doc;
125
        if (currDoc->m_Selection->count() > 0)
126
        {
12055 jghali 127
                QVector<double> m_array;
11006 fschmid 128
                PageItem *currItem = currDoc->m_Selection->itemAt(0);
129
                FPointArray path = currItem->PoLine;
11018 fschmid 130
                QPainterPath pp;
131
                if (currItem->itemType() == PageItem::PolyLine)
132
                        pp = path.toQPainterPath(false);
133
                else
134
                        pp = path.toQPainterPath(true);
12920 fschmid 135
                if (currItem->NamedLStyle.isEmpty())
11006 fschmid 136
                {
12920 fschmid 137
                        QPainterPathStroker stroke;
138
                        stroke.setCapStyle(currItem->lineEnd());
139
                        stroke.setJoinStyle(currItem->lineJoin());
140
                        if (currItem->lineStyle() == Qt::SolidLine)
141
                                stroke.setDashPattern(currItem->lineStyle());
142
                        else
11006 fschmid 143
                        {
12920 fschmid 144
                                getDashArray(currItem->lineStyle(), 1, m_array);
145
                                stroke.setDashPattern(m_array);
146
                        }
147
                        stroke.setWidth(currItem->lineWidth());
16350 fschmid 148
                        QPainterPath result = stroke.createStroke(pp).simplified();
12920 fschmid 149
                        if (currItem->startArrowIndex() != 0)
150
                        {
151
                                FPoint Start = currItem->PoLine.point(0);
18114 jghali 152
                                for (int xx = 1; xx < currItem->PoLine.size(); xx += 2)
11006 fschmid 153
                                {
12920 fschmid 154
                                        FPoint Vector = currItem->PoLine.point(xx);
155
                                        if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
156
                                        {
157
                                                double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
13951 fschmid 158
                                                QTransform arrowTrans;
14969 cbradney 159
                                                FPointArray arrow = currDoc->arrowStyles().at(currItem->startArrowIndex()-1).points.copy();
12920 fschmid 160
                                                arrowTrans.translate(Start.x(), Start.y());
161
                                                arrowTrans.rotate(r);
15345 fschmid 162
                                                arrowTrans.scale(currItem->startArrowScale() / 100.0, currItem->startArrowScale() / 100.0);
12920 fschmid 163
                                                arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
164
                                                arrow.map(arrowTrans);
165
                                                result.addPath(arrow.toQPainterPath(true));
166
                                                break;
167
                                        }
11006 fschmid 168
                                }
169
                        }
12920 fschmid 170
                        if (currItem->endArrowIndex() != 0)
171
                        {
172
                                FPoint End = currItem->PoLine.point(currItem->PoLine.size()-2);
173
                                for (uint xx = currItem->PoLine.size()-1; xx > 0; xx -= 2)
174
                                {
175
                                        FPoint Vector = currItem->PoLine.point(xx);
176
                                        if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
177
                                        {
178
                                                double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
13951 fschmid 179
                                                QTransform arrowTrans;
14969 cbradney 180
                                                FPointArray arrow = currDoc->arrowStyles().at(currItem->endArrowIndex()-1).points.copy();
12920 fschmid 181
                                                arrowTrans.translate(End.x(), End.y());
182
                                                arrowTrans.rotate(r);
15345 fschmid 183
                                                arrowTrans.scale(currItem->endArrowScale() / 100.0, currItem->endArrowScale() / 100.0);
12920 fschmid 184
                                                arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
185
                                                arrow.map(arrowTrans);
186
                                                result.addPath(arrow.toQPainterPath(true));
187
                                                break;
188
                                        }
189
                                }
190
                        }
191
                        currDoc->m_Selection->clear();
192
                        PageItem* newItem = currDoc->convertItemTo(currItem, PageItem::Polygon);
193
                        newItem->setLineWidth(0);
194
                        newItem->setLineStyle(Qt::SolidLine);
195
                        newItem->setFillColor(newItem->lineColor());
196
                        newItem->setFillShade(newItem->lineShade());
197
                        newItem->setFillTransparency(newItem->lineTransparency());
198
                        newItem->setFillBlendmode(newItem->lineBlendmode());
199
                        FPointArray points;
200
                        points.fromQPainterPath(result);
201
                        newItem->PoLine = points;
202
                        newItem->ClipEdited = true;
203
                        newItem->FrameType = 3;
204
                        currDoc->AdjustItemSize(newItem);
205
                        newItem->OldB2 = newItem->width();
206
                        newItem->OldH2 = newItem->height();
207
                        newItem->updateClip();
208
                        newItem->ContourLine = newItem->PoLine.copy();
16338 fschmid 209
                        newItem->setFillEvenOdd(false);
12920 fschmid 210
                        currDoc->m_Selection->addItem(newItem);
11006 fschmid 211
                }
12920 fschmid 212
                else
11006 fschmid 213
                {
12920 fschmid 214
                        currDoc->m_Selection->clear();
215
                        multiLine ml = currDoc->MLineStyles[currItem->NamedLStyle];
216
                        bool first = true;
217
                        for (int it = ml.size()-1; it > -1; it--)
11006 fschmid 218
                        {
12920 fschmid 219
                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
11006 fschmid 220
                                {
12920 fschmid 221
                                        QPainterPathStroker stroke;
222
                                        stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[it].LineEnd));
223
                                        stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[it].LineJoin));
224
                                        if (static_cast<Qt::PenStyle>(ml[it].Dash) == Qt::SolidLine)
225
                                                stroke.setDashPattern(static_cast<Qt::PenStyle>(ml[it].Dash));
226
                                        else
227
                                        {
228
                                                getDashArray(static_cast<Qt::PenStyle>(ml[it].Dash), 1, m_array);
229
                                                stroke.setDashPattern(m_array);
230
                                        }
231
                                        stroke.setWidth(ml[it].Width);
13842 fschmid 232
                                        QPainterPath result = stroke.createStroke(pp).simplified();
12920 fschmid 233
                                        PageItem* newItem;
234
                                        if (first)
235
                                        {
236
                                                newItem = currDoc->convertItemTo(currItem, PageItem::Polygon);
237
                                        }
238
                                        else
239
                                        {
240
                                                newItem = new PageItem_Polygon(*currItem);
12921 fschmid 241
                                                newItem->convertTo(PageItem::Polygon);
12920 fschmid 242
                                                currDoc->Items->append(newItem);
243
                                        }
244
                                        first = false;
245
                                        newItem->setLineStyle(Qt::SolidLine);
246
                                        newItem->setFillColor(ml[it].Color);
247
                                        newItem->setFillShade(ml[it].Shade);
248
                                        newItem->setFillTransparency(newItem->lineTransparency());
249
                                        newItem->setFillBlendmode(newItem->lineBlendmode());
250
                                        newItem->setLineColor(CommonStrings::None);
251
                                        newItem->setCustomLineStyle("");
252
                                        FPointArray points;
253
                                        points.fromQPainterPath(result);
254
                                        newItem->PoLine = points;
255
                                        newItem->ClipEdited = true;
256
                                        newItem->FrameType = 3;
257
                                        currDoc->AdjustItemSize(newItem);
258
                                        newItem->OldB2 = newItem->width();
259
                                        newItem->OldH2 = newItem->height();
260
                                        newItem->updateClip();
261
                                        newItem->ContourLine = newItem->PoLine.copy();
16338 fschmid 262
                                        newItem->setFillEvenOdd(false);
12920 fschmid 263
                                        currDoc->m_Selection->addItem(newItem);
11006 fschmid 264
                                }
265
                        }
12920 fschmid 266
                        if (currItem->startArrowIndex() != 0)
267
                        {
268
                                FPoint Start = currItem->PoLine.point(0);
18114 jghali 269
                                for (int xx = 1; xx < currItem->PoLine.size(); xx += 2)
12920 fschmid 270
                                {
271
                                        FPoint Vector = currItem->PoLine.point(xx);
272
                                        if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
273
                                        {
274
                                                double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
13951 fschmid 275
                                                QTransform arrowTrans;
14969 cbradney 276
                                                FPointArray arrow = currDoc->arrowStyles().at(currItem->startArrowIndex()-1).points.copy();
12920 fschmid 277
                                                arrowTrans.translate(Start.x(), Start.y());
278
                                                arrowTrans.rotate(r);
15345 fschmid 279
                                                arrowTrans.scale(currItem->startArrowScale() / 100.0, currItem->startArrowScale() / 100.0);
12920 fschmid 280
                                                arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
281
                                                arrow.map(arrowTrans);
282
                                                PageItem* newItem = new PageItem_Polygon(*currItem);
283
                                                currDoc->Items->append(newItem);
284
                                                newItem->setLineWidth(0);
285
                                                newItem->setLineStyle(Qt::SolidLine);
286
                                                newItem->setCustomLineStyle("");
287
                                                newItem->setFillColor(newItem->lineColor());
288
                                                newItem->setFillShade(newItem->lineShade());
289
                                                newItem->setFillTransparency(newItem->lineTransparency());
290
                                                newItem->setFillBlendmode(newItem->lineBlendmode());
291
                                                newItem->PoLine = arrow;
292
                                                newItem->ClipEdited = true;
293
                                                newItem->FrameType = 3;
294
                                                currDoc->AdjustItemSize(newItem);
295
                                                newItem->OldB2 = newItem->width();
296
                                                newItem->OldH2 = newItem->height();
297
                                                newItem->updateClip();
298
                                                newItem->ContourLine = newItem->PoLine.copy();
12921 fschmid 299
                                                newItem->setFillEvenOdd(true);
12920 fschmid 300
                                                currDoc->m_Selection->addItem(newItem);
301
                                                break;
302
                                        }
303
                                }
304
                        }
305
                        if (currItem->endArrowIndex() != 0)
306
                        {
307
                                FPoint End = currItem->PoLine.point(currItem->PoLine.size()-2);
308
                                for (uint xx = currItem->PoLine.size()-1; xx > 0; xx -= 2)
309
                                {
310
                                        FPoint Vector = currItem->PoLine.point(xx);
311
                                        if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
312
                                        {
313
                                                double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
13951 fschmid 314
                                                QTransform arrowTrans;
14969 cbradney 315
                                                FPointArray arrow = currDoc->arrowStyles().at(currItem->endArrowIndex()-1).points.copy();
12920 fschmid 316
                                                arrowTrans.translate(End.x(), End.y());
317
                                                arrowTrans.rotate(r);
15345 fschmid 318
                                                arrowTrans.scale(currItem->endArrowScale() / 100.0, currItem->endArrowScale() / 100.0);
12920 fschmid 319
                                                arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
320
                                                arrow.map(arrowTrans);
321
                                                PageItem* newItem = new PageItem_Polygon(*currItem);
322
                                                currDoc->Items->append(newItem);
323
                                                newItem->setLineWidth(0);
324
                                                newItem->setLineStyle(Qt::SolidLine);
325
                                                newItem->setCustomLineStyle("");
326
                                                newItem->setFillColor(newItem->lineColor());
327
                                                newItem->setFillShade(newItem->lineShade());
328
                                                newItem->setFillTransparency(newItem->lineTransparency());
329
                                                newItem->setFillBlendmode(newItem->lineBlendmode());
330
                                                newItem->PoLine = arrow;
331
                                                newItem->ClipEdited = true;
332
                                                newItem->FrameType = 3;
333
                                                currDoc->AdjustItemSize(newItem);
334
                                                newItem->OldB2 = newItem->width();
335
                                                newItem->OldH2 = newItem->height();
336
                                                newItem->updateClip();
337
                                                newItem->ContourLine = newItem->PoLine.copy();
12921 fschmid 338
                                                newItem->setFillEvenOdd(true);
12920 fschmid 339
                                                currDoc->m_Selection->addItem(newItem);
340
                                                break;
341
                                        }
342
                                }
343
                        }
344
                        if (currDoc->m_Selection->count() > 1)
345
                                currDoc->itemSelection_GroupObjects(false, false);
12921 fschmid 346
                        currDoc->m_Selection->itemAt(0)->emitAllToGUI();
11006 fschmid 347
                }
348
                currDoc->changed();
349
        }
350
        return true;
351
}