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.
7
/***************************************************************************
8
* Copyright (C) 2007 by Franz Schmid *
9
* franz.schmid@altmuehlnet.de *
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. *
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. *
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., *
24
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25
****************************************************************************/
27
#include "pathstroker.h"
28
#include "pageitem_polygon.h"
29
#include "commonstrings.h"
30
#include "scribuscore.h"
31
#include "scribusstructs.h"
33
#include "util_math.h"
34
#include <QPainterPathStroker>
36
int pathstroker_getPluginAPIVersion()
38
return PLUGIN_API_VERSION;
41
ScPlugin* pathstroker_getPlugin()
43
PathStrokerPlugin* plug = new PathStrokerPlugin();
48
void pathstroker_freePlugin(ScPlugin* plugin)
50
PathStrokerPlugin* plug = dynamic_cast<PathStrokerPlugin*>(plugin);
55
PathStrokerPlugin::PathStrokerPlugin() : ScActionPlugin()
57
// Set action info in languageChange, so we only have to do
62
PathStrokerPlugin::~PathStrokerPlugin() {};
64
void PathStrokerPlugin::languageChange()
66
// Note that we leave the unused members unset. They'll be initialised
67
// with their default ctors during construction.
69
m_actionInfo.name = "PathStroker";
70
// Action text for menu, including accel
71
m_actionInfo.text = tr("Create Path from Stroke");
73
m_actionInfo.menu = "ItemPathOps";
74
m_actionInfo.parentMenu = "Item";
75
m_actionInfo.subMenuName = tr("Path Tools");
76
m_actionInfo.enabledOnStartup = false;
77
m_actionInfo.notSuitableFor.append(PageItem::Line);
78
m_actionInfo.notSuitableFor.append(PageItem::TextFrame);
79
m_actionInfo.notSuitableFor.append(PageItem::ImageFrame);
80
m_actionInfo.notSuitableFor.append(PageItem::PathText);
81
m_actionInfo.notSuitableFor.append(PageItem::LatexFrame);
82
m_actionInfo.forAppMode.append(modeNormal);
83
m_actionInfo.needsNumObjects = 1;
86
const QString PathStrokerPlugin::fullTrName() const
88
return QObject::tr("PathStroker");
91
const ScActionPlugin::AboutData* PathStrokerPlugin::getAboutData() const
93
AboutData* about = new AboutData;
95
about->authors = QString::fromUtf8("Franz Schmid <Franz.Schmid@altmuehlnet.de>");
96
about->shortDescription = tr("Create Path from Stroke");
97
about->description = tr("Converts the stroke of a Path to a filled Path.");
101
about->license = "GPL";
105
void PathStrokerPlugin::deleteAboutData(const AboutData* about) const
111
bool PathStrokerPlugin::run(ScribusDoc* doc, QString)
113
ScribusDoc* currDoc = doc;
115
currDoc = ScCore->primaryMainWindow()->doc;
116
if (currDoc->m_Selection->count() > 0)
118
QVector<double> m_array;
119
PageItem *currItem = currDoc->m_Selection->itemAt(0);
120
FPointArray path = currItem->PoLine;
122
if (currItem->itemType() == PageItem::PolyLine)
123
pp = path.toQPainterPath(false);
125
pp = path.toQPainterPath(true);
126
if (currItem->NamedLStyle.isEmpty())
128
QPainterPathStroker stroke;
129
stroke.setCapStyle(currItem->lineEnd());
130
stroke.setJoinStyle(currItem->lineJoin());
131
if (currItem->lineStyle() == Qt::SolidLine)
132
stroke.setDashPattern(currItem->lineStyle());
135
getDashArray(currItem->lineStyle(), 1, m_array);
136
stroke.setDashPattern(m_array);
138
stroke.setWidth(currItem->lineWidth());
139
QPainterPath result = stroke.createStroke(pp).simplified();
140
if (currItem->startArrowIndex() != 0)
142
FPoint Start = currItem->PoLine.point(0);
143
for (uint xx = 1; xx < currItem->PoLine.size(); xx += 2)
145
FPoint Vector = currItem->PoLine.point(xx);
146
if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
148
double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
150
FPointArray arrow = currDoc->arrowStyles.at(currItem->startArrowIndex()-1).points.copy();
151
arrowTrans.translate(Start.x(), Start.y());
152
arrowTrans.rotate(r);
153
arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
154
arrow.map(arrowTrans);
155
result.addPath(arrow.toQPainterPath(true));
160
if (currItem->endArrowIndex() != 0)
162
FPoint End = currItem->PoLine.point(currItem->PoLine.size()-2);
163
for (uint xx = currItem->PoLine.size()-1; xx > 0; xx -= 2)
165
FPoint Vector = currItem->PoLine.point(xx);
166
if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
168
double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
170
FPointArray arrow = currDoc->arrowStyles.at(currItem->endArrowIndex()-1).points.copy();
171
arrowTrans.translate(End.x(), End.y());
172
arrowTrans.rotate(r);
173
arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
174
arrow.map(arrowTrans);
175
result.addPath(arrow.toQPainterPath(true));
180
currDoc->m_Selection->clear();
181
PageItem* newItem = currDoc->convertItemTo(currItem, PageItem::Polygon);
182
newItem->setLineWidth(0);
183
newItem->setLineStyle(Qt::SolidLine);
184
newItem->setFillColor(newItem->lineColor());
185
newItem->setFillShade(newItem->lineShade());
186
newItem->setFillTransparency(newItem->lineTransparency());
187
newItem->setFillBlendmode(newItem->lineBlendmode());
189
points.fromQPainterPath(result);
190
newItem->PoLine = points;
191
newItem->Frame = false;
192
newItem->ClipEdited = true;
193
newItem->FrameType = 3;
194
currDoc->AdjustItemSize(newItem);
195
newItem->OldB2 = newItem->width();
196
newItem->OldH2 = newItem->height();
197
newItem->updateClip();
198
newItem->ContourLine = newItem->PoLine.copy();
199
newItem->setFillEvenOdd(true);
200
currDoc->m_Selection->addItem(newItem);
204
currDoc->m_Selection->clear();
205
multiLine ml = currDoc->MLineStyles[currItem->NamedLStyle];
207
for (int it = ml.size()-1; it > -1; it--)
209
if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
211
QPainterPathStroker stroke;
212
stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[it].LineEnd));
213
stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[it].LineJoin));
214
if (static_cast<Qt::PenStyle>(ml[it].Dash) == Qt::SolidLine)
215
stroke.setDashPattern(static_cast<Qt::PenStyle>(ml[it].Dash));
218
getDashArray(static_cast<Qt::PenStyle>(ml[it].Dash), 1, m_array);
219
stroke.setDashPattern(m_array);
221
stroke.setWidth(ml[it].Width);
222
QPainterPath result = stroke.createStroke(pp).simplified();
226
newItem = currDoc->convertItemTo(currItem, PageItem::Polygon);
230
newItem = new PageItem_Polygon(*currItem);
231
newItem->convertTo(PageItem::Polygon);
232
currDoc->Items->append(newItem);
235
newItem->ItemNr = currDoc->Items->count()-1;
236
newItem->setLineStyle(Qt::SolidLine);
237
newItem->setFillColor(ml[it].Color);
238
newItem->setFillShade(ml[it].Shade);
239
newItem->setFillTransparency(newItem->lineTransparency());
240
newItem->setFillBlendmode(newItem->lineBlendmode());
241
newItem->setLineColor(CommonStrings::None);
242
newItem->setCustomLineStyle("");
244
points.fromQPainterPath(result);
245
newItem->PoLine = points;
246
newItem->Frame = false;
247
newItem->ClipEdited = true;
248
newItem->FrameType = 3;
249
currDoc->AdjustItemSize(newItem);
250
newItem->OldB2 = newItem->width();
251
newItem->OldH2 = newItem->height();
252
newItem->updateClip();
253
newItem->ContourLine = newItem->PoLine.copy();
254
newItem->setFillEvenOdd(true);
255
currDoc->m_Selection->addItem(newItem);
258
if (currItem->startArrowIndex() != 0)
260
FPoint Start = currItem->PoLine.point(0);
261
for (uint xx = 1; xx < currItem->PoLine.size(); xx += 2)
263
FPoint Vector = currItem->PoLine.point(xx);
264
if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
266
double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
268
FPointArray arrow = currDoc->arrowStyles.at(currItem->startArrowIndex()-1).points.copy();
269
arrowTrans.translate(Start.x(), Start.y());
270
arrowTrans.rotate(r);
271
arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
272
arrow.map(arrowTrans);
273
PageItem* newItem = new PageItem_Polygon(*currItem);
274
currDoc->Items->append(newItem);
275
newItem->ItemNr = currDoc->Items->count()-1;
276
newItem->setLineWidth(0);
277
newItem->setLineStyle(Qt::SolidLine);
278
newItem->setCustomLineStyle("");
279
newItem->setFillColor(newItem->lineColor());
280
newItem->setFillShade(newItem->lineShade());
281
newItem->setFillTransparency(newItem->lineTransparency());
282
newItem->setFillBlendmode(newItem->lineBlendmode());
283
newItem->PoLine = arrow;
284
newItem->Frame = false;
285
newItem->ClipEdited = true;
286
newItem->FrameType = 3;
287
currDoc->AdjustItemSize(newItem);
288
newItem->OldB2 = newItem->width();
289
newItem->OldH2 = newItem->height();
290
newItem->updateClip();
291
newItem->ContourLine = newItem->PoLine.copy();
292
newItem->setFillEvenOdd(true);
293
currDoc->m_Selection->addItem(newItem);
298
if (currItem->endArrowIndex() != 0)
300
FPoint End = currItem->PoLine.point(currItem->PoLine.size()-2);
301
for (uint xx = currItem->PoLine.size()-1; xx > 0; xx -= 2)
303
FPoint Vector = currItem->PoLine.point(xx);
304
if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
306
double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
308
FPointArray arrow = currDoc->arrowStyles.at(currItem->endArrowIndex()-1).points.copy();
309
arrowTrans.translate(End.x(), End.y());
310
arrowTrans.rotate(r);
311
arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
312
arrow.map(arrowTrans);
313
PageItem* newItem = new PageItem_Polygon(*currItem);
314
currDoc->Items->append(newItem);
315
newItem->ItemNr = currDoc->Items->count()-1;
316
newItem->setLineWidth(0);
317
newItem->setLineStyle(Qt::SolidLine);
318
newItem->setCustomLineStyle("");
319
newItem->setFillColor(newItem->lineColor());
320
newItem->setFillShade(newItem->lineShade());
321
newItem->setFillTransparency(newItem->lineTransparency());
322
newItem->setFillBlendmode(newItem->lineBlendmode());
323
newItem->PoLine = arrow;
324
newItem->Frame = false;
325
newItem->ClipEdited = true;
326
newItem->FrameType = 3;
327
currDoc->AdjustItemSize(newItem);
328
newItem->OldB2 = newItem->width();
329
newItem->OldH2 = newItem->height();
330
newItem->updateClip();
331
newItem->ContourLine = newItem->PoLine.copy();
332
newItem->setFillEvenOdd(true);
333
currDoc->m_Selection->addItem(newItem);
338
if (currDoc->m_Selection->count() > 1)
339
currDoc->itemSelection_GroupObjects(false, false);
340
currDoc->m_Selection->itemAt(0)->emitAllToGUI();