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