1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "paintcommands.h"
42 
43 #include <qdir.h>
44 #include <qfile.h>
45 #include <qfileinfo.h>
46 #include <qpainter.h>
47 #include <qbitmap.h>
48 #include <qtextstream.h>
49 #include <qtextlayout.h>
50 #include <qdebug.h>
51 #include <QStaticText>
52 
53 #ifdef QT3_SUPPORT
54 #include <q3painter.h>
55 #endif
56 
57 #ifndef QT_NO_OPENGL
58 #include <qglpixelbuffer.h>
59 #endif
60 
61 /*********************************************************************************
62 ** everything to populate static tables
63 **********************************************************************************/
64 const char *PaintCommands::brushStyleTable[] = {
65     "NoBrush",
66     "SolidPattern",
67     "Dense1Pattern",
68     "Dense2Pattern",
69     "Dense3Pattern",
70     "Dense4Pattern",
71     "Dense5Pattern",
72     "Dense6Pattern",
73     "Dense7Pattern",
74     "HorPattern",
75     "VerPattern",
76     "CrossPattern",
77     "BDiagPattern",
78     "FDiagPattern",
79     "DiagCrossPattern",
80     "LinearGradientPattern"
81 };
82 
83 const char *PaintCommands::penStyleTable[] = {
84     "NoPen",
85     "SolidLine",
86     "DashLine",
87     "DotLine",
88     "DashDotLine",
89     "DashDotDotLine"
90 };
91 
92 const char *PaintCommands::fontWeightTable[] = {
93     "Light",
94     "Normal",
95     "DemiBold",
96     "Bold",
97     "Black"
98 };
99 
100 const char *PaintCommands::fontHintingTable[] = {
101     "Default",
102     "None",
103     "Vertical",
104     "Full"
105 };
106 
107 const char *PaintCommands::clipOperationTable[] = {
108     "NoClip",
109     "ReplaceClip",
110     "IntersectClip",
111     "UniteClip"
112 };
113 
114 const char *PaintCommands::spreadMethodTable[] = {
115     "PadSpread",
116     "ReflectSpread",
117     "RepeatSpread"
118 };
119 
120 const char *PaintCommands::coordinateMethodTable[] = {
121     "LogicalMode",
122     "StretchToDeviceMode",
123     "ObjectBoundingMode"
124 };
125 
126 const char *PaintCommands::sizeModeTable[] = {
127     "AbsoluteSize",
128     "RelativeSize"
129 };
130 
131 const char *PaintCommands::compositionModeTable[] = {
132     "SourceOver",
133     "DestinationOver",
134     "Clear",
135     "Source",
136     "Destination",
137     "SourceIn",
138     "DestinationIn",
139     "SourceOut",
140     "DestinationOut",
141     "SourceAtop",
142     "DestinationAtop",
143     "Xor",
144     "Plus",
145     "Multiply",
146     "Screen",
147     "Overlay",
148     "Darken",
149     "Lighten",
150     "ColorDodge",
151     "ColorBurn",
152     "HardLight",
153     "SoftLight",
154     "Difference",
155     "Exclusion",
156     "SourceOrDestination",
157     "SourceAndDestination",
158     "SourceXorDestination",
159     "NotSourceAndNotDestination",
160     "NotSourceOrNotDestination",
161     "NotSourceXorDestination",
162     "NotSource",
163     "NotSourceAndDestination",
164     "SourceAndNotDestination"
165 };
166 
167 const char *PaintCommands::imageFormatTable[] = {
168     "Invalid",
169     "Mono",
170     "MonoLSB",
171     "Indexed8",
172     "RGB32",
173     "ARGB32",
174     "ARGB32_Premultiplied",
175     "Format_RGB16",
176     "Format_ARGB8565_Premultiplied",
177     "Format_RGB666",
178     "Format_ARGB6666_Premultiplied",
179     "Format_RGB555",
180     "Format_ARGB8555_Premultiplied",
181     "Format_RGB888",
182     "Format_RGB444",
183     "Format_ARGB4444_Premultiplied"
184 };
185 
translateEnum(const char * table[],const QString & pattern,int limit)186 int PaintCommands::translateEnum(const char *table[], const QString &pattern, int limit)
187 {
188     QByteArray p = pattern.toLatin1().toLower();
189     for (int i=0; i<limit; ++i)
190         if (p == QByteArray::fromRawData(table[i], qstrlen(table[i])).toLower())
191             return i;
192     return -1;
193 }
194 
195 QList<PaintCommands::PaintCommandInfos> PaintCommands::s_commandInfoTable = QList<PaintCommands::PaintCommandInfos>();
196 QList<QPair<QString,QStringList> > PaintCommands::s_enumsTable = QList<QPair<QString,QStringList> >();
197 QMultiHash<QString, int> PaintCommands::s_commandHash;
198 
199 #define DECL_PAINTCOMMAND(identifier, method, regexp, syntax, sample) \
200     s_commandInfoTable << PaintCommandInfos(QLatin1String(identifier), &PaintCommands::method, QRegExp(regexp), \
201                                             QLatin1String(syntax), QLatin1String(sample) );
202 
203 #define DECL_PAINTCOMMANDSECTION(title) \
204     s_commandInfoTable << PaintCommandInfos(QLatin1String(title));
205 
206 #define ADD_ENUMLIST(listCaption, cStrArray) { \
207         QStringList list; \
208         for (int i=0; i<int(sizeof(cStrArray)/sizeof(char*)); i++)      \
209         list << cStrArray[i]; \
210         s_enumsTable << qMakePair(QString(listCaption), list); \
211     }
212 
staticInit()213 void PaintCommands::staticInit()
214 {
215     // check if already done
216     if (!s_commandInfoTable.isEmpty()) return;
217 
218     // populate the command list
219     DECL_PAINTCOMMANDSECTION("misc");
220     DECL_PAINTCOMMAND("comment", command_comment,
221                       "^\\s*#",
222                       "# this is some comments",
223                       "# place your comments here");
224     DECL_PAINTCOMMAND("import", command_import,
225                       "^import\\s+\"(.*)\"$",
226                       "import <qrcFilename>",
227                       "import \"myfile.qrc\"");
228     DECL_PAINTCOMMAND("begin_block", command_begin_block,
229                       "^begin_block\\s+(\\w*)$",
230                       "begin_block <blockName>",
231                       "begin_block blockName");
232     DECL_PAINTCOMMAND("end_block", command_end_block,
233                       "^end_block$",
234                       "end_block",
235                       "end_block");
236     DECL_PAINTCOMMAND("repeat_block", command_repeat_block,
237                       "^repeat_block\\s+(\\w*)$",
238                       "repeat_block <blockName>",
239                       "repeat_block blockName");
240     DECL_PAINTCOMMAND("textlayout_draw", command_textlayout_draw,
241                       "^textlayout_draw\\s+\"(.*)\"\\s+([0-9.]*)$",
242                       "textlayout_draw <text> <width>",
243                       "textlayout_draw \"your text\" 1.0");
244     DECL_PAINTCOMMAND("abort", command_abort,
245                       "^abort$",
246                       "abort",
247                       "abort");
248     DECL_PAINTCOMMAND("noop", command_noop,
249                       "^$",
250                       "-",
251                       "\n");
252 
253     DECL_PAINTCOMMANDSECTION("setters");
254     DECL_PAINTCOMMAND("setBackgroundMode", command_setBgMode,
255                       "^(setBackgroundMode|setBgMode)\\s+(\\w*)$",
256                       "setBackgroundMode <OpaqueMode|TransparentMode>",
257                       "setBackgroundMode TransparentMode");
258     DECL_PAINTCOMMAND("setBackground", command_setBackground,
259                       "^setBackground\\s+#?(\\w*)\\s*(\\w*)?$",
260                       "setBackground <color> [brush style enum]",
261                       "setBackground black SolidPattern");
262     DECL_PAINTCOMMAND("setOpacity", command_setOpacity,
263                       "^setOpacity\\s+(-?\\d*\\.?\\d*)$",
264                       "setOpacity <opacity>\n  - opacity is in [0,1]",
265                       "setOpacity 1.0");
266     DECL_PAINTCOMMAND("path_setFillRule", command_path_setFillRule,
267                       "^path_setFillRule\\s+(\\w*)\\s+(\\w*)$",
268                       "path_setFillRule <pathName> [Winding|OddEven]",
269                       "path_setFillRule pathName Winding");
270     DECL_PAINTCOMMAND("setBrush", command_setBrush,
271                       "^setBrush\\s+(#?[\\w.:\\/]*)\\s*(\\w*)?$",
272                       "setBrush <pixmapFileName>\nsetBrush noBrush\nsetBrush <color> <brush style enum>",
273                       "setBrush white SolidPattern");
274     DECL_PAINTCOMMAND("setBrushOrigin", command_setBrushOrigin,
275                       "^setBrushOrigin\\s*(-?\\w*)\\s+(-?\\w*)$",
276                       "setBrushOrigin <dx> <dy>",
277                       "setBrushOrigin 0 0");
278     DECL_PAINTCOMMAND("brushTranslate", command_brushTranslate,
279                       "^brushTranslate\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
280                       "brushTranslate <tx> <ty>",
281                       "brushTranslate 0.0 0.0");
282     DECL_PAINTCOMMAND("brushScale", command_brushScale,
283                       "^brushScale\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
284                       "brushScale <kx> <ky>",
285                       "brushScale 0.0 0.0");
286     DECL_PAINTCOMMAND("brushRotate", command_brushRotate,
287                       "^brushRotate\\s+(-?[\\w.]*)$",
288                       "brushRotate <angle>\n - angle in degrees",
289                       "brushRotate 0.0");
290     DECL_PAINTCOMMAND("brushShear", command_brushShear,
291                       "^brushShear\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
292                       "brushShear <sx> <sy>",
293                       "brushShear 0.0 0.0");
294     DECL_PAINTCOMMAND("setCompositionMode", command_setCompositionMode,
295                       "^setCompositionMode\\s+([\\w_0-9]*)$",
296                       "setCompositionMode <composition mode enum>",
297                       "setCompositionMode SourceOver");
298     DECL_PAINTCOMMAND("setFont", command_setFont,
299                       "^setFont\\s+\"([\\w\\s]*)\"\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)$",
300                       "setFont <fontFace> [size] [font weight|font weight enum] [italic] [hinting enum]\n  - font weight is an integer between 0 and 99",
301                       "setFont \"times\" 12");
302     DECL_PAINTCOMMAND("setPen", command_setPen,
303                       "^setPen\\s+#?(\\w*)$",
304                       "setPen <color>\nsetPen <pen style enum>\nsetPen brush",
305                       "setPen black");
306     DECL_PAINTCOMMAND("setPen", command_setPen2,
307                       "^setPen\\s+(#?\\w*)\\s+([\\w.]+)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)$",
308                       "setPen brush|<color> [width] [pen style enum] [FlatCap|SquareCap|RoundCap] [MiterJoin|BevelJoin|RoundJoin]",
309                       "setPen black 1 FlatCap MiterJoin");
310     DECL_PAINTCOMMAND("pen_setDashOffset", command_pen_setDashOffset,
311                       "^pen_setDashOffset\\s+(-?[\\w.]+)$",
312                       "pen_setDashOffset <offset>\n",
313                       "pen_setDashOffset 1.0");
314     DECL_PAINTCOMMAND("pen_setDashPattern", command_pen_setDashPattern,
315                       "^pen_setDashPattern\\s+\\[([\\w\\s.]*)\\]$",
316                       "pen_setDashPattern <[ <dash_1> <space_1> ... <dash_n> <space_n> ]>",
317                       "pen_setDashPattern [ 2 1 4 1 3 3 ]");
318     DECL_PAINTCOMMAND("pen_setCosmetic", command_pen_setCosmetic,
319                       "^pen_setCosmetic\\s+(\\w*)$",
320                       "pen_setCosmetic <true|false>",
321                       "pen_setCosmetic true");
322     DECL_PAINTCOMMAND("setRenderHint", command_setRenderHint,
323                       "^setRenderHint\\s+([\\w_0-9]*)\\s*(\\w*)$",
324                       "setRenderHint <Antialiasing|SmoothPixmapTransform> <true|false>",
325                       "setRenderHint Antialiasing true");
326     DECL_PAINTCOMMAND("clearRenderHint", command_clearRenderHint,
327                       "^clearRenderHint$",
328                       "clearRenderHint",
329                       "clearRenderHint");
330 
331     DECL_PAINTCOMMANDSECTION("gradients");
332     DECL_PAINTCOMMAND("gradient_appendStop", command_gradient_appendStop,
333                       "^gradient_appendStop\\s+([\\w.]*)\\s+#?(\\w*)$",
334                       "gradient_appendStop <pos> <color>",
335                       "gradient_appendStop 1.0 red");
336     DECL_PAINTCOMMAND("gradient_clearStops", command_gradient_clearStops,
337                       "^gradient_clearStops$",
338                       "gradient_clearStops",
339                       "gradient_clearStops");
340     DECL_PAINTCOMMAND("gradient_setConical", command_gradient_setConical,
341                       "^gradient_setConical\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$",
342                       "gradient_setConical <cx> <cy> <angle>\n  - angle in degrees",
343                       "gradient_setConical 5.0 5.0 45.0");
344     DECL_PAINTCOMMAND("gradient_setLinear", command_gradient_setLinear,
345                       "^gradient_setLinear\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$",
346                       "gradient_setLinear <x1> <y1> <x2> <y2>",
347                       "gradient_setLinear 1.0 1.0 2.0 2.0");
348     DECL_PAINTCOMMAND("gradient_setRadial", command_gradient_setRadial,
349                       "^gradient_setRadial\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$",
350                       "gradient_setRadial <cx> <cy> <rad> <fx> <fy>\n  - C is the center\n  - rad is the radius\n  - F is the focal point",
351                       "gradient_setRadial 1.0 1.0 45.0 2.0 2.0");
352     DECL_PAINTCOMMAND("gradient_setRadialExtended", command_gradient_setRadialExtended,
353                       "^gradient_setRadialExtended\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$",
354                       "gradient_setRadialExtended <cx> <cy> <rad> <fx> <fy> <frad>\n  - C is the center\n  - rad is the center radius\n  - F is the focal point\n  - frad is the focal radius",
355                       "gradient_setRadialExtended 1.0 1.0 45.0 2.0 2.0 45.0");
356     DECL_PAINTCOMMAND("gradient_setLinearPen", command_gradient_setLinearPen,
357                       "^gradient_setLinearPen\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$",
358                       "gradient_setLinearPen <x1> <y1> <x2> <y2>",
359                       "gradient_setLinearPen 1.0 1.0 2.0 2.0");
360     DECL_PAINTCOMMAND("gradient_setSpread", command_gradient_setSpread,
361                       "^gradient_setSpread\\s+(\\w*)$",
362                       "gradient_setSpread <spread method enum>",
363                       "gradient_setSpread PadSpread");
364     DECL_PAINTCOMMAND("gradient_setCoordinateMode", command_gradient_setCoordinateMode,
365                       "^gradient_setCoordinateMode\\s+(\\w*)$",
366                       "gradient_setCoordinateMode <coordinate method enum>",
367                       "gradient_setCoordinateMode ObjectBoundingMode");
368 #ifdef QT3_SUPPORT
369     DECL_PAINTCOMMANDSECTION("qt3 drawing ops");
370     DECL_PAINTCOMMAND("qt3_drawArc", command_qt3_drawArc,
371                       "^qt3_drawArc\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
372                       "qt3_drawArc <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in 1/16th of degree",
373                       "qt3_drawArc 10 10 20 20 0 5760");
374     DECL_PAINTCOMMAND("qt3_drawChord", command_qt3_drawChord,
375                       "^qt3_drawChord\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
376                       "qt3_drawChord <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in 1/16th of degree",
377                       "qt3_drawChord 10 10 20 20 0 5760");
378     DECL_PAINTCOMMAND("qt3_drawEllipse", command_qt3_drawEllipse,
379                       "^qt3_drawEllipse\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
380                       "qt3_drawEllipse <x> <y> <w> <h>",
381                       "qt3_drawEllipse 10 10 20 20");
382     DECL_PAINTCOMMAND("qt3_drawPie", command_qt3_drawPie,
383                       "^qt3_drawPie\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
384                       "qt3_drawPie <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in 1/16th of degree",
385                       "qt3_drawPie 10 10 20 20 0 5760");
386     DECL_PAINTCOMMAND("qt3_drawRect", command_qt3_drawRect,
387                       "^qt3_drawRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
388                       "qt3_drawRect <x> <y> <w> <h>",
389                       "qt3_drawRect 10 10 20 20");
390     DECL_PAINTCOMMAND("qt3_drawRoundRect", command_qt3_drawRoundRect,
391                       "^qt3_drawRoundRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(-?\\w)?\\s*(-?\\w)?$",
392                       "qt3_drawRoundRect <x> <y> <w> <h> [rx] [ry]",
393                       "qt3_drawRoundRect 10 10 20 20 3 3");
394 #endif
395     DECL_PAINTCOMMANDSECTION("drawing ops");
396     DECL_PAINTCOMMAND("drawPoint", command_drawPoint,
397                       "^drawPoint\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
398                       "drawPoint <x> <y>",
399                       "drawPoint 10.0 10.0");
400     DECL_PAINTCOMMAND("drawLine", command_drawLine,
401                       "^drawLine\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
402                       "drawLine <x1> <y1> <x2> <y2>",
403                       "drawLine 10.0 10.0 20.0 20.0");
404     DECL_PAINTCOMMAND("drawRect", command_drawRect,
405                       "^drawRect\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
406                       "drawRect <x> <y> <w> <h>",
407                       "drawRect 10.0 10.0 20.0 20.0");
408     DECL_PAINTCOMMAND("drawRoundRect", command_drawRoundRect,
409                       "^drawRoundRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(-?\\w*)?\\s*(-?\\w*)?$",
410                       "drawRoundRect <x> <y> <w> <h> [rx] [ry]",
411                       "drawRoundRect 10 10 20 20 3 3");
412     DECL_PAINTCOMMAND("drawRoundedRect", command_drawRoundedRect,
413                       "^drawRoundedRect\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s*(\\w*)?$",
414                       "drawRoundedRect <x> <y> <w> <h> <rx> <ry> [SizeMode enum]",
415                       "drawRoundedRect 10 10 20 20 4 4 AbsoluteSize");
416     DECL_PAINTCOMMAND("drawArc", command_drawArc,
417                       "^drawArc\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
418                       "drawArc <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in 1/16th of degree",
419                       "drawArc 10 10 20 20 0 5760");
420     DECL_PAINTCOMMAND("drawChord", command_drawChord,
421                       "^drawChord\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
422                       "drawChord <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in 1/16th of degree",
423                       "drawChord 10 10 20 20 0 5760");
424     DECL_PAINTCOMMAND("drawEllipse", command_drawEllipse,
425                       "^drawEllipse\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
426                       "drawEllipse <x> <y> <w> <h>",
427                       "drawEllipse 10.0 10.0 20.0 20.0");
428     DECL_PAINTCOMMAND("drawPath", command_drawPath,
429                       "^drawPath\\s+(\\w*)$",
430                       "drawPath <pathName>",
431                       "drawPath mypath");
432     DECL_PAINTCOMMAND("drawPie", command_drawPie,
433                       "^drawPie\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
434                       "drawPie <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in 1/16th of degree",
435                       "drawPie 10 10 20 20 0 5760");
436     DECL_PAINTCOMMAND("drawPixmap", command_drawPixmap,
437                       "^drawPixmap\\s+([\\w.:\\-/]*)"
438                       "\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?"    // target rect
439                       "\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?$", // source rect
440                       "drawPixmap <filename> <tx> <ty> <tw> <th> <sx> <sy> <sw> <sh>"
441                       "\n- where t means target and s means source"
442                       "\n- a width or height of -1 means maximum space",
443                       "drawPixmap :/images/face.png 0 0 -1 -1 0 0 -1 -1");
444     DECL_PAINTCOMMAND("drawImage", command_drawImage,
445                       "^drawImage\\s+([\\w.:\\/]*)"
446                       "\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?"    // target rect
447                       "\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?$", // source rect
448                       "drawImage <filename> <tx> <ty> <tw> <th> <sx> <sy> <sw> <sh>"
449                       "\n- where t means target and s means source"
450                       "\n- a width or height of -1 means maximum space",
451                       "drawImage :/images/face.png 0 0 -1 -1 0 0 -1 -1");
452     DECL_PAINTCOMMAND("drawPolygon", command_drawPolygon,
453                       "^drawPolygon\\s+\\[([\\w\\s-.]*)\\]\\s*(\\w*)$",
454                       "drawPolygon <[ <x1> <y1> ... <xn> <yn> ]> <Winding|OddEven>",
455                       "drawPolygon [ 1 4  6 8  5 3 ] Winding");
456     DECL_PAINTCOMMAND("drawConvexPolygon", command_drawConvexPolygon,
457                       "^drawConvexPolygon\\s+\\[([\\w\\s-.]*)\\]$",
458                       "drawConvexPolygon <[ <x1> <y1> ... <xn> <yn> ]>",
459                       "drawConvexPolygon [ 1 4  6 8  5 3 ]");
460     DECL_PAINTCOMMAND("drawPolyline", command_drawPolyline,
461                       "^drawPolyline\\s+\\[([\\w\\s]*)\\]$",
462                       "drawPolyline <[ <x1> <y1> ... <xn> <yn> ]>",
463                       "drawPolyline [ 1 4  6 8  5 3 ]");
464     DECL_PAINTCOMMAND("drawText", command_drawText,
465                       "^drawText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$",
466                       "drawText <x> <y> <text>",
467                       "drawText 10 10 \"my text\"");
468     DECL_PAINTCOMMAND("drawStaticText", command_drawStaticText,
469                       "^drawStaticText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$",
470                       "drawStaticText <x> <y> <text>",
471                       "drawStaticText 10 10 \"my text\"");
472     DECL_PAINTCOMMAND("drawTiledPixmap", command_drawTiledPixmap,
473                       "^drawTiledPixmap\\s+([\\w.:\\/]*)"
474                       "\\s+(-?\\w*)\\s+(-?\\w*)\\s*(-?\\w*)\\s*(-?\\w*)"
475                       "\\s*(-?\\w*)\\s*(-?\\w*)$",
476                       "drawTiledPixmap <tile image filename> <tx> <ty> <tx> <ty> <sx> <sy>"
477                       "\n  - where t means tile"
478                       "\n  - and s is an offset in the tile",
479                       "drawTiledPixmap :/images/alpha.png ");
480 
481     DECL_PAINTCOMMANDSECTION("painterPaths");
482     DECL_PAINTCOMMAND("path_moveTo", command_path_moveTo,
483                       "^path_moveTo\\s+([.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
484                       "path_moveTo <pathName> <x> <y>",
485                       "path_moveTo mypath 1.0 1.0");
486     DECL_PAINTCOMMAND("path_lineTo", command_path_lineTo,
487                       "^path_lineTo\\s+([.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
488                       "path_lineTo <pathName> <x> <y>",
489                       "path_lineTo mypath 1.0 1.0");
490     DECL_PAINTCOMMAND("path_addEllipse", command_path_addEllipse,
491                       "^path_addEllipse\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
492                       "path_addEllipse <pathName> <x1> <y1> <x2> <y2>",
493                       "path_addEllipse mypath 10.0 10.0 20.0 20.0");
494     DECL_PAINTCOMMAND("path_addPolygon", command_path_addPolygon,
495                       "^path_addPolygon\\s+(\\w*)\\s+\\[([\\w\\s]*)\\]\\s*(\\w*)$",
496                       "path_addPolygon <pathName> <[ <x1> <y1> ... <xn> <yn> ]>",
497                       "path_addPolygon mypath [ 1 4  6 8  5 3 ]");
498     DECL_PAINTCOMMAND("path_addRect", command_path_addRect,
499                       "^path_addRect\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
500                       "path_addRect <pathName> <x1> <y1> <x2> <y2>",
501                       "path_addRect mypath 10.0 10.0 20.0 20.0");
502     DECL_PAINTCOMMAND("path_addText", command_path_addText,
503                       "^path_addText\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+\"(.*)\"$",
504                       "path_addText <pathName> <x> <y> <text>",
505                       "path_addText mypath 10.0 20.0 \"some text\"");
506     DECL_PAINTCOMMAND("path_arcTo", command_path_arcTo,
507                       "^path_arcTo\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
508                       "path_arcTo <pathName> <x> <y> <w> <h> <angleStart> <angleArc>\n  - angles are expressed in degrees",
509                       "path_arcTo mypath 0.0 0.0 10.0 10.0 0.0 360.0");
510     DECL_PAINTCOMMAND("path_cubicTo", command_path_cubicTo,
511                       "^path_cubicTo\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
512                       "path_cubicTo <pathName> <x1> <y1> <x2> <y2> <x3> <y3>",
513                       "path_cubicTo mypath 0.0 0.0 10.0 10.0 20.0 20.0");
514     DECL_PAINTCOMMAND("path_closeSubpath", command_path_closeSubpath,
515                       "^path_closeSubpath\\s+(\\w*)$",
516                       "path_closeSubpath <pathName>",
517                       "path_closeSubpath mypath");
518     DECL_PAINTCOMMAND("path_createOutline", command_path_createOutline,
519                       "^path_createOutline\\s+(\\w*)\\s+(\\w*)$",
520                       "path_createOutline <pathName> <newName>",
521                       "path_createOutline mypath myoutline");
522     DECL_PAINTCOMMAND("path_debugPrint", command_path_debugPrint,
523                       "^path_debugPrint\\s+(\\w*)$",
524                       "path_debugPrint <pathName>",
525                       "path_debugPrint mypath");
526 
527     DECL_PAINTCOMMANDSECTION("regions");
528     DECL_PAINTCOMMAND("region_addRect", command_region_addRect,
529                       "^region_addRect\\s+(\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
530                       "region_addRect <regionName> <x1> <y1> <x2> <y2>",
531                       "region_addRect myregion 0.0 0.0 10.0 10.0");
532     DECL_PAINTCOMMAND("region_addEllipse", command_region_addEllipse,
533                       "^region_addEllipse\\s+(\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
534                       "region_addEllipse <regionName> <x1> <y1> <x2> <y2>",
535                       "region_addEllipse myregion 0.0 0.0 10.0 10.0");
536 
537     DECL_PAINTCOMMANDSECTION("clipping");
538     DECL_PAINTCOMMAND("region_getClipRegion", command_region_getClipRegion,
539                       "^region_getClipRegion\\s+(\\w*)$",
540                       "region_getClipRegion <regionName>",
541                       "region_getClipRegion myregion");
542     DECL_PAINTCOMMAND("setClipRegion", command_setClipRegion,
543                       "^setClipRegion\\s+(\\w*)\\s*(\\w*)$",
544                       "setClipRegion <regionName> <clip operation enum>",
545                       "setClipRegion myregion ReplaceClip");
546     DECL_PAINTCOMMAND("path_getClipPath", command_path_getClipPath,
547                       "^path_getClipPath\\s+([\\w0-9]*)$",
548                       "path_getClipPath <pathName>",
549                       "path_getClipPath mypath");
550     DECL_PAINTCOMMAND("setClipPath", command_setClipPath,
551                       "^setClipPath\\s+(\\w*)\\s*(\\w*)$",
552                       "setClipPath <pathName> <clip operation enum>",
553                       "setClipPath mypath ReplaceClip");
554     DECL_PAINTCOMMAND("setClipRect", command_setClipRect,
555                       "^setClipRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(\\w*)$",
556                       "setClipRect <x1> <y1> <x2> <y2> <clip operation enum>",
557                       "setClipRect 0.0 0.0 10.0 10.0 ReplaceClip");
558     DECL_PAINTCOMMAND("setClipping", command_setClipping,
559                       "^setClipping\\s+(\\w*)$",
560                       "setClipping <true|false>",
561                       "setClipping true");
562 
563     DECL_PAINTCOMMANDSECTION("surface");
564     DECL_PAINTCOMMAND("surface_begin", command_surface_begin,
565                       "^surface_begin\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
566                       "surface_begin <x> <y> <w> <h>",
567                       "surface_begin 0.0 0.0 10.0 10.0");
568     DECL_PAINTCOMMAND("surface_end", command_surface_end,
569                       "^surface_end$",
570                       "surface_end",
571                       "surface_end");
572 
573     DECL_PAINTCOMMANDSECTION("painter states");
574     DECL_PAINTCOMMAND("restore", command_restore,
575                       "^restore$",
576                       "restore",
577                       "restore");
578     DECL_PAINTCOMMAND("save", command_save,
579                       "^save$",
580                       "save",
581                       "save");
582 
583     DECL_PAINTCOMMANDSECTION("pixmaps'n'images");
584     DECL_PAINTCOMMAND("pixmap_load", command_pixmap_load,
585                       "^pixmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
586                       "pixmap_load <image filename> <pixmapName>",
587                       "pixmap_load :/images/face.png myPixmap");
588     DECL_PAINTCOMMAND("pixmap_setMask", command_pixmap_setMask,
589                       "^pixmap_setMask\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]*)$",
590                       "pixmap_setMask <pixmapName> <bitmap filename>",
591                       "pixmap_setMask myPixmap :/images/bitmap.png");
592     DECL_PAINTCOMMAND("bitmap_load", command_bitmap_load,
593                       "^bitmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
594                       "bitmap_load <bitmap filename> <bitmapName>\n  - note that the image is stored as a pixmap",
595                       "bitmap_load :/images/bitmap.png myBitmap");
596     DECL_PAINTCOMMAND("image_convertToFormat", command_image_convertToFormat,
597                       "^image_convertToFormat\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]+)\\s+([\\w0-9_]*)$",
598                       "image_convertToFormat <sourceImageName> <destImageName> <image format enum>",
599                       "image_convertToFormat myImage myNewImage Indexed8");
600     DECL_PAINTCOMMAND("image_load", command_image_load,
601                       "^image_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
602                       "image_load <filename> <imageName>",
603                       "image_load :/images/face.png myImage");
604     DECL_PAINTCOMMAND("image_setColor", command_image_setColor,
605                       "^image_setColor\\s+([\\w.:\\/]*)\\s+([0-9]*)\\s+#([0-9]*)$",
606                       "image_setColor <imageName> <index> <color>",
607                       "image_setColor myImage 0 black");
608     DECL_PAINTCOMMAND("image_setColorCount", command_image_setColorCount,
609                       "^image_setColorCount\\s+([\\w.:\\/]*)\\s+([0-9]*)$",
610                       "image_setColorCount <imageName> <nbColors>",
611                       "image_setColorCount myImage 128");
612 
613     DECL_PAINTCOMMANDSECTION("transformations");
614     DECL_PAINTCOMMAND("resetMatrix", command_resetMatrix,
615                       "^resetMatrix$",
616                       "resetMatrix",
617                       "resetMatrix");
618     DECL_PAINTCOMMAND("setMatrix", command_setMatrix,
619                       "^setMatrix\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
620                       "setMatrix <m11> <m12> <m13> <m21> <m22> <m23> <m31> <m32> <m33>",
621                       "setMatrix 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0");
622     DECL_PAINTCOMMAND("translate", command_translate,
623                       "^translate\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
624                       "translate <tx> <ty>",
625                       "translate 10.0 10.0");
626     DECL_PAINTCOMMAND("rotate", command_rotate,
627                       "^rotate\\s+(-?[\\w.]*)$",
628                       "rotate <angle>\n  - with angle in degrees",
629                       "rotate 30.0");
630     DECL_PAINTCOMMAND("rotate_x", command_rotate_x,
631                       "^rotate_x\\s+(-?[\\w.]*)$",
632                       "rotate_x <angle>\n  - with angle in degrees",
633                       "rotate_x 30.0");
634     DECL_PAINTCOMMAND("rotate_y", command_rotate_y,
635                       "^rotate_y\\s+(-?[\\w.]*)$",
636                       "rotate_y <angle>\n  - with angle in degrees",
637                       "rotate_y 30.0");
638     DECL_PAINTCOMMAND("scale", command_scale,
639                       "^scale\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
640                       "scale <sx> <sy>",
641                       "scale 2.0 1.0");
642     DECL_PAINTCOMMAND("mapQuadToQuad", command_mapQuadToQuad,
643                       "^mapQuadToQuad\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
644                       "mapQuadToQuad <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4> <x5> <y5> <x6> <y6> <x7> <y7> <x8> <y8>"
645                       "\n  - where vertices 1 to 4 defines the source quad and 5 to 8 the destination quad",
646                       "mapQuadToQuad 0.0 0.0 1.0 1.0 0.0 0.0 -1.0 -1.0");
647 
648     // populate the command lookup hash
649     for (int i=0; i<s_commandInfoTable.size(); i++) {
650         if (s_commandInfoTable.at(i).isSectionHeader() ||
651             s_commandInfoTable.at(i).identifier == QLatin1String("comment") ||
652             s_commandInfoTable.at(i).identifier == QLatin1String("noop"))
653             continue;
654         s_commandHash.insert(s_commandInfoTable.at(i).identifier, i);
655     }
656 
657     // populate the enums list
658     ADD_ENUMLIST("brush styles", brushStyleTable);
659     ADD_ENUMLIST("pen styles", penStyleTable);
660     ADD_ENUMLIST("font weights", fontWeightTable);
661     ADD_ENUMLIST("font hintings", fontHintingTable);
662     ADD_ENUMLIST("clip operations", clipOperationTable);
663     ADD_ENUMLIST("spread methods", spreadMethodTable);
664     ADD_ENUMLIST("composition modes", compositionModeTable);
665     ADD_ENUMLIST("image formats", imageFormatTable);
666     ADD_ENUMLIST("coordinate modes", coordinateMethodTable);
667     ADD_ENUMLIST("size modes", sizeModeTable);
668 }
669 
670 #undef DECL_PAINTCOMMAND
671 #undef ADD_ENUMLIST
672 /*********************************************************************************
673 ** utility
674 **********************************************************************************/
image_load(const QString & filepath)675 template <typename T> T PaintCommands::image_load(const QString &filepath)
676 {
677     T t(filepath);
678 
679     if (t.isNull())
680         t = T(":images/" + filepath);
681 
682     if (t.isNull())
683         t = T("images/" + filepath);
684 
685     if (t.isNull()) {
686         QFileInfo fi(filepath);
687         QDir dir = fi.absoluteDir();
688         dir.cdUp();
689         dir.cd("images");
690         QString fileName = QString("%1/%2").arg(dir.absolutePath()).arg(fi.fileName());
691         t = T(fileName);
692         if (t.isNull() && !fileName.endsWith(".png")) {
693             fileName.append(".png");
694             t = T(fileName);
695         }
696     }
697 
698     return t;
699 }
700 
701 /*********************************************************************************
702 ** setters
703 **********************************************************************************/
insertAt(int commandIndex,const QStringList & newCommands)704 void PaintCommands::insertAt(int commandIndex, const QStringList &newCommands)
705 {
706     int index = 0;
707     int left = newCommands.size();
708     while (left--)
709         m_commands.insert(++commandIndex, newCommands.at(index++));
710 }
711 
712 /*********************************************************************************
713 ** run
714 **********************************************************************************/
runCommand(const QString & scriptLine)715 void PaintCommands::runCommand(const QString &scriptLine)
716 {
717     if (scriptLine.isEmpty()) {
718         command_noop(QRegExp());
719         return;
720     }
721     if (scriptLine.startsWith('#')) {
722         command_comment(QRegExp());
723         return;
724     }
725     QString firstWord = scriptLine.section(QRegExp("\\s"), 0, 0);
726     QList<int> indices = s_commandHash.values(firstWord);
727     foreach(int idx, indices) {
728         const PaintCommandInfos &command = s_commandInfoTable.at(idx);
729         if (command.regExp.indexIn(scriptLine) >= 0) {
730             (this->*(command.paintMethod))(command.regExp);
731             return;
732         }
733     }
734     qWarning("ERROR: unknown command or argument syntax error in \"%s\"", qPrintable(scriptLine));
735 }
736 
runCommands()737 void PaintCommands::runCommands()
738 {
739     staticInit();
740     int width = m_painter->window().width();
741     int height = m_painter->window().height();
742 
743     if (width <= 0)
744         width = 800;
745     if (height <= 0)
746         height = 800;
747 
748     // paint background
749     if (m_checkers_background) {
750         QPixmap pm(20, 20);
751         pm.fill(Qt::white);
752         QPainter pt(&pm);
753         pt.fillRect(0, 0, 10, 10, QColor::fromRgba(0xffdfdfdf));
754         pt.fillRect(10, 10, 10, 10, QColor::fromRgba(0xffdfdfdf));
755         pt.end();
756         m_painter->drawTiledPixmap(0, 0, width, height, pm);
757     } else {
758         m_painter->fillRect(0, 0, width, height, Qt::white);
759     }
760 
761     // run each command
762     m_abort = false;
763     for (int i=0; i<m_commands.size() && !m_abort; ++i) {
764         const QString &commandNow = m_commands.at(i);
765         m_currentCommand = commandNow;
766         m_currentCommandIndex = i;
767         runCommand(commandNow.trimmed());
768     }
769 }
770 
771 /*********************************************************************************
772 ** conversions
773 **********************************************************************************/
convertToInt(const QString & str)774 int PaintCommands::convertToInt(const QString &str)
775 {
776     return qRound(convertToDouble(str));
777 }
778 
convertToFloat(const QString & str)779 float PaintCommands::convertToFloat(const QString &str)
780 {
781     return float(convertToDouble(str));
782 }
783 
convertToDouble(const QString & str)784 double PaintCommands::convertToDouble(const QString &str)
785 {
786     static QRegExp re("cp([0-9])([xy])");
787     if (str.toLower() == "width") {
788         if (m_painter->device()->devType() == Qt::Widget)
789             return m_painter->window().width();
790         else
791             return 800;
792     }
793     if (str.toLower() == "height") {
794         if (m_painter->device()->devType() == Qt::Widget)
795             return m_painter->window().height();
796         else
797             return 800;
798     }
799     if (re.indexIn(str) >= 0) {
800         int index = re.cap(1).toInt();
801         bool is_it_x = re.cap(2) == "x";
802         if (index < 0 || index >= m_controlPoints.size()) {
803             qWarning("ERROR: control point index=%d is out of bounds", index);
804             return 0;
805         }
806         return is_it_x ? m_controlPoints.at(index).x() : m_controlPoints.at(index).y();
807     }
808     return str.toDouble();
809 }
810 
convertToColor(const QString & str)811 QColor PaintCommands::convertToColor(const QString &str)
812 {
813     static QRegExp alphaColor("#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})");
814     static QRegExp opaqueColor("#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})");
815 
816     Q_ASSERT(alphaColor.isValid());
817     Q_ASSERT(opaqueColor.isValid());
818 
819     if (alphaColor.indexIn(str) >= 0) {
820         return QColor(alphaColor.cap(2).toInt(0, 16),
821                       alphaColor.cap(3).toInt(0, 16),
822                       alphaColor.cap(4).toInt(0, 16),
823                       alphaColor.cap(1).toInt(0, 16));
824     } else if (opaqueColor.indexIn(str) >= 0) {
825         return QColor(opaqueColor.cap(1).toInt(0, 16),
826                       opaqueColor.cap(2).toInt(0, 16),
827                       opaqueColor.cap(3).toInt(0, 16));
828     }
829     return QColor(str);
830 }
831 
832 /*********************************************************************************
833 ** command implementations
834 **********************************************************************************/
command_comment(QRegExp)835 void PaintCommands::command_comment(QRegExp)
836 {
837     if (m_verboseMode)
838         printf(" -(lance) comment: %s\n", qPrintable(m_currentCommand));
839 }
840 
841 /***************************************************************************************************/
command_import(QRegExp re)842 void PaintCommands::command_import(QRegExp re)
843 {
844     QString importFile(re.cap(1));
845     QFileInfo fi(m_filepath);
846     QDir dir = fi.absoluteDir();
847     QFile *file = new QFile(dir.absolutePath() + QDir::separator() + importFile);
848 
849     if (importFile.isEmpty() || !file->exists()) {
850         dir.cdUp();
851         dir.cd("data");
852         dir.cd("qps");
853         delete file;
854         file = new QFile(dir.absolutePath() + QDir::separator() + importFile);
855     }
856 
857     if (importFile.isEmpty() || !file->exists()) {
858         dir.cdUp();
859         dir.cd("images");
860         delete file;
861         file = new QFile(dir.absolutePath() + QDir::separator() + importFile);
862     }
863 
864     if (importFile.isEmpty() || !file->exists()) {
865         printf(" - importing non-existing file at line %d (%s)\n", m_currentCommandIndex,
866                qPrintable(file->fileName()));
867         delete file;
868         return;
869     }
870 
871     if (!file->open(QIODevice::ReadOnly)) {
872         printf(" - failed to read file: '%s'\n", qPrintable(file->fileName()));
873         delete file;
874         return;
875     }
876     if (m_verboseMode)
877         printf(" -(lance) importing file at line %d (%s)\n", m_currentCommandIndex,
878                qPrintable(fi.fileName()));
879 
880     QFileInfo fileinfo(*file);
881     m_commands[m_currentCommandIndex] = QString("# import file (%1) start").arg(fileinfo.fileName());
882     QTextStream textFile(file);
883     QString rawContent = textFile.readAll();
884     QStringList importedData = rawContent.split('\n', QString::SkipEmptyParts);
885     importedData.append(QString("# import file (%1) end ---").arg(fileinfo.fileName()));
886     insertAt(m_currentCommandIndex, importedData);
887 
888     if (m_verboseMode) {
889         printf(" -(lance) Command buffer now looks like:\n");
890         for (int i = 0; i < m_commands.count(); ++i)
891             printf(" ---> {%s}\n", qPrintable(m_commands.at(i)));
892     }
893     delete file;
894 }
895 
896 /***************************************************************************************************/
command_begin_block(QRegExp re)897 void PaintCommands::command_begin_block(QRegExp re)
898 {
899     const QString &blockName = re.cap(1);
900     if (m_verboseMode)
901         printf(" -(lance) begin_block (%s)\n", qPrintable(blockName));
902 
903     m_commands[m_currentCommandIndex] = QString("# begin block (%1)").arg(blockName);
904     QStringList newBlock;
905     int i = m_currentCommandIndex + 1;
906     for (; i < m_commands.count(); ++i) {
907         const QString &nextCmd = m_commands.at(i);
908         if (nextCmd.startsWith("end_block")) {
909             m_commands[i] = QString("# end block (%1)").arg(blockName);
910             break;
911         }
912         newBlock += nextCmd;
913     }
914 
915     if (m_verboseMode)
916         for (int j = 0; j < newBlock.count(); ++j)
917             printf("      %d: %s\n", j, qPrintable(newBlock.at(j)));
918 
919     if (i >= m_commands.count())
920         printf(" - Warning! Block doesn't have an 'end_block' marker!\n");
921 
922     m_blockMap.insert(blockName, newBlock);
923 }
924 
925 /***************************************************************************************************/
command_end_block(QRegExp)926 void PaintCommands::command_end_block(QRegExp)
927 {
928     printf(" - end_block should be consumed by begin_block command.\n");
929     printf("   You will never see this if your block markers are in sync\n");
930     printf("   (noop)\n");
931 }
932 
933 /***************************************************************************************************/
command_repeat_block(QRegExp re)934 void PaintCommands::command_repeat_block(QRegExp re)
935 {
936     QString blockName = re.cap(1);
937     if (m_verboseMode)
938         printf(" -(lance) repeating block (%s)\n", qPrintable(blockName));
939 
940     QStringList block = m_blockMap.value(blockName);
941     if (block.isEmpty()) {
942         printf(" - repeated block (%s) is empty!\n", qPrintable(blockName));
943         return;
944     }
945 
946     m_commands[m_currentCommandIndex] = QString("# repeated block (%1)").arg(blockName);
947     insertAt(m_currentCommandIndex, block);
948 }
949 
950 /***************************************************************************************************/
command_drawLine(QRegExp re)951 void PaintCommands::command_drawLine(QRegExp re)
952 {
953     QStringList caps = re.capturedTexts();
954     double x1 = convertToDouble(caps.at(1));
955     double y1 = convertToDouble(caps.at(2));
956     double x2 = convertToDouble(caps.at(3));
957     double y2 = convertToDouble(caps.at(4));
958 
959     if (m_verboseMode)
960         printf(" -(lance) drawLine((%.2f, %.2f), (%.2f, %.2f))\n", x1, y1, x2, y2);
961 
962     m_painter->drawLine(QLineF(x1, y1, x2, y2));
963 }
964 
965 /***************************************************************************************************/
command_drawPath(QRegExp re)966 void PaintCommands::command_drawPath(QRegExp re)
967 {
968     if (m_verboseMode)
969         printf(" -(lance) drawPath(name=%s)\n", qPrintable(re.cap(1)));
970 
971     QPainterPath &path = m_pathMap[re.cap(1)];
972     m_painter->drawPath(path);
973 }
974 
975 /***************************************************************************************************/
command_drawPixmap(QRegExp re)976 void PaintCommands::command_drawPixmap(QRegExp re)
977 {
978     QPixmap pm;
979     pm = m_pixmapMap[re.cap(1)]; // try cache first
980     if (pm.isNull())
981         pm = image_load<QPixmap>(re.cap(1));
982     if (pm.isNull()) {
983         QFileInfo fi(m_filepath);
984         QDir dir = fi.absoluteDir();
985         dir.cdUp();
986         dir.cd("images");
987         QString fileName = QString("%1/%2").arg(dir.absolutePath()).arg(re.cap(1));
988         pm = QPixmap(fileName);
989         if (pm.isNull() && !fileName.endsWith(".png")) {
990             fileName.append(".png");
991             pm = QPixmap(fileName);
992         }
993     }
994     if (pm.isNull()) {
995         fprintf(stderr, "ERROR(drawPixmap): failed to load pixmap: '%s'\n",
996                 qPrintable(re.cap(1)));
997         return;
998     }
999 
1000     qreal tx = convertToFloat(re.cap(2));
1001     qreal ty = convertToFloat(re.cap(3));
1002     qreal tw = convertToFloat(re.cap(4));
1003     qreal th = convertToFloat(re.cap(5));
1004 
1005     qreal sx = convertToFloat(re.cap(6));
1006     qreal sy = convertToFloat(re.cap(7));
1007     qreal sw = convertToFloat(re.cap(8));
1008     qreal sh = convertToFloat(re.cap(9));
1009 
1010     if (tw == 0) tw = -1;
1011     if (th == 0) th = -1;
1012     if (sw == 0) sw = -1;
1013     if (sh == 0) sh = -1;
1014 
1015     if (m_verboseMode)
1016         printf(" -(lance) drawPixmap('%s' dim=(%d, %d), depth=%d, (%f, %f, %f, %f), (%f, %f, %f, %f)\n",
1017                qPrintable(re.cap(1)), pm.width(), pm.height(), pm.depth(),
1018                tx, ty, tw, th, sx, sy, sw, sh);
1019 
1020     m_painter->drawPixmap(QRectF(tx, ty, tw, th), pm, QRectF(sx, sy, sw, sh));
1021 }
1022 
1023 /***************************************************************************************************/
command_drawImage(QRegExp re)1024 void PaintCommands::command_drawImage(QRegExp re)
1025 {
1026     QImage im;
1027     im = m_imageMap[re.cap(1)]; // try cache first
1028     if (im.isNull())
1029         im = image_load<QImage>(re.cap(1));
1030 
1031     if (im.isNull()) {
1032         QFileInfo fi(m_filepath);
1033         QDir dir = fi.absoluteDir();
1034         dir.cdUp();
1035         dir.cd("images");
1036         QString fileName = QString("%1/%2").arg(dir.absolutePath()).arg(re.cap(1));
1037         im = QImage(fileName);
1038         if (im.isNull() && !fileName.endsWith(".png")) {
1039             fileName.append(".png");
1040             im = QImage(fileName);
1041         }
1042     }
1043     if (im.isNull()) {
1044         fprintf(stderr, "ERROR(drawImage): failed to load image: '%s'\n", qPrintable(re.cap(1)));
1045         return;
1046     }
1047 
1048     qreal tx = convertToFloat(re.cap(2));
1049     qreal ty = convertToFloat(re.cap(3));
1050     qreal tw = convertToFloat(re.cap(4));
1051     qreal th = convertToFloat(re.cap(5));
1052 
1053     qreal sx = convertToFloat(re.cap(6));
1054     qreal sy = convertToFloat(re.cap(7));
1055     qreal sw = convertToFloat(re.cap(8));
1056     qreal sh = convertToFloat(re.cap(9));
1057 
1058     if (tw == 0) tw = -1;
1059     if (th == 0) th = -1;
1060     if (sw == 0) sw = -1;
1061     if (sh == 0) sh = -1;
1062 
1063     if (m_verboseMode)
1064         printf(" -(lance) drawImage('%s' dim=(%d, %d), (%f, %f, %f, %f), (%f, %f, %f, %f)\n",
1065                qPrintable(re.cap(1)), im.width(), im.height(), tx, ty, tw, th, sx, sy, sw, sh);
1066 
1067     m_painter->drawImage(QRectF(tx, ty, tw, th), im, QRectF(sx, sy, sw, sh), Qt::OrderedDither | Qt::OrderedAlphaDither);
1068 }
1069 
1070 /***************************************************************************************************/
command_drawTiledPixmap(QRegExp re)1071 void PaintCommands::command_drawTiledPixmap(QRegExp re)
1072 {
1073     QPixmap pm;
1074     pm = m_pixmapMap[re.cap(1)]; // try cache first
1075     if (pm.isNull())
1076         pm = image_load<QPixmap>(re.cap(1));
1077     if (pm.isNull()) {
1078         QFileInfo fi(m_filepath);
1079         QDir dir = fi.absoluteDir();
1080         dir.cdUp();
1081         dir.cd("images");
1082         QString fileName = QString("%1/%2").arg(dir.absolutePath()).arg(re.cap(1));
1083         pm = QPixmap(fileName);
1084         if (pm.isNull() && !fileName.endsWith(".png")) {
1085             fileName.append(".png");
1086             pm = QPixmap(fileName);
1087         }
1088     }
1089     if (pm.isNull()) {
1090         fprintf(stderr, "ERROR(drawTiledPixmap): failed to load pixmap: '%s'\n",
1091                 qPrintable(re.cap(1)));
1092         return;
1093     }
1094 
1095     int tx = convertToInt(re.cap(2));
1096     int ty = convertToInt(re.cap(3));
1097     int tw = convertToInt(re.cap(4));
1098     int th = convertToInt(re.cap(5));
1099 
1100     int sx = convertToInt(re.cap(6));
1101     int sy = convertToInt(re.cap(7));
1102 
1103     if (tw == 0) tw = -1;
1104     if (th == 0) th = -1;
1105 
1106     if (m_verboseMode)
1107         printf(" -(lance) drawTiledPixmap('%s' dim=(%d, %d), (%d, %d, %d, %d), (%d, %d)\n",
1108                qPrintable(re.cap(1)), pm.width(), pm.height(), tx, ty, tw, th, sx, sy);
1109 
1110     m_painter->drawTiledPixmap(tx, ty, tw, th, pm, sx, sy);
1111 }
1112 
1113 /***************************************************************************************************/
command_drawPoint(QRegExp re)1114 void PaintCommands::command_drawPoint(QRegExp re)
1115 {
1116     QStringList caps = re.capturedTexts();
1117     float x = convertToFloat(caps.at(1));
1118     float y = convertToFloat(caps.at(2));
1119 
1120     if (m_verboseMode)
1121         printf(" -(lance) drawPoint(%.2f, %.2f)\n", x, y);
1122 
1123     m_painter->drawPoint(QPointF(x, y));
1124 }
1125 
1126 /***************************************************************************************************/
command_drawPolygon(QRegExp re)1127 void PaintCommands::command_drawPolygon(QRegExp re)
1128 {
1129     static QRegExp separators("\\s");
1130     QStringList caps = re.capturedTexts();
1131     QString cap = caps.at(1);
1132     QStringList numbers = cap.split(separators, QString::SkipEmptyParts);
1133 
1134     QPolygonF array;
1135     for (int i=0; i + 1<numbers.size(); i+=2)
1136         array.append(QPointF(convertToDouble(numbers.at(i)), convertToDouble(numbers.at(i+1))));
1137 
1138     if (m_verboseMode)
1139         printf(" -(lance) drawPolygon(size=%d)\n", array.size());
1140 
1141     m_painter->drawPolygon(array, caps.at(2).toLower() == "winding" ? Qt::WindingFill : Qt::OddEvenFill);
1142 }
1143 
1144 /***************************************************************************************************/
command_drawPolyline(QRegExp re)1145 void PaintCommands::command_drawPolyline(QRegExp re)
1146 {
1147     static QRegExp separators("\\s");
1148     QStringList numbers = re.cap(1).split(separators, QString::SkipEmptyParts);
1149 
1150     QPolygonF array;
1151     for (int i=0; i + 1<numbers.size(); i+=2)
1152         array.append(QPointF(numbers.at(i).toFloat(),numbers.at(i+1).toFloat()));
1153 
1154     if (m_verboseMode)
1155         printf(" -(lance) drawPolyline(size=%d)\n", array.size());
1156 
1157     m_painter->drawPolyline(array.toPolygon());
1158 }
1159 
1160 /***************************************************************************************************/
command_drawRect(QRegExp re)1161 void PaintCommands::command_drawRect(QRegExp re)
1162 {
1163     QStringList caps = re.capturedTexts();
1164     float x = convertToFloat(caps.at(1));
1165     float y = convertToFloat(caps.at(2));
1166     float w = convertToFloat(caps.at(3));
1167     float h = convertToFloat(caps.at(4));
1168 
1169     if (m_verboseMode)
1170         printf(" -(lance) drawRect(%.2f, %.2f, %.2f, %.2f)\n", x, y, w, h);
1171 
1172     m_painter->drawRect(QRectF(x, y, w, h));
1173 }
1174 
1175 /***************************************************************************************************/
command_drawRoundedRect(QRegExp re)1176 void PaintCommands::command_drawRoundedRect(QRegExp re)
1177 {
1178     QStringList caps = re.capturedTexts();
1179     float x = convertToFloat(caps.at(1));
1180     float y = convertToFloat(caps.at(2));
1181     float w = convertToFloat(caps.at(3));
1182     float h = convertToFloat(caps.at(4));
1183     float xr = convertToFloat(caps.at(5));
1184     float yr = convertToFloat(caps.at(6));
1185 
1186     int mode = translateEnum(sizeModeTable, caps.at(7), sizeof(sizeModeTable)/sizeof(char *));
1187     if (mode < 0)
1188         mode = Qt::AbsoluteSize;
1189 
1190     if (m_verboseMode)
1191         printf(" -(lance) drawRoundRect(%f, %f, %f, %f, %f, %f, %s)\n", x, y, w, h, xr, yr, mode ? "RelativeSize" : "AbsoluteSize");
1192 
1193     m_painter->drawRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::SizeMode(mode));
1194 }
1195 
1196 /***************************************************************************************************/
command_drawRoundRect(QRegExp re)1197 void PaintCommands::command_drawRoundRect(QRegExp re)
1198 {
1199     QStringList caps = re.capturedTexts();
1200     int x = convertToInt(caps.at(1));
1201     int y = convertToInt(caps.at(2));
1202     int w = convertToInt(caps.at(3));
1203     int h = convertToInt(caps.at(4));
1204     int xs = caps.at(5).isEmpty() ? 50 : convertToInt(caps.at(5));
1205     int ys = caps.at(6).isEmpty() ? 50 : convertToInt(caps.at(6));
1206 
1207     if (m_verboseMode)
1208         printf(" -(lance) drawRoundRect(%d, %d, %d, %d, [%d, %d])\n", x, y, w, h, xs, ys);
1209 
1210     m_painter->drawRoundRect(x, y, w, h, xs, ys);
1211 }
1212 
1213 /***************************************************************************************************/
command_drawEllipse(QRegExp re)1214 void PaintCommands::command_drawEllipse(QRegExp re)
1215 {
1216     QStringList caps = re.capturedTexts();
1217     float x = convertToFloat(caps.at(1));
1218     float y = convertToFloat(caps.at(2));
1219     float w = convertToFloat(caps.at(3));
1220     float h = convertToFloat(caps.at(4));
1221 
1222     if (m_verboseMode)
1223         printf(" -(lance) drawEllipse(%.2f, %.2f, %.2f, %.2f)\n", x, y, w, h);
1224 
1225     m_painter->drawEllipse(QRectF(x, y, w, h));
1226 }
1227 
1228 /***************************************************************************************************/
command_drawPie(QRegExp re)1229 void PaintCommands::command_drawPie(QRegExp re)
1230 {
1231     QStringList caps = re.capturedTexts();
1232     int x = convertToInt(caps.at(1));
1233     int y = convertToInt(caps.at(2));
1234     int w = convertToInt(caps.at(3));
1235     int h = convertToInt(caps.at(4));
1236     int angle = convertToInt(caps.at(5));
1237     int sweep = convertToInt(caps.at(6));
1238 
1239     if (m_verboseMode)
1240         printf(" -(lance) drawPie(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
1241 
1242     m_painter->drawPie(x, y, w, h, angle, sweep);
1243 }
1244 
1245 /***************************************************************************************************/
command_drawChord(QRegExp re)1246 void PaintCommands::command_drawChord(QRegExp re)
1247 {
1248     QStringList caps = re.capturedTexts();
1249     int x = convertToInt(caps.at(1));
1250     int y = convertToInt(caps.at(2));
1251     int w = convertToInt(caps.at(3));
1252     int h = convertToInt(caps.at(4));
1253     int angle = convertToInt(caps.at(5));
1254     int sweep = convertToInt(caps.at(6));
1255 
1256     if (m_verboseMode)
1257         printf(" -(lance) drawChord(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
1258 
1259     m_painter->drawChord(x, y, w, h, angle, sweep);
1260 }
1261 
1262 /***************************************************************************************************/
command_drawArc(QRegExp re)1263 void PaintCommands::command_drawArc(QRegExp re)
1264 {
1265     QStringList caps = re.capturedTexts();
1266     int x = convertToInt(caps.at(1));
1267     int y = convertToInt(caps.at(2));
1268     int w = convertToInt(caps.at(3));
1269     int h = convertToInt(caps.at(4));
1270     int angle = convertToInt(caps.at(5));
1271     int sweep = convertToInt(caps.at(6));
1272 
1273     if (m_verboseMode)
1274         printf(" -(lance) drawArc(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
1275 
1276     m_painter->drawArc(x, y, w, h, angle, sweep);
1277 }
1278 
1279 #ifdef QT3_SUPPORT
1280 /***************************************************************************************************/
command_qt3_drawRect(QRegExp re)1281 void PaintCommands::command_qt3_drawRect(QRegExp re)
1282 {
1283     Q_UNUSED(re);
1284 #ifdef QT3_SUPPORT
1285     QStringList caps = re.capturedTexts();
1286     int x = convertToInt(caps.at(1));
1287     int y = convertToInt(caps.at(2));
1288     int w = convertToInt(caps.at(3));
1289     int h = convertToInt(caps.at(4));
1290 
1291     if (m_verboseMode)
1292         printf(" -(lance) qt3_drawRect(%d, %d, %d, %d)\n", x, y, w, h);
1293 
1294     static_cast<Q3Painter*>(m_painter)->drawRect(x, y, w, h);
1295 #endif
1296 }
1297 
1298 /***************************************************************************************************/
command_qt3_drawRoundRect(QRegExp re)1299 void PaintCommands::command_qt3_drawRoundRect(QRegExp re)
1300 {
1301     Q_UNUSED(re);
1302 #ifdef QT3_SUPPORT
1303     QStringList caps = re.capturedTexts();
1304     int x = convertToInt(caps.at(1));
1305     int y = convertToInt(caps.at(2));
1306     int w = convertToInt(caps.at(3));
1307     int h = convertToInt(caps.at(4));
1308     int xrnd = caps.at(5).isEmpty() ? 25 : convertToInt(caps.at(5));
1309     int yrnd = caps.at(6).isEmpty() ? 25 : convertToInt(caps.at(6));
1310 
1311     if (m_verboseMode)
1312         printf(" -(lance) qt3_drawRoundRect(%d, %d, %d, %d), %d, %d\n", x, y, w, h, xrnd, yrnd);
1313 
1314     static_cast<Q3Painter*>(m_painter)->drawRoundRect(x, y, w, h, xrnd, yrnd);
1315 #endif
1316 }
1317 
1318 /***************************************************************************************************/
command_qt3_drawEllipse(QRegExp re)1319 void PaintCommands::command_qt3_drawEllipse(QRegExp re)
1320 {
1321     Q_UNUSED(re);
1322 #ifdef QT3_SUPPORT
1323     QStringList caps = re.capturedTexts();
1324     int x = convertToInt(caps.at(1));
1325     int y = convertToInt(caps.at(2));
1326     int w = convertToInt(caps.at(3));
1327     int h = convertToInt(caps.at(4));
1328 
1329     if (m_verboseMode)
1330         printf(" -(lance) qt3_drawEllipse(%d, %d, %d, %d)\n", x, y, w, h);
1331 
1332     static_cast<Q3Painter*>(m_painter)->drawEllipse(x, y, w, h);
1333 #endif
1334 }
1335 
1336 /***************************************************************************************************/
command_qt3_drawPie(QRegExp re)1337 void PaintCommands::command_qt3_drawPie(QRegExp re)
1338 {
1339     Q_UNUSED(re);
1340 #ifdef QT3_SUPPORT
1341     QStringList caps = re.capturedTexts();
1342     int x = convertToInt(caps.at(1));
1343     int y = convertToInt(caps.at(2));
1344     int w = convertToInt(caps.at(3));
1345     int h = convertToInt(caps.at(4));
1346     int angle = convertToInt(caps.at(5));
1347     int sweep = convertToInt(caps.at(6));
1348 
1349     if (m_verboseMode)
1350         printf(" -(lance) qt3_drawPie(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
1351 
1352     static_cast<Q3Painter*>(m_painter)->drawPie(x, y, w, h, angle, sweep);
1353 #endif
1354 }
1355 
1356 /***************************************************************************************************/
command_qt3_drawChord(QRegExp re)1357 void PaintCommands::command_qt3_drawChord(QRegExp re)
1358 {
1359     Q_UNUSED(re);
1360 #ifdef QT3_SUPPORT
1361     QStringList caps = re.capturedTexts();
1362     int x = convertToInt(caps.at(1));
1363     int y = convertToInt(caps.at(2));
1364     int w = convertToInt(caps.at(3));
1365     int h = convertToInt(caps.at(4));
1366     int angle = convertToInt(caps.at(5));
1367     int sweep = convertToInt(caps.at(6));
1368 
1369     if (m_verboseMode)
1370         printf(" -(lance) qt3_drawChord(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
1371 
1372     static_cast<Q3Painter*>(m_painter)->drawChord(x, y, w, h, angle, sweep);
1373 #endif
1374 }
1375 
1376 /***************************************************************************************************/
command_qt3_drawArc(QRegExp re)1377 void PaintCommands::command_qt3_drawArc(QRegExp re)
1378 {
1379     Q_UNUSED(re);
1380 #ifdef QT3_SUPPORT
1381     QStringList caps = re.capturedTexts();
1382     int x = convertToInt(caps.at(1));
1383     int y = convertToInt(caps.at(2));
1384     int w = convertToInt(caps.at(3));
1385     int h = convertToInt(caps.at(4));
1386     int angle = convertToInt(caps.at(5));
1387     int sweep = convertToInt(caps.at(6));
1388 
1389     if (m_verboseMode)
1390         printf(" -(lance) qt3_drawArc(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
1391 
1392     static_cast<Q3Painter*>(m_painter)->drawArc(x, y, w, h, angle, sweep);
1393 #endif
1394 }
1395 #endif //QT3_SUPPORT
1396 /***************************************************************************************************/
command_drawText(QRegExp re)1397 void PaintCommands::command_drawText(QRegExp re)
1398 {
1399     if (!m_shouldDrawText)
1400         return;
1401     QStringList caps = re.capturedTexts();
1402     int x = convertToInt(caps.at(1));
1403     int y = convertToInt(caps.at(2));
1404     QString txt = caps.at(3);
1405 
1406     if (m_verboseMode)
1407         printf(" -(lance) drawText(%d, %d, %s)\n", x, y, qPrintable(txt));
1408 
1409     m_painter->drawText(x, y, txt);
1410 }
1411 
command_drawStaticText(QRegExp re)1412 void PaintCommands::command_drawStaticText(QRegExp re)
1413 {
1414     if (!m_shouldDrawText)
1415         return;
1416     QStringList caps = re.capturedTexts();
1417     int x = convertToInt(caps.at(1));
1418     int y = convertToInt(caps.at(2));
1419     QString txt = caps.at(3);
1420 
1421     if (m_verboseMode)
1422         printf(" -(lance) drawStaticText(%d, %d, %s)\n", x, y, qPrintable(txt));
1423 
1424     m_painter->drawStaticText(x, y, QStaticText(txt));
1425 }
1426 
1427 /***************************************************************************************************/
command_noop(QRegExp)1428 void PaintCommands::command_noop(QRegExp)
1429 {
1430     if (m_verboseMode)
1431         printf(" -(lance) noop: %s\n", qPrintable(m_currentCommand));
1432 
1433     if (!m_currentCommand.trimmed().isEmpty()) {
1434         fprintf(stderr, "unknown command: '%s'\n", qPrintable(m_currentCommand.trimmed()));
1435     }
1436 }
1437 
1438 /***************************************************************************************************/
command_path_addText(QRegExp re)1439 void PaintCommands::command_path_addText(QRegExp re)
1440 {
1441     QStringList caps = re.capturedTexts();
1442     QString name = caps.at(1);
1443     double x = convertToDouble(caps.at(2));
1444     double y = convertToDouble(caps.at(3));
1445     QString text = caps.at(4);
1446 
1447     if (m_verboseMode)
1448         printf(" -(lance) path_addText(%s, %.2f, %.2f, text=%s\n", qPrintable(name), x, y, qPrintable(text));
1449 
1450     m_pathMap[name].addText(x, y, m_painter->font(), text);
1451 }
1452 
1453 /***************************************************************************************************/
command_path_addEllipse(QRegExp re)1454 void PaintCommands::command_path_addEllipse(QRegExp re)
1455 {
1456     QStringList caps = re.capturedTexts();
1457     QString name = caps.at(1);
1458     double x = convertToDouble(caps.at(2));
1459     double y = convertToDouble(caps.at(3));
1460     double w = convertToDouble(caps.at(4));
1461     double h = convertToDouble(caps.at(5));
1462 
1463     if (m_verboseMode)
1464         printf(" -(lance) path_addEllipse(%s, %.2f, %.2f, %.2f, %.2f)\n", qPrintable(name), x, y, w, h);
1465 
1466     m_pathMap[name].addEllipse(x, y, w, h);
1467 }
1468 
1469 /***************************************************************************************************/
command_path_addRect(QRegExp re)1470 void PaintCommands::command_path_addRect(QRegExp re)
1471 {
1472     QStringList caps = re.capturedTexts();
1473     QString name = caps.at(1);
1474     double x = convertToDouble(caps.at(2));
1475     double y = convertToDouble(caps.at(3));
1476     double w = convertToDouble(caps.at(4));
1477     double h = convertToDouble(caps.at(5));
1478 
1479     if (m_verboseMode)
1480         printf(" -(lance) path_addRect(%s, %.2f, %.2f, %.2f, %.2f)\n", qPrintable(name), x, y, w, h);
1481 
1482     m_pathMap[name].addRect(x, y, w, h);
1483 }
1484 
1485 /***************************************************************************************************/
command_path_addPolygon(QRegExp re)1486 void PaintCommands::command_path_addPolygon(QRegExp re)
1487 {
1488     static QRegExp separators("\\s");
1489     QStringList caps = re.capturedTexts();
1490     QString name = caps.at(1);
1491     QString cap = caps.at(2);
1492     QStringList numbers = cap.split(separators, QString::SkipEmptyParts);
1493 
1494     QPolygonF array;
1495     for (int i=0; i + 1<numbers.size(); i+=2)
1496         array.append(QPointF(numbers.at(i).toFloat(),numbers.at(i+1).toFloat()));
1497 
1498     if (m_verboseMode)
1499         printf(" -(lance) path_addPolygon(name=%s, size=%d)\n", qPrintable(name), array.size());
1500 
1501     m_pathMap[name].addPolygon(array);
1502 }
1503 
1504 /***************************************************************************************************/
command_path_arcTo(QRegExp re)1505 void PaintCommands::command_path_arcTo(QRegExp re)
1506 {
1507     QStringList caps = re.capturedTexts();
1508     QString name = caps.at(1);
1509     double x = convertToDouble(caps.at(2));
1510     double y = convertToDouble(caps.at(3));
1511     double w = convertToDouble(caps.at(4));
1512     double h = convertToDouble(caps.at(5));
1513     double angle = convertToDouble(caps.at(6));
1514     double length = convertToDouble(caps.at(7));
1515 
1516     if (m_verboseMode)
1517         printf(" -(lance) path_arcTo(%s, %.2f, %.2f, %.2f, %.2f, angle=%.2f, len=%.2f)\n", qPrintable(name), x, y, w, h, angle, length);
1518 
1519     m_pathMap[name].arcTo(x, y, w, h, angle, length);
1520 }
1521 
1522 /***************************************************************************************************/
command_path_createOutline(QRegExp re)1523 void PaintCommands::command_path_createOutline(QRegExp re)
1524 {
1525     QStringList caps = re.capturedTexts();
1526     QString name = caps.at(1);
1527     QString newName = caps.at(2);
1528     QPen pen = m_painter->pen();
1529 
1530     if (m_verboseMode)
1531         printf(" -(lance) path_createOutline(%s, name=%s, width=%d)\n",
1532                qPrintable(name), qPrintable(newName), pen.width());
1533 
1534     if (!m_pathMap.contains(name)) {
1535         fprintf(stderr, "createOutline(), unknown path: %s\n", qPrintable(name));
1536         return;
1537     }
1538     QPainterPathStroker stroker;
1539     stroker.setWidth(pen.widthF());
1540     stroker.setDashPattern(pen.style());
1541     stroker.setCapStyle(pen.capStyle());
1542     stroker.setJoinStyle(pen.joinStyle());
1543     m_pathMap[newName] = stroker.createStroke(m_pathMap[name]);
1544 }
1545 
1546 /***************************************************************************************************/
command_path_cubicTo(QRegExp re)1547 void PaintCommands::command_path_cubicTo(QRegExp re)
1548 {
1549     QStringList caps = re.capturedTexts();
1550     QString name = caps.at(1);
1551     double x1 = convertToDouble(caps.at(2));
1552     double y1 = convertToDouble(caps.at(3));
1553     double x2 = convertToDouble(caps.at(4));
1554     double y2 = convertToDouble(caps.at(5));
1555     double x3 = convertToDouble(caps.at(6));
1556     double y3 = convertToDouble(caps.at(7));
1557 
1558     if (m_verboseMode)
1559         printf(" -(lance) path_cubicTo(%s, (%.2f, %.2f), (%.2f, %.2f), (%.2f, %.2f))\n", qPrintable(name), x1, y1, x2, y2, x3, y3);
1560 
1561     m_pathMap[name].cubicTo(x1, y1, x2, y2, x3, y3);
1562 }
1563 
1564 /***************************************************************************************************/
command_path_moveTo(QRegExp re)1565 void PaintCommands::command_path_moveTo(QRegExp re)
1566 {
1567     QStringList caps = re.capturedTexts();
1568     QString name = caps.at(1);
1569     double x1 = convertToDouble(caps.at(2));
1570     double y1 = convertToDouble(caps.at(3));
1571 
1572     if (m_verboseMode)
1573         printf(" -(lance) path_moveTo(%s, (%.2f, %.2f))\n", qPrintable(name), x1, y1);
1574 
1575     m_pathMap[name].moveTo(x1, y1);
1576 }
1577 
1578 /***************************************************************************************************/
command_path_lineTo(QRegExp re)1579 void PaintCommands::command_path_lineTo(QRegExp re)
1580 {
1581     QStringList caps = re.capturedTexts();
1582     QString name = caps.at(1);
1583     double x1 = convertToDouble(caps.at(2));
1584     double y1 = convertToDouble(caps.at(3));
1585 
1586     if (m_verboseMode)
1587         printf(" -(lance) path_lineTo(%s, (%.2f, %.2f))\n", qPrintable(name), x1, y1);
1588 
1589     m_pathMap[name].lineTo(x1, y1);
1590 }
1591 
1592 /***************************************************************************************************/
command_path_setFillRule(QRegExp re)1593 void PaintCommands::command_path_setFillRule(QRegExp re)
1594 {
1595     QStringList caps = re.capturedTexts();
1596     QString name = caps.at(1);
1597     bool winding = caps.at(2).toLower() == "winding";
1598 
1599     if (m_verboseMode)
1600         printf(" -(lance) path_setFillRule(name=%s, winding=%d)\n", qPrintable(name), winding);
1601 
1602     m_pathMap[name].setFillRule(winding ? Qt::WindingFill : Qt::OddEvenFill);
1603 }
1604 
1605 /***************************************************************************************************/
command_path_closeSubpath(QRegExp re)1606 void PaintCommands::command_path_closeSubpath(QRegExp re)
1607 {
1608     QStringList caps = re.capturedTexts();
1609     QString name = caps.at(1);
1610 
1611     if (m_verboseMode)
1612         printf(" -(lance) path_closeSubpath(name=%s)\n", qPrintable(name));
1613 
1614     m_pathMap[name].closeSubpath();
1615 }
1616 
1617 /***************************************************************************************************/
command_path_getClipPath(QRegExp re)1618 void PaintCommands::command_path_getClipPath(QRegExp re)
1619 {
1620     QStringList caps = re.capturedTexts();
1621     QString name = caps.at(1);
1622 
1623     if (m_verboseMode)
1624         printf(" -(lance) path_closeSubpath(name=%s)\n", qPrintable(name));
1625 
1626     m_pathMap[name] = m_painter->clipPath();
1627 }
1628 
1629 /***************************************************************************************************/
qt_debug_path(const QPainterPath & path,const QString & name)1630 static void qt_debug_path(const QPainterPath &path, const QString &name)
1631 {
1632     const char *names[] = {
1633         "MoveTo     ",
1634         "LineTo     ",
1635         "CurveTo    ",
1636         "CurveToData"
1637     };
1638 
1639     printf("\nQPainterPath (%s): elementCount=%d\n", qPrintable(name), path.elementCount());
1640     for (int i=0; i<path.elementCount(); ++i) {
1641         const QPainterPath::Element &e = path.elementAt(i);
1642         Q_ASSERT(e.type >= 0 && e.type <= QPainterPath::CurveToDataElement);
1643         printf(" - %3d:: %s, (%.2f, %.2f)\n", i, names[e.type], e.x, e.y);
1644     }
1645 }
1646 
1647 /***************************************************************************************************/
command_path_debugPrint(QRegExp re)1648 void PaintCommands::command_path_debugPrint(QRegExp re)
1649 {
1650     QStringList caps = re.capturedTexts();
1651     QString name = caps.at(1);
1652     qt_debug_path(m_pathMap[name], name);
1653 }
1654 
1655 /***************************************************************************************************/
command_region_addRect(QRegExp re)1656 void PaintCommands::command_region_addRect(QRegExp re)
1657 {
1658     QStringList caps = re.capturedTexts();
1659     QString name = caps.at(1);
1660     int x = convertToInt(caps.at(2));
1661     int y = convertToInt(caps.at(3));
1662     int w = convertToInt(caps.at(4));
1663     int h = convertToInt(caps.at(5));
1664 
1665     if (m_verboseMode)
1666         printf(" -(lance) region_addRect(%s, %d, %d, %d, %d)\n", qPrintable(name), x, y, w, h);
1667 
1668     m_regionMap[name] += QRect(x, y, w, h);
1669 }
1670 
1671 /***************************************************************************************************/
command_region_addEllipse(QRegExp re)1672 void PaintCommands::command_region_addEllipse(QRegExp re)
1673 {
1674     QStringList caps = re.capturedTexts();
1675     QString name = caps.at(1);
1676     int x = convertToInt(caps.at(2));
1677     int y = convertToInt(caps.at(3));
1678     int w = convertToInt(caps.at(4));
1679     int h = convertToInt(caps.at(5));
1680 
1681     if (m_verboseMode)
1682         printf(" -(lance) region_addEllipse(%s, %d, %d, %d, %d)\n", qPrintable(name), x, y, w, h);
1683 
1684     m_regionMap[name] += QRegion(x, y, w, h, QRegion::Ellipse);
1685 }
1686 
1687 /***************************************************************************************************/
command_region_getClipRegion(QRegExp re)1688 void PaintCommands::command_region_getClipRegion(QRegExp re)
1689 {
1690     QStringList caps = re.capturedTexts();
1691     QString name = caps.at(1);
1692     QRegion region = m_painter->clipRegion();
1693 
1694     if (m_verboseMode)
1695         printf(" -(lance) region_getClipRegion(name=%s), bounds=[%d, %d, %d, %d]\n", qPrintable(name),
1696                region.boundingRect().x(),
1697                region.boundingRect().y(),
1698                region.boundingRect().width(),
1699                region.boundingRect().height());
1700 
1701     m_regionMap[name] = region;
1702 }
1703 
1704 /***************************************************************************************************/
command_resetMatrix(QRegExp)1705 void PaintCommands::command_resetMatrix(QRegExp)
1706 {
1707     if (m_verboseMode)
1708         printf(" -(lance) resetMatrix()\n");
1709 
1710     m_painter->resetTransform();
1711 }
1712 
1713 /***************************************************************************************************/
command_restore(QRegExp)1714 void PaintCommands::command_restore(QRegExp)
1715 {
1716     if (m_verboseMode)
1717         printf(" -(lance) restore()\n");
1718 
1719     m_painter->restore();
1720 }
1721 
1722 /***************************************************************************************************/
command_rotate(QRegExp re)1723 void PaintCommands::command_rotate(QRegExp re)
1724 {
1725     QStringList caps = re.capturedTexts();
1726     double angle = convertToDouble(caps.at(1));
1727 
1728     if (m_verboseMode)
1729         printf(" -(lance) rotate(%.2f)\n", angle);
1730 
1731     m_painter->rotate(angle);
1732 }
1733 
1734 /***************************************************************************************************/
command_rotate_x(QRegExp re)1735 void PaintCommands::command_rotate_x(QRegExp re)
1736 {
1737     QStringList caps = re.capturedTexts();
1738     double angle = convertToDouble(caps.at(1));
1739 
1740     if (m_verboseMode)
1741         printf(" -(lance) rotate_x(%.2f)\n", angle);
1742 
1743     QTransform transform;
1744     transform.rotate(angle, Qt::XAxis);
1745     m_painter->setTransform(transform, true);
1746 }
1747 
1748 /***************************************************************************************************/
command_rotate_y(QRegExp re)1749 void PaintCommands::command_rotate_y(QRegExp re)
1750 {
1751     QStringList caps = re.capturedTexts();
1752     double angle = convertToDouble(caps.at(1));
1753 
1754     if (m_verboseMode)
1755         printf(" -(lance) rotate_y(%.2f)\n", angle);
1756 
1757     QTransform transform;
1758     transform.rotate(angle, Qt::YAxis);
1759     m_painter->setTransform(transform, true);
1760 }
1761 
1762 /***************************************************************************************************/
command_save(QRegExp)1763 void PaintCommands::command_save(QRegExp)
1764 {
1765     if (m_verboseMode)
1766         printf(" -(lance) save()\n");
1767 
1768     m_painter->save();
1769 }
1770 
1771 /***************************************************************************************************/
command_mapQuadToQuad(QRegExp re)1772 void PaintCommands::command_mapQuadToQuad(QRegExp re)
1773 {
1774     QStringList caps = re.capturedTexts();
1775     double x1 = convertToDouble(caps.at(1));
1776     double y1 = convertToDouble(caps.at(2));
1777     double x2 = convertToDouble(caps.at(3));
1778     double y2 = convertToDouble(caps.at(4));
1779     double x3 = convertToDouble(caps.at(5));
1780     double y3 = convertToDouble(caps.at(6));
1781     double x4 = convertToDouble(caps.at(7));
1782     double y4 = convertToDouble(caps.at(8));
1783     QPolygonF poly1(4);
1784     poly1[0] = QPointF(x1, y1);
1785     poly1[1] = QPointF(x2, y2);
1786     poly1[2] = QPointF(x3, y3);
1787     poly1[3] = QPointF(x4, y4);
1788 
1789     double x5 = convertToDouble(caps.at(9));
1790     double y5 = convertToDouble(caps.at(10));
1791     double x6 = convertToDouble(caps.at(11));
1792     double y6 = convertToDouble(caps.at(12));
1793     double x7 = convertToDouble(caps.at(13));
1794     double y7 = convertToDouble(caps.at(14));
1795     double x8 = convertToDouble(caps.at(15));
1796     double y8 = convertToDouble(caps.at(16));
1797     QPolygonF poly2(4);
1798     poly2[0] = QPointF(x5, y5);
1799     poly2[1] = QPointF(x6, y6);
1800     poly2[2] = QPointF(x7, y7);
1801     poly2[3] = QPointF(x8, y8);
1802 
1803     if (m_verboseMode)
1804         printf(" -(lance) mapQuadToQuad(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ->\n\t"
1805                ",%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
1806                x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8);
1807 
1808     QTransform trans;
1809 
1810     if (!QTransform::quadToQuad(poly1, poly2, trans)) {
1811         qWarning("Couldn't perform quad to quad transformation!");
1812     }
1813 
1814     m_painter->setTransform(trans, true);
1815 }
1816 
1817 /***************************************************************************************************/
command_setMatrix(QRegExp re)1818 void PaintCommands::command_setMatrix(QRegExp re)
1819 {
1820     QStringList caps = re.capturedTexts();
1821     double m11 = convertToDouble(caps.at(1));
1822     double m12 = convertToDouble(caps.at(2));
1823     double m13 = convertToDouble(caps.at(3));
1824     double m21 = convertToDouble(caps.at(4));
1825     double m22 = convertToDouble(caps.at(5));
1826     double m23 = convertToDouble(caps.at(6));
1827     double m31 = convertToDouble(caps.at(7));
1828     double m32 = convertToDouble(caps.at(8));
1829     double m33 = convertToDouble(caps.at(9));
1830 
1831     if (m_verboseMode)
1832         printf(" -(lance) setMatrix(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
1833                m11, m12, m13, m21, m22, m23, m31, m32, m33);
1834 
1835     QTransform trans;
1836     trans.setMatrix(m11, m12, m13,
1837                     m21, m22, m23,
1838                     m31, m32, m33);
1839 
1840     m_painter->setTransform(trans, true);
1841 }
1842 
1843 /***************************************************************************************************/
command_scale(QRegExp re)1844 void PaintCommands::command_scale(QRegExp re)
1845 {
1846     QStringList caps = re.capturedTexts();
1847     double sx = convertToDouble(caps.at(1));
1848     double sy = convertToDouble(caps.at(2));
1849 
1850     if (m_verboseMode)
1851         printf(" -(lance) scale(%.2f, %.2f)\n", sx, sy);
1852 
1853 
1854     m_painter->scale(sx, sy);
1855 }
1856 
1857 /***************************************************************************************************/
command_setBackground(QRegExp re)1858 void PaintCommands::command_setBackground(QRegExp re)
1859 {
1860     QStringList caps = re.capturedTexts();
1861     QColor color = convertToColor(caps.at(1));
1862     QString pattern = caps.at(2);
1863 
1864     int style = translateEnum(brushStyleTable, pattern, Qt::LinearGradientPattern);
1865     if (style < 0)
1866         style = Qt::SolidPattern;
1867 
1868     if (m_verboseMode)
1869         printf(" -(lance) setBackground(%s, %s)\n", qPrintable(color.name()), qPrintable(pattern));
1870 
1871     m_painter->setBackground(QBrush(color, Qt::BrushStyle(style)));
1872 }
1873 
1874 /***************************************************************************************************/
command_setOpacity(QRegExp re)1875 void PaintCommands::command_setOpacity(QRegExp re)
1876 {
1877     QStringList caps = re.capturedTexts();
1878     double opacity = convertToDouble(caps.at(1));
1879 
1880     if (m_verboseMode)
1881         printf(" -(lance) setOpacity(%lf)\n", opacity);
1882 
1883     m_painter->setOpacity(opacity);
1884 }
1885 
1886 /***************************************************************************************************/
command_setBgMode(QRegExp re)1887 void PaintCommands::command_setBgMode(QRegExp re)
1888 {
1889     QString cap = re.cap(2);
1890     Qt::BGMode mode = Qt::TransparentMode;
1891     if (cap.toLower() == QLatin1String("opaquemode") || cap.toLower() == QLatin1String("opaque"))
1892         mode = Qt::OpaqueMode;
1893 
1894     if (m_verboseMode)
1895         printf(" -(lance) setBackgroundMode(%s)\n", mode == Qt::OpaqueMode ? "OpaqueMode" : "TransparentMode");
1896 
1897     m_painter->setBackgroundMode(mode);
1898 }
1899 
1900 /***************************************************************************************************/
command_setBrush(QRegExp re)1901 void PaintCommands::command_setBrush(QRegExp re)
1902 {
1903     QStringList caps = re.capturedTexts();
1904 
1905     QPixmap pm = image_load<QPixmap>(caps.at(1));
1906     if (!pm.isNull()) { // Assume pixmap
1907         if (m_verboseMode)
1908             printf(" -(lance) setBrush(pixmap=%s, width=%d, height=%d)\n",
1909                    qPrintable(caps.at(1)), pm.width(), pm.height());
1910 
1911         m_painter->setBrush(QBrush(pm));
1912     } else if (caps.at(1).toLower() == "nobrush") {
1913         m_painter->setBrush(Qt::NoBrush);
1914         if (m_verboseMode)
1915             printf(" -(lance) setBrush(Qt::NoBrush)\n");
1916     } else {
1917         QColor color = convertToColor(caps.at(1));
1918         QString pattern = caps.at(2);
1919 
1920         int style = translateEnum(brushStyleTable, pattern, Qt::LinearGradientPattern);
1921         if (style < 0)
1922             style = Qt::SolidPattern;
1923 
1924         if (m_verboseMode)
1925             printf(" -(lance) setBrush(%s, %s (%d))\n", qPrintable(color.name()), qPrintable(pattern), style);
1926 
1927         m_painter->setBrush(QBrush(color, Qt::BrushStyle(style)));
1928     }
1929 }
1930 
1931 /***************************************************************************************************/
command_setBrushOrigin(QRegExp re)1932 void PaintCommands::command_setBrushOrigin(QRegExp re)
1933 {
1934     int x = convertToInt(re.cap(1));
1935     int y = convertToInt(re.cap(2));
1936 
1937     if (m_verboseMode)
1938         printf(" -(lance) setBrushOrigin(%d, %d)\n", x, y);
1939 
1940     m_painter->setBrushOrigin(x, y);
1941 }
1942 
1943 /***************************************************************************************************/
command_brushTranslate(QRegExp re)1944 void PaintCommands::command_brushTranslate(QRegExp re)
1945 {
1946     QStringList caps = re.capturedTexts();
1947     double dx = convertToDouble(caps.at(1));
1948     double dy = convertToDouble(caps.at(2));
1949 
1950     if (m_verboseMode)
1951         printf(" -(lance) brushTranslate(%f, %f)\n", dx, dy);
1952 
1953     QBrush new_brush = m_painter->brush();
1954     QTransform brush_matrix = new_brush.transform();
1955     brush_matrix.translate(dx, dy);
1956     new_brush.setTransform(brush_matrix);
1957     m_painter->setBrush(new_brush);
1958 }
1959 
1960 /***************************************************************************************************/
command_brushScale(QRegExp re)1961 void PaintCommands::command_brushScale(QRegExp re)
1962 {
1963     QStringList caps = re.capturedTexts();
1964     double sx = convertToDouble(caps.at(1));
1965     double sy = convertToDouble(caps.at(2));
1966 
1967     if (m_verboseMode)
1968         printf(" -(lance) brushScale(%f, %f)\n", sx, sy);
1969 
1970     QBrush new_brush = m_painter->brush();
1971     QTransform brush_matrix = new_brush.transform();
1972     brush_matrix.scale(sx, sy);
1973     new_brush.setTransform(brush_matrix);
1974     m_painter->setBrush(new_brush);
1975 }
1976 
1977 /***************************************************************************************************/
command_brushRotate(QRegExp re)1978 void PaintCommands::command_brushRotate(QRegExp re)
1979 {
1980     QStringList caps = re.capturedTexts();
1981     double rot = convertToDouble(caps.at(1));
1982 
1983     if (m_verboseMode)
1984         printf(" -(lance) brushScale(%f)\n", rot);
1985 
1986     QBrush new_brush = m_painter->brush();
1987     QTransform brush_matrix = new_brush.transform();
1988     brush_matrix.rotate(rot);
1989     new_brush.setTransform(brush_matrix);
1990     m_painter->setBrush(new_brush);
1991 }
1992 
1993 /***************************************************************************************************/
command_brushShear(QRegExp re)1994 void PaintCommands::command_brushShear(QRegExp re)
1995 {
1996     QStringList caps = re.capturedTexts();
1997     double sx = convertToDouble(caps.at(1));
1998     double sy = convertToDouble(caps.at(2));
1999 
2000     if (m_verboseMode)
2001         printf(" -(lance) brushShear(%f, %f)\n", sx, sy);
2002 
2003     QBrush new_brush = m_painter->brush();
2004     QTransform brush_matrix = new_brush.transform();
2005     brush_matrix.shear(sx, sy);
2006     new_brush.setTransform(brush_matrix);
2007     m_painter->setBrush(new_brush);
2008 }
2009 
2010 /***************************************************************************************************/
command_setClipping(QRegExp re)2011 void PaintCommands::command_setClipping(QRegExp re)
2012 {
2013     bool clipping = re.cap(1).toLower() == "true";
2014 
2015     if (m_verboseMode)
2016         printf(" -(lance) setClipping(%d)\n", clipping);
2017 
2018     m_painter->setClipping(clipping);
2019 }
2020 
2021 /***************************************************************************************************/
command_setClipRect(QRegExp re)2022 void PaintCommands::command_setClipRect(QRegExp re)
2023 {
2024     QStringList caps = re.capturedTexts();
2025     int x = convertToInt(caps.at(1));
2026     int y = convertToInt(caps.at(2));
2027     int w = convertToInt(caps.at(3));
2028     int h = convertToInt(caps.at(4));
2029 
2030     int combine = translateEnum(clipOperationTable, caps.at(5), Qt::UniteClip + 1);
2031     if (combine == -1)
2032         combine = Qt::ReplaceClip;
2033 
2034     if (m_verboseMode)
2035         printf(" -(lance) setClipRect(%d, %d, %d, %d), %s\n", x, y, w, h, clipOperationTable[combine]);
2036 
2037     m_painter->setClipRect(x, y, w, h, Qt::ClipOperation(combine));
2038 }
2039 
2040 /***************************************************************************************************/
command_setClipPath(QRegExp re)2041 void PaintCommands::command_setClipPath(QRegExp re)
2042 {
2043     int combine = translateEnum(clipOperationTable, re.cap(2), Qt::UniteClip + 1);
2044     if (combine == -1)
2045         combine = Qt::ReplaceClip;
2046 
2047     if (m_verboseMode)
2048         printf(" -(lance) setClipPath(name=%s), %s\n", qPrintable(re.cap(1)), clipOperationTable[combine]);
2049 
2050     if (!m_pathMap.contains(re.cap(1)))
2051         fprintf(stderr, " - setClipPath, no such path");
2052     m_painter->setClipPath(m_pathMap[re.cap(1)], Qt::ClipOperation(combine));
2053 }
2054 
2055 /***************************************************************************************************/
command_setClipRegion(QRegExp re)2056 void PaintCommands::command_setClipRegion(QRegExp re)
2057 {
2058     int combine = translateEnum(clipOperationTable, re.cap(2), Qt::UniteClip + 1);
2059     if (combine == -1)
2060         combine = Qt::ReplaceClip;
2061     QRegion r = m_regionMap[re.cap(1)];
2062 
2063     if (m_verboseMode)
2064         printf(" -(lance) setClipRegion(name=%s), bounds=[%d, %d, %d, %d], %s\n",
2065                qPrintable(re.cap(1)),
2066                r.boundingRect().x(),
2067                r.boundingRect().y(),
2068                r.boundingRect().width(),
2069                r.boundingRect().height(),
2070                clipOperationTable[combine]);
2071 
2072     m_painter->setClipRegion(m_regionMap[re.cap(1)], Qt::ClipOperation(combine));
2073 }
2074 
2075 /***************************************************************************************************/
command_setFont(QRegExp re)2076 void PaintCommands::command_setFont(QRegExp re)
2077 {
2078     QStringList caps = re.capturedTexts();
2079     QString family = caps.at(1);
2080     int size = convertToInt(caps.at(2));
2081 
2082     int weight = translateEnum(fontWeightTable, re.cap(3).toLower(), 5);
2083     if (weight != -1) {
2084         switch (weight) {
2085         case 0: weight = QFont::Light; break;
2086         case 1: weight = QFont::Normal; break;
2087         case 2: weight = QFont::DemiBold; break;
2088         case 3: weight = QFont::Bold; break;
2089         case 4: weight = QFont::Black; break;
2090         }
2091     } else {
2092         weight = convertToInt(re.cap(3));
2093     }
2094 
2095     bool italic = caps.at(4).toLower() == "true" || caps.at(4).toLower() == "italic";
2096 
2097     QFont font(family, size, weight, italic);
2098 
2099 #if QT_VERSION >= 0x040800
2100     int hinting = translateEnum(fontHintingTable, caps.at(5), 4);
2101     if (hinting == -1)
2102         hinting = 0;
2103     else
2104         font.setHintingPreference(QFont::HintingPreference(hinting));
2105 #else
2106     int hinting = 1;
2107 #endif
2108     if (m_verboseMode)
2109         printf(" -(lance) setFont(family=%s, size=%d, weight=%d, italic=%d hinting=%s\n",
2110                qPrintable(family), size, weight, italic, fontHintingTable[hinting]);
2111 
2112     m_painter->setFont(font);
2113 }
2114 
2115 /***************************************************************************************************/
command_setPen(QRegExp re)2116 void PaintCommands::command_setPen(QRegExp re)
2117 {
2118     QString cap = re.cap(1);
2119     int style = translateEnum(penStyleTable, cap, Qt::DashDotDotLine + 1);
2120     if (style >= 0) {
2121         if (m_verboseMode)
2122             printf(" -(lance) setPen(%s)\n", qPrintable(cap));
2123 
2124         m_painter->setPen(Qt::PenStyle(style));
2125     } else if (cap.toLower() == "brush") {
2126         QPen pen(m_painter->brush(), 0);
2127         if (m_verboseMode) {
2128             printf(" -(lance) setPen(brush), style=%d, color=%08x\n",
2129                    pen.brush().style(), pen.color().rgba());
2130         }
2131         m_painter->setPen(pen);
2132     } else {
2133         QColor color = convertToColor(cap);
2134         if (m_verboseMode)
2135             printf(" -(lance) setPen(%s)\n", qPrintable(color.name()));
2136 
2137         m_painter->setPen(color);
2138     }
2139 }
2140 
2141 /***************************************************************************************************/
command_setPen2(QRegExp re)2142 void PaintCommands::command_setPen2(QRegExp re)
2143 {
2144     QStringList caps = re.capturedTexts();
2145 
2146     QBrush brush;
2147 
2148     if (caps.at(1).toLower() == "brush")
2149         brush = m_painter->brush();
2150     else
2151         brush = convertToColor(caps.at(1));
2152 
2153     double width = convertToDouble(caps.at(2));
2154     int penStyle = translateEnum(penStyleTable, caps.at(3), Qt::DashDotDotLine + 1);
2155     if (penStyle < 0)
2156         penStyle = Qt::SolidLine;
2157 
2158     Qt::PenCapStyle capStyle = Qt::SquareCap;
2159     if (caps.at(4).toLower() == "flatcap") capStyle = Qt::FlatCap;
2160     else if (caps.at(4).toLower() == "squarecap") capStyle = Qt::SquareCap;
2161     else if (caps.at(4).toLower() == "roundcap") capStyle = Qt::RoundCap;
2162     else if (!caps.at(4).isEmpty())
2163         fprintf(stderr, "ERROR: setPen, unknown capStyle: %s\n", qPrintable(caps.at(4)));
2164 
2165     Qt::PenJoinStyle joinStyle = Qt::BevelJoin;
2166     if (caps.at(5).toLower() == "miterjoin") joinStyle = Qt::MiterJoin;
2167     else if (caps.at(5).toLower() == "beveljoin") joinStyle = Qt::BevelJoin;
2168     else if (caps.at(5).toLower() == "roundjoin") joinStyle = Qt::RoundJoin;
2169     else if (!caps.at(5).isEmpty())
2170         fprintf(stderr, "ERROR: setPen, unknown joinStyle: %s\n", qPrintable(caps.at(5)));
2171 
2172     if (m_verboseMode)
2173         printf(" -(lance) setPen(%s, width=%f, style=%d, cap=%d, join=%d)\n",
2174                qPrintable(brush.color().name()), width, penStyle, capStyle, joinStyle);
2175 
2176     m_painter->setPen(QPen(brush, width, Qt::PenStyle(penStyle), capStyle, joinStyle));
2177 }
2178 
2179 /***************************************************************************************************/
command_setRenderHint(QRegExp re)2180 void PaintCommands::command_setRenderHint(QRegExp re)
2181 {
2182     QString hintString = re.cap(1).toLower();
2183     bool on = re.cap(2).isEmpty() || re.cap(2).toLower() == "true";
2184     if (hintString.contains("antialiasing")) {
2185         if (m_verboseMode)
2186             printf(" -(lance) setRenderHint Antialiasing\n");
2187 
2188         m_painter->setRenderHint(QPainter::Antialiasing, on);
2189     } else if (hintString.contains("smoothpixmaptransform")) {
2190         if (m_verboseMode)
2191             printf(" -(lance) setRenderHint SmoothPixmapTransform\n");
2192         m_painter->setRenderHint(QPainter::SmoothPixmapTransform, on);
2193     } else {
2194         fprintf(stderr, "ERROR(setRenderHint): unknown hint '%s'\n", qPrintable(hintString));
2195     }
2196 }
2197 
2198 /***************************************************************************************************/
command_clearRenderHint(QRegExp)2199 void PaintCommands::command_clearRenderHint(QRegExp /*re*/)
2200 {
2201     m_painter->setRenderHint(QPainter::Antialiasing, false);
2202     m_painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
2203     if (m_verboseMode)
2204         printf(" -(lance) clearRenderHint\n");
2205 }
2206 
2207 /***************************************************************************************************/
command_setCompositionMode(QRegExp re)2208 void PaintCommands::command_setCompositionMode(QRegExp re)
2209 {
2210     QString modeString = re.cap(1).toLower();
2211     int mode = translateEnum(compositionModeTable, modeString, 33);
2212 
2213     if (mode < 0 || mode > QPainter::RasterOp_SourceAndNotDestination) {
2214         fprintf(stderr, "ERROR: invalid mode: %s\n", qPrintable(modeString));
2215         return;
2216     }
2217 
2218     if (m_verboseMode)
2219         printf(" -(lance) setCompositionMode: %d: %s\n", mode, qPrintable(modeString));
2220 
2221     m_painter->setCompositionMode(QPainter::CompositionMode(mode));
2222 }
2223 
2224 /***************************************************************************************************/
command_translate(QRegExp re)2225 void PaintCommands::command_translate(QRegExp re)
2226 {
2227     QStringList caps = re.capturedTexts();
2228     double dx = convertToDouble(caps.at(1));
2229     double dy = convertToDouble(caps.at(2));
2230 
2231     if (m_verboseMode)
2232         printf(" -(lance) translate(%f, %f)\n", dx, dy);
2233 
2234     m_painter->translate(dx, dy);
2235 }
2236 
2237 /***************************************************************************************************/
command_pixmap_load(QRegExp re)2238 void PaintCommands::command_pixmap_load(QRegExp re)
2239 {
2240     QStringList caps = re.capturedTexts();
2241 
2242     QString fileName = caps.at(1);
2243     QString name = caps.at(2);
2244 
2245     if (name.isEmpty())
2246         name = fileName;
2247 
2248     QImage im = image_load<QImage>(fileName);
2249     QPixmap px = QPixmap::fromImage(im, Qt::OrderedDither | Qt::OrderedAlphaDither);
2250 
2251     if (m_verboseMode)
2252         printf(" -(lance) pixmap_load(%s as %s), size=[%d, %d], depth=%d\n",
2253                qPrintable(fileName), qPrintable(name),
2254                px.width(), px.height(), px.depth());
2255 
2256     m_pixmapMap[name] = px;
2257 }
2258 
2259 /***************************************************************************************************/
command_bitmap_load(QRegExp re)2260 void PaintCommands::command_bitmap_load(QRegExp re)
2261 {
2262     QStringList caps = re.capturedTexts();
2263 
2264     QString fileName = caps.at(1);
2265     QString name = caps.at(2);
2266 
2267     if (name.isEmpty())
2268         name = fileName;
2269 
2270     QBitmap bm = image_load<QBitmap>(fileName);
2271 
2272     if (m_verboseMode)
2273         printf(" -(lance) bitmap_load(%s as %s), size=[%d, %d], depth=%d\n",
2274                qPrintable(fileName), qPrintable(name),
2275                bm.width(), bm.height(), bm.depth());
2276 
2277     m_pixmapMap[name] = bm;
2278 }
2279 
2280 /***************************************************************************************************/
command_pixmap_setMask(QRegExp re)2281 void PaintCommands::command_pixmap_setMask(QRegExp re)
2282 {
2283     QStringList caps = re.capturedTexts();
2284     QBitmap mask = image_load<QBitmap>(caps.at(2));
2285 
2286     if (m_verboseMode)
2287         printf(" -(lance) pixmap_setMask(%s, %s)\n", qPrintable(caps.at(1)), qPrintable(caps.at(2)));
2288 
2289     if (!m_pixmapMap[caps.at(1)].isNull())
2290         m_pixmapMap[caps.at(1)].setMask(mask);
2291 }
2292 
2293 /***************************************************************************************************/
command_image_load(QRegExp re)2294 void PaintCommands::command_image_load(QRegExp re)
2295 {
2296     QStringList caps = re.capturedTexts();
2297 
2298     QString fileName = caps.at(1);
2299     QString name = caps.at(2);
2300 
2301     if (name.isEmpty())
2302         name = fileName;
2303 
2304     QImage image = image_load<QImage>(fileName);
2305 
2306     if (m_verboseMode)
2307         printf(" -(lance) image_load(%s as %s), size=[%d, %d], format=%d\n",
2308                qPrintable(fileName), qPrintable(name),
2309                image.width(), image.height(), image.format());
2310 
2311     m_imageMap[name] = image;
2312 }
2313 
2314 /***************************************************************************************************/
command_image_setColorCount(QRegExp re)2315 void PaintCommands::command_image_setColorCount(QRegExp re)
2316 {
2317     QStringList caps = re.capturedTexts();
2318 
2319     QString name = caps.at(1);
2320     int count = convertToInt(caps.at(2));
2321 
2322     if (m_verboseMode)
2323         printf(" -(lance) image_setColorCount(%s), %d -> %d\n",
2324                qPrintable(name), m_imageMap[name].colorCount(), count);
2325 
2326     m_imageMap[name].setColorCount(count);
2327 }
2328 
2329 /***************************************************************************************************/
command_image_setColor(QRegExp re)2330 void PaintCommands::command_image_setColor(QRegExp re)
2331 {
2332     QStringList caps = re.capturedTexts();
2333 
2334     QString name = caps.at(1);
2335     int index = convertToInt(caps.at(2));
2336     QColor color = convertToColor(caps.at(3));
2337 
2338     if (m_verboseMode)
2339         printf(" -(lance) image_setColor(%s), %d = %08x\n", qPrintable(name), index, color.rgba());
2340 
2341     m_imageMap[name].setColor(index, color.rgba());
2342 }
2343 
2344 /***************************************************************************************************/
command_abort(QRegExp)2345 void PaintCommands::command_abort(QRegExp)
2346 {
2347     m_abort = true;
2348 }
2349 
2350 /***************************************************************************************************/
command_gradient_clearStops(QRegExp)2351 void PaintCommands::command_gradient_clearStops(QRegExp)
2352 {
2353     if (m_verboseMode)
2354         printf(" -(lance) gradient_clearStops\n");
2355     m_gradientStops.clear();
2356 }
2357 
2358 /***************************************************************************************************/
command_gradient_appendStop(QRegExp re)2359 void PaintCommands::command_gradient_appendStop(QRegExp re)
2360 {
2361     QStringList caps = re.capturedTexts();
2362     double pos = convertToDouble(caps.at(1));
2363     QColor color = convertToColor(caps.at(2));
2364 
2365     if (m_verboseMode)
2366         printf(" -(lance) gradient_appendStop(%.2f, %x)\n", pos, color.rgba());
2367 
2368     m_gradientStops << QGradientStop(pos, color);
2369 }
2370 
2371 /***************************************************************************************************/
command_gradient_setLinear(QRegExp re)2372 void PaintCommands::command_gradient_setLinear(QRegExp re)
2373 {
2374     QStringList caps = re.capturedTexts();
2375     double x1 = convertToDouble(caps.at(1));
2376     double y1 = convertToDouble(caps.at(2));
2377     double x2 = convertToDouble(caps.at(3));
2378     double y2 = convertToDouble(caps.at(4));
2379 
2380     if (m_verboseMode)
2381         printf(" -(lance) gradient_setLinear (%.2f, %.2f), (%.2f, %.2f), spread=%d\n",
2382                x1, y1, x2, y2, m_gradientSpread);
2383 
2384     QLinearGradient lg(QPointF(x1, y1), QPointF(x2, y2));
2385     lg.setStops(m_gradientStops);
2386     lg.setSpread(m_gradientSpread);
2387     lg.setCoordinateMode(m_gradientCoordinate);
2388     QBrush brush(lg);
2389     QTransform brush_matrix = m_painter->brush().transform();
2390     brush.setTransform(brush_matrix);
2391     m_painter->setBrush(brush);
2392 }
2393 
2394 /***************************************************************************************************/
command_gradient_setLinearPen(QRegExp re)2395 void PaintCommands::command_gradient_setLinearPen(QRegExp re)
2396 {
2397     QStringList caps = re.capturedTexts();
2398     double x1 = convertToDouble(caps.at(1));
2399     double y1 = convertToDouble(caps.at(2));
2400     double x2 = convertToDouble(caps.at(3));
2401     double y2 = convertToDouble(caps.at(4));
2402 
2403     if (m_verboseMode)
2404         printf(" -(lance) gradient_setLinear (%.2f, %.2f), (%.2f, %.2f), spread=%d\n",
2405                x1, y1, x2, y2, m_gradientSpread);
2406 
2407     QLinearGradient lg(QPointF(x1, y1), QPointF(x2, y2));
2408     lg.setStops(m_gradientStops);
2409     lg.setSpread(m_gradientSpread);
2410     lg.setCoordinateMode(m_gradientCoordinate);
2411     QPen pen = m_painter->pen();
2412     pen.setBrush(lg);
2413     m_painter->setPen(pen);
2414 }
2415 
2416 /***************************************************************************************************/
command_gradient_setRadial(QRegExp re)2417 void PaintCommands::command_gradient_setRadial(QRegExp re)
2418 {
2419     QStringList caps = re.capturedTexts();
2420     double cx = convertToDouble(caps.at(1));
2421     double cy = convertToDouble(caps.at(2));
2422     double rad = convertToDouble(caps.at(3));
2423     double fx = convertToDouble(caps.at(4));
2424     double fy = convertToDouble(caps.at(5));
2425 
2426     if (m_verboseMode)
2427         printf(" -(lance) gradient_setRadial center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), "
2428                "spread=%d\n",
2429                cx, cy, rad, fx, fy, m_gradientSpread);
2430 
2431     QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy));
2432     rg.setStops(m_gradientStops);
2433     rg.setSpread(m_gradientSpread);
2434     rg.setCoordinateMode(m_gradientCoordinate);
2435     QBrush brush(rg);
2436     QTransform brush_matrix = m_painter->brush().transform();
2437     brush.setTransform(brush_matrix);
2438     m_painter->setBrush(brush);
2439 }
2440 
2441 /***************************************************************************************************/
command_gradient_setRadialExtended(QRegExp re)2442 void PaintCommands::command_gradient_setRadialExtended(QRegExp re)
2443 {
2444     QStringList caps = re.capturedTexts();
2445     double cx = convertToDouble(caps.at(1));
2446     double cy = convertToDouble(caps.at(2));
2447     double rad = convertToDouble(caps.at(3));
2448     double fx = convertToDouble(caps.at(4));
2449     double fy = convertToDouble(caps.at(5));
2450     double frad = convertToDouble(caps.at(6));
2451 
2452     if (m_verboseMode)
2453         printf(" -(lance) gradient_setRadialExtended center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), "
2454                "focal radius=%.2f, spread=%d\n",
2455                cx, cy, rad, fx, fy, frad, m_gradientSpread);
2456 
2457 #if QT_VERSION >= 0x040800
2458     QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy), frad);
2459 #else
2460     QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy));
2461 #endif
2462     rg.setStops(m_gradientStops);
2463     rg.setSpread(m_gradientSpread);
2464     rg.setCoordinateMode(m_gradientCoordinate);
2465     QBrush brush(rg);
2466     QTransform brush_matrix = m_painter->brush().transform();
2467     brush.setTransform(brush_matrix);
2468     m_painter->setBrush(brush);
2469 }
2470 
2471 /***************************************************************************************************/
command_gradient_setConical(QRegExp re)2472 void PaintCommands::command_gradient_setConical(QRegExp re)
2473 {
2474     QStringList caps = re.capturedTexts();
2475     double cx = convertToDouble(caps.at(1));
2476     double cy = convertToDouble(caps.at(2));
2477     double angle = convertToDouble(caps.at(3));
2478 
2479     if (m_verboseMode) {
2480         printf(" -(lance) gradient_setConical center=(%.2f, %.2f), angle=%.2f\n, spread=%d",
2481                cx, cy, angle, m_gradientSpread);
2482     }
2483 
2484     QConicalGradient cg(QPointF(cx, cy), angle);
2485     cg.setStops(m_gradientStops);
2486     cg.setSpread(m_gradientSpread);
2487     cg.setCoordinateMode(m_gradientCoordinate);
2488     QBrush brush(cg);
2489     QTransform brush_matrix = m_painter->brush().transform();
2490     brush.setTransform(brush_matrix);
2491     m_painter->setBrush(brush);
2492 }
2493 
2494 /***************************************************************************************************/
command_gradient_setSpread(QRegExp re)2495 void PaintCommands::command_gradient_setSpread(QRegExp re)
2496 {
2497     int spreadMethod = translateEnum(spreadMethodTable, re.cap(1), 3);
2498 
2499     if (m_verboseMode)
2500         printf(" -(lance) gradient_setSpread %d=[%s]\n", spreadMethod, spreadMethodTable[spreadMethod]);
2501 
2502     m_gradientSpread = QGradient::Spread(spreadMethod);
2503 }
2504 
command_gradient_setCoordinateMode(QRegExp re)2505 void PaintCommands::command_gradient_setCoordinateMode(QRegExp re)
2506 {
2507     int coord = translateEnum(coordinateMethodTable, re.cap(1), 3);
2508 
2509     if (m_verboseMode)
2510         printf(" -(lance) gradient_setCoordinateMode %d=[%s]\n", coord,
2511                coordinateMethodTable[coord]);
2512 
2513     m_gradientCoordinate = QGradient::CoordinateMode(coord);
2514 }
2515 
2516 /***************************************************************************************************/
command_surface_begin(QRegExp re)2517 void PaintCommands::command_surface_begin(QRegExp re)
2518 {
2519     QStringList caps = re.capturedTexts();
2520     double x = convertToDouble(caps.at(1));
2521     double y = convertToDouble(caps.at(2));
2522     double w = convertToDouble(caps.at(3));
2523     double h = convertToDouble(caps.at(4));
2524 
2525     if (m_surface_painter) {
2526         fprintf(stderr, "ERROR: surface already active");
2527         return;
2528     }
2529 
2530     if (m_verboseMode)
2531         printf(" -(lance) surface_begin, pos=[%.2f, %.2f], size=[%.2f, %.2f]\n", x, y, w, h);
2532 
2533     m_surface_painter = m_painter;
2534 
2535     if (m_type == OpenGLType || m_type == OpenGLPBufferType) {
2536 #ifndef QT_NO_OPENGL
2537         m_surface_pbuffer = new QGLPixelBuffer(qRound(w), qRound(h));
2538         m_painter = new QPainter(m_surface_pbuffer);
2539         m_painter->fillRect(QRect(0, 0, qRound(w), qRound(h)), Qt::transparent);
2540 #endif
2541 #ifdef Q_WS_X11
2542     } else if (m_type == WidgetType) {
2543         m_surface_pixmap = QPixmap(qRound(w), qRound(h));
2544         m_surface_pixmap.fill(Qt::transparent);
2545         m_painter = new QPainter(&m_surface_pixmap);
2546 #endif
2547     } else {
2548         m_surface_image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32_Premultiplied);
2549         m_surface_image.fill(0);
2550         m_painter = new QPainter(&m_surface_image);
2551     }
2552     m_surface_rect = QRectF(x, y, w, h);
2553 }
2554 
2555 /***************************************************************************************************/
command_surface_end(QRegExp)2556 void PaintCommands::command_surface_end(QRegExp)
2557 {
2558     if (!m_surface_painter) {
2559         fprintf(stderr, "ERROR: surface not active");
2560         return;
2561     }
2562 
2563     if (m_verboseMode)
2564         printf(" -(lance) surface_end, pos=[%.2f, %.2f], size=[%.2f, %.2f]\n",
2565                m_surface_rect.x(),
2566                m_surface_rect.y(),
2567                m_surface_rect.width(),
2568                m_surface_rect.height());
2569     m_painter->end();
2570 
2571     delete m_painter;
2572     m_painter = m_surface_painter;
2573     m_surface_painter = 0;
2574 
2575     if (m_type == OpenGLType || m_type == OpenGLPBufferType) {
2576 #ifndef QT_NO_OPENGL
2577         QImage image = m_surface_pbuffer->toImage();
2578         QImage new_image(image.bits(), image.width(),
2579                          image.height(), QImage::Format_ARGB32_Premultiplied);
2580         QPaintDevice *pdev = m_painter->device();
2581         if (pdev->devType() == QInternal::Widget) {
2582             QWidget *w = static_cast<QWidget *>(pdev);
2583             static_cast<QGLWidget *>(w)->makeCurrent();
2584         } else if (pdev->devType() == QInternal::Pbuffer) {
2585             static_cast<QGLPixelBuffer *>(pdev)->makeCurrent();
2586         }
2587 
2588         m_painter->drawImage(m_surface_rect, new_image);
2589 
2590         delete m_surface_pbuffer;
2591         m_surface_pbuffer = 0;
2592 #endif
2593 #ifdef Q_WS_X11
2594     } else if (m_type == WidgetType) {
2595         m_painter->drawPixmap(m_surface_rect.topLeft(), m_surface_pixmap);
2596         m_surface_pixmap = QPixmap();
2597 #endif
2598     } else {
2599         m_painter->drawImage(m_surface_rect, m_surface_image);
2600         m_surface_image = QImage();
2601     }
2602     m_surface_rect = QRectF();
2603 }
2604 
2605 /***************************************************************************************************/
command_image_convertToFormat(QRegExp re)2606 void PaintCommands::command_image_convertToFormat(QRegExp re)
2607 {
2608     QStringList caps = re.capturedTexts();
2609 
2610     QString srcName = caps.at(1);
2611     QString destName = caps.at(2);
2612 
2613     if (!m_imageMap.contains(srcName)) {
2614         fprintf(stderr, "ERROR(convertToFormat): no such image '%s'\n", qPrintable(srcName));
2615         return;
2616     }
2617 
2618     int format = translateEnum(imageFormatTable, caps.at(3), QImage::NImageFormats);
2619     if (format < 0 || format >= QImage::NImageFormats) {
2620         fprintf(stderr, "ERROR(convertToFormat): invalid format %d = '%s'\n",
2621                 format, qPrintable(caps.at(3)));
2622         return;
2623     }
2624 
2625     QImage src = m_imageMap[srcName];
2626     QImage dest = src.convertToFormat(QImage::Format(format),
2627                                       Qt::OrderedAlphaDither | Qt::OrderedDither);
2628 
2629     if (m_verboseMode) {
2630         printf(" -(lance) convertToFormat %s:%d -> %s:%d\n",
2631                qPrintable(srcName), src.format(),
2632                qPrintable(destName), dest.format());
2633     }
2634 
2635     m_imageMap[destName] = dest;
2636 }
2637 
2638 /***************************************************************************************************/
command_textlayout_draw(QRegExp re)2639 void PaintCommands::command_textlayout_draw(QRegExp re)
2640 {
2641     QStringList caps = re.capturedTexts();
2642 
2643     QString text = caps.at(1);
2644     double width = convertToDouble(caps.at(2));
2645 
2646     if (m_verboseMode)
2647         printf(" -(lance) textlayout_draw text='%s', width=%f\n",
2648                qPrintable(text), width);
2649 
2650     QFont copy = m_painter->font();
2651     copy.setPointSize(10);
2652 
2653     QTextLayout layout(text, copy, m_painter->device());
2654     layout.beginLayout();
2655 
2656     double y_offset = 0;
2657 
2658     while (true) {
2659         QTextLine line = layout.createLine();
2660         if (!line.isValid())
2661             break;
2662         line.setLineWidth(width);
2663         line.setPosition(QPointF(0, y_offset));
2664 
2665         y_offset += line.height();
2666     }
2667 
2668     layout.draw(m_painter, QPointF(0, 0));
2669 }
2670 
2671 /***************************************************************************************************/
command_pen_setDashOffset(QRegExp re)2672 void PaintCommands::command_pen_setDashOffset(QRegExp re)
2673 {
2674     QStringList caps = re.capturedTexts();
2675     double offset = convertToDouble(caps.at(1));
2676 
2677     if (m_verboseMode)
2678         printf(" -(lance) setDashOffset(%lf)\n", offset);
2679 
2680     QPen p = m_painter->pen();
2681     p.setDashOffset(offset);
2682     m_painter->setPen(p);
2683 }
2684 
2685 /***************************************************************************************************/
command_pen_setDashPattern(QRegExp re)2686 void PaintCommands::command_pen_setDashPattern(QRegExp re)
2687 {
2688     static QRegExp separators("\\s");
2689     QStringList caps = re.capturedTexts();
2690     QString cap = caps.at(1);
2691     QStringList numbers = cap.split(separators, QString::SkipEmptyParts);
2692 
2693     QVector<qreal> pattern;
2694     for (int i=0; i<numbers.size(); ++i)
2695         pattern.append(convertToDouble(numbers.at(i)));
2696 
2697     if (m_verboseMode)
2698         printf(" -(lance) pen_setDashPattern(size=%d)\n", pattern.size());
2699 
2700     QPen p = m_painter->pen();
2701     p.setDashPattern(pattern);
2702     m_painter->setPen(p);
2703 }
2704 
2705 /***************************************************************************************************/
command_pen_setCosmetic(QRegExp re)2706 void PaintCommands::command_pen_setCosmetic(QRegExp re)
2707 {
2708     QString hm = re.capturedTexts().at(1);
2709     bool on = hm == "true" || hm == "yes" || hm == "on";
2710 
2711     if (m_verboseMode) {
2712         printf(" -(lance) pen_setCosmetic(%s)\n", on ? "true" : "false");
2713     }
2714 
2715     QPen p = m_painter->pen();
2716     p.setCosmetic(on);
2717 
2718     m_painter->setPen(p);
2719 }
2720 
2721 /***************************************************************************************************/
command_drawConvexPolygon(QRegExp re)2722 void PaintCommands::command_drawConvexPolygon(QRegExp re)
2723 {
2724     static QRegExp separators("\\s");
2725     QStringList caps = re.capturedTexts();
2726     QString cap = caps.at(1);
2727     QStringList numbers = cap.split(separators, QString::SkipEmptyParts);
2728 
2729     QPolygonF array;
2730     for (int i=0; i + 1<numbers.size(); i+=2)
2731         array.append(QPointF(convertToDouble(numbers.at(i)), convertToDouble(numbers.at(i+1))));
2732 
2733     if (m_verboseMode)
2734         printf(" -(lance) drawConvexPolygon(size=%d)\n", array.size());
2735 
2736 
2737     m_painter->drawConvexPolygon(array);
2738 }
2739