qt5base-lts/tests/baseline/shared/paintcommands.cpp
Marc Mutz f2f8820073 tests: port assorted trivial uses of Q_FOREACH to ranged for loops
All of these fall into the trivial category: loops over (readily made)
const local containers. As such, they cannot possibly depend on the
safety copy that Q_FOREACH performs, so are safe to port as-is to
ranged for loops.

There may be more where these came from, but these were the ones that
stood out as immediately obvious when scanning the 100s of uses in
qtbase, so I preferred to directly fix them over white-listing their
files with QT_NO_FOREACH (which still may be necessary for some files,
as this patch may not port all uses in that file).

Pick-to: 6.6 6.5
Task-nubmber: QTBUG-115839
Change-Id: I7b7893bec8254f902660dac24167113aca855029
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2023-08-14 23:11:54 +03:00

2951 lines
114 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "paintcommands.h"
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qpainter.h>
#include <qpainterpath.h>
#include <qbitmap.h>
#include <qtextstream.h>
#include <qtextlayout.h>
#include <qdebug.h>
#include <QStaticText>
#include <QTextDocument>
#include <private/qimage_p.h>
#ifndef QT_NO_OPENGL
#include <QOpenGLFramebufferObjectFormat>
#include <QOpenGLContext>
#include <QOpenGLPaintDevice>
#endif
/*********************************************************************************
** everything to populate static tables
**********************************************************************************/
const char *PaintCommands::brushStyleTable[] = {
"NoBrush",
"SolidPattern",
"Dense1Pattern",
"Dense2Pattern",
"Dense3Pattern",
"Dense4Pattern",
"Dense5Pattern",
"Dense6Pattern",
"Dense7Pattern",
"HorPattern",
"VerPattern",
"CrossPattern",
"BDiagPattern",
"FDiagPattern",
"DiagCrossPattern",
"LinearGradientPattern"
};
const char *PaintCommands::penStyleTable[] = {
"NoPen",
"SolidLine",
"DashLine",
"DotLine",
"DashDotLine",
"DashDotDotLine"
};
const char *PaintCommands::fontWeightTable[] = {
"Light",
"Normal",
"DemiBold",
"Bold",
"Black"
};
const char *PaintCommands::fontHintingTable[] = {
"Default",
"None",
"Vertical",
"Full"
};
const char *PaintCommands::fontCapitalizationTable[] = {
"MixedCase",
"AllUppercase",
"AllLowercase",
"SmallCaps",
"Capitalize"
};
const char *PaintCommands::clipOperationTable[] = {
"NoClip",
"ReplaceClip",
"IntersectClip",
"UniteClip"
};
const char *PaintCommands::spreadMethodTable[] = {
"PadSpread",
"ReflectSpread",
"RepeatSpread"
};
const char *PaintCommands::coordinateMethodTable[] = {
"LogicalMode",
"StretchToDeviceMode",
"ObjectBoundingMode",
"ObjectMode"
};
const char *PaintCommands::sizeModeTable[] = {
"AbsoluteSize",
"RelativeSize"
};
const char *PaintCommands::compositionModeTable[] = {
"SourceOver",
"DestinationOver",
"Clear",
"Source",
"Destination",
"SourceIn",
"DestinationIn",
"SourceOut",
"DestinationOut",
"SourceAtop",
"DestinationAtop",
"Xor",
"Plus",
"Multiply",
"Screen",
"Overlay",
"Darken",
"Lighten",
"ColorDodge",
"ColorBurn",
"HardLight",
"SoftLight",
"Difference",
"Exclusion",
"SourceOrDestination",
"SourceAndDestination",
"SourceXorDestination",
"NotSourceAndNotDestination",
"NotSourceOrNotDestination",
"NotSourceXorDestination",
"NotSource",
"NotSourceAndDestination",
"SourceAndNotDestination"
};
const char *PaintCommands::imageFormatTable[] = {
"Invalid",
"Mono",
"MonoLSB",
"Indexed8",
"RGB32",
"ARGB32",
"ARGB32_Premultiplied",
"Format_RGB16",
"Format_ARGB8565_Premultiplied",
"Format_RGB666",
"Format_ARGB6666_Premultiplied",
"Format_RGB555",
"Format_ARGB8555_Premultiplied",
"Format_RGB888",
"Format_RGB444",
"Format_ARGB4444_Premultiplied",
"Format_RGBX8888",
"Format_RGBA8888",
"Format_RGBA8888_Premultiplied",
"Format_BGR30",
"Format_A2BGR30_Premultiplied",
"Format_RGB30",
"Format_A2RGB30_Premultiplied",
"Alpha8",
"Grayscale8",
"RGBx64",
"RGBA64",
"RGBA64_Premultiplied",
"Grayscale16",
"BGR888",
"RGBx16FPx4",
"RGBA16FPx4",
"RGBA16FPx4_Premultiplied",
"RGBx32FPx4",
"RGBA32FPx4",
"RGBA32FPx4_Premultiplied",
};
const char *PaintCommands::renderHintTable[] = {
"Antialiasing",
"SmoothPixmapTransform",
"NonCosmeticBrushPatterns"
};
int PaintCommands::translateEnum(const char *table[], const QString &pattern, int limit)
{
QByteArray p = pattern.toLatin1().toLower();
for (int i=0; i<limit; ++i)
if (p == QByteArray::fromRawData(table[i], qstrlen(table[i])).toLower())
return i;
return -1;
}
QList<PaintCommands::PaintCommandInfos> PaintCommands::s_commandInfoTable = QList<PaintCommands::PaintCommandInfos>();
QList<QPair<QString,QStringList> > PaintCommands::s_enumsTable = QList<QPair<QString,QStringList> >();
QMultiHash<QString, int> PaintCommands::s_commandHash;
#define DECL_PAINTCOMMAND(identifier, method, regexp, syntax, sample) \
s_commandInfoTable << PaintCommandInfos(QLatin1String(identifier), &PaintCommands::method, QRegularExpression(regexp), \
QLatin1String(syntax), QLatin1String(sample) );
#define DECL_PAINTCOMMANDSECTION(title) \
s_commandInfoTable << PaintCommandInfos(QLatin1String(title));
#define ADD_ENUMLIST(listCaption, cStrArray) { \
QStringList list; \
for (int i=0; i<int(sizeof(cStrArray)/sizeof(char*)); i++) \
list << cStrArray[i]; \
s_enumsTable << qMakePair(QString(listCaption), list); \
}
void PaintCommands::staticInit()
{
// check if already done
if (!s_commandInfoTable.isEmpty()) return;
// populate the command list
DECL_PAINTCOMMANDSECTION("misc");
DECL_PAINTCOMMAND("comment", command_comment,
"^\\s*#",
"# this is some comments",
"# place your comments here");
DECL_PAINTCOMMAND("import", command_import,
"^import\\s+\"(.*)\"$",
"import <qrcFilename>",
"import \"myfile.qrc\"");
DECL_PAINTCOMMAND("begin_block", command_begin_block,
"^begin_block\\s+(\\w*)$",
"begin_block <blockName>",
"begin_block blockName");
DECL_PAINTCOMMAND("end_block", command_end_block,
"^end_block\\s*(\\w*)$",
"end_block [blockName]",
"end_block blockName");
DECL_PAINTCOMMAND("repeat_block", command_repeat_block,
"^repeat_block\\s+(\\w*)$",
"repeat_block <blockName>",
"repeat_block blockName");
DECL_PAINTCOMMAND("textlayout_draw", command_textlayout_draw,
"^textlayout_draw\\s+\"(.*)\"\\s+([0-9.]*)$",
"textlayout_draw <text> <width>",
"textlayout_draw \"your text\" 1.0");
DECL_PAINTCOMMAND("abort", command_abort,
"^abort$",
"abort",
"abort");
DECL_PAINTCOMMAND("noop", command_noop,
"^$",
"-",
"\n");
DECL_PAINTCOMMANDSECTION("setters");
DECL_PAINTCOMMAND("setBackgroundMode", command_setBgMode,
"^(setBackgroundMode|setBgMode)\\s+(\\w*)$",
"setBackgroundMode <OpaqueMode|TransparentMode>",
"setBackgroundMode TransparentMode");
DECL_PAINTCOMMAND("setBackground", command_setBackground,
"^setBackground\\s+#?(\\w*)\\s*(\\w*)?$",
"setBackground <color> [brush style enum]",
"setBackground black SolidPattern");
DECL_PAINTCOMMAND("setOpacity", command_setOpacity,
"^setOpacity\\s+(-?\\d*\\.?\\d*)$",
"setOpacity <opacity>\n - opacity is in [0,1]",
"setOpacity 1.0");
DECL_PAINTCOMMAND("path_setFillRule", command_path_setFillRule,
"^path_setFillRule\\s+(\\w*)\\s+(\\w*)$",
"path_setFillRule <pathName> [Winding|OddEven]",
"path_setFillRule pathName Winding");
DECL_PAINTCOMMAND("setBrush", command_setBrush,
"^setBrush\\s+(#?[\\w.:\\/]*)\\s*(\\w*)?$",
"setBrush <imageFileName>\nsetBrush noBrush\nsetBrush <color> <brush style enum>",
"setBrush white SolidPattern");
DECL_PAINTCOMMAND("setBrushOrigin", command_setBrushOrigin,
"^setBrushOrigin\\s*(-?\\w*)\\s+(-?\\w*)$",
"setBrushOrigin <dx> <dy>",
"setBrushOrigin 0 0");
DECL_PAINTCOMMAND("brushTranslate", command_brushTranslate,
"^brushTranslate\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"brushTranslate <tx> <ty>",
"brushTranslate 0.0 0.0");
DECL_PAINTCOMMAND("brushScale", command_brushScale,
"^brushScale\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"brushScale <kx> <ky>",
"brushScale 0.0 0.0");
DECL_PAINTCOMMAND("brushRotate", command_brushRotate,
"^brushRotate\\s+(-?[\\w.]*)$",
"brushRotate <angle>\n - angle in degrees",
"brushRotate 0.0");
DECL_PAINTCOMMAND("brushShear", command_brushShear,
"^brushShear\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"brushShear <sx> <sy>",
"brushShear 0.0 0.0");
DECL_PAINTCOMMAND("setCompositionMode", command_setCompositionMode,
"^setCompositionMode\\s+([\\w_0-9]*)$",
"setCompositionMode <composition mode enum>",
"setCompositionMode SourceOver");
DECL_PAINTCOMMAND("setFont", command_setFont,
"^setFont\\s+\"([\\w\\s]*)\"\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)$",
"setFont <fontFace> [size] [font weight|font weight enum] [italic] [hinting enum] [underline] [strikeout] [overline] [capitalization enum]\n - font weight is an integer between 0 and 99",
"setFont \"times\" 12");
DECL_PAINTCOMMAND("setPen", command_setPen,
"^setPen\\s+#?(\\w*)$",
"setPen <color>\nsetPen <pen style enum>\nsetPen brush",
"setPen black");
DECL_PAINTCOMMAND("setPen", command_setPen2,
"^setPen\\s+(#?\\w*)\\s+([\\w.]+)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)$",
"setPen brush|<color> [width] [pen style enum] [FlatCap|SquareCap|RoundCap] [MiterJoin|BevelJoin|RoundJoin]",
"setPen black 1 FlatCap MiterJoin");
DECL_PAINTCOMMAND("pen_setDashOffset", command_pen_setDashOffset,
"^pen_setDashOffset\\s+(-?[\\w.]+)$",
"pen_setDashOffset <offset>\n",
"pen_setDashOffset 1.0");
DECL_PAINTCOMMAND("pen_setDashPattern", command_pen_setDashPattern,
"^pen_setDashPattern\\s+\\[([\\w\\s.]*)\\]$",
"pen_setDashPattern <[ <dash_1> <space_1> ... <dash_n> <space_n> ]>",
"pen_setDashPattern [ 2 1 4 1 3 3 ]");
DECL_PAINTCOMMAND("pen_setCosmetic", command_pen_setCosmetic,
"^pen_setCosmetic\\s+(\\w*)$",
"pen_setCosmetic <true|false>",
"pen_setCosmetic true");
DECL_PAINTCOMMAND("setRenderHint", command_setRenderHint,
"^setRenderHint\\s+([\\w_0-9]*)\\s*(\\w*)$",
"setRenderHint <hint> <true|false>",
"setRenderHint Antialiasing true");
DECL_PAINTCOMMAND("clearRenderHint", command_clearRenderHint,
"^clearRenderHint$",
"clearRenderHint",
"clearRenderHint");
DECL_PAINTCOMMANDSECTION("gradients");
DECL_PAINTCOMMAND("gradient_appendStop", command_gradient_appendStop,
"^gradient_appendStop\\s+([\\w.]*)\\s+#?(\\w*)$",
"gradient_appendStop <pos> <color>",
"gradient_appendStop 1.0 red");
DECL_PAINTCOMMAND("gradient_clearStops", command_gradient_clearStops,
"^gradient_clearStops$",
"gradient_clearStops",
"gradient_clearStops");
DECL_PAINTCOMMAND("gradient_setConical", command_gradient_setConical,
"^gradient_setConical\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$",
"gradient_setConical <cx> <cy> <angle>\n - angle in degrees",
"gradient_setConical 5.0 5.0 45.0");
DECL_PAINTCOMMAND("gradient_setLinear", command_gradient_setLinear,
"^gradient_setLinear\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$",
"gradient_setLinear <x1> <y1> <x2> <y2>",
"gradient_setLinear 1.0 1.0 2.0 2.0");
DECL_PAINTCOMMAND("gradient_setRadial", command_gradient_setRadial,
"^gradient_setRadial\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$",
"gradient_setRadial <cx> <cy> <rad> <fx> <fy>\n - C is the center\n - rad is the radius\n - F is the focal point",
"gradient_setRadial 1.0 1.0 45.0 2.0 2.0");
DECL_PAINTCOMMAND("gradient_setRadialExtended", command_gradient_setRadialExtended,
"^gradient_setRadialExtended\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$",
"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",
"gradient_setRadialExtended 1.0 1.0 45.0 2.0 2.0 45.0");
DECL_PAINTCOMMAND("gradient_setLinearPen", command_gradient_setLinearPen,
"^gradient_setLinearPen\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$",
"gradient_setLinearPen <x1> <y1> <x2> <y2>",
"gradient_setLinearPen 1.0 1.0 2.0 2.0");
DECL_PAINTCOMMAND("gradient_setSpread", command_gradient_setSpread,
"^gradient_setSpread\\s+(\\w*)$",
"gradient_setSpread <spread method enum>",
"gradient_setSpread PadSpread");
DECL_PAINTCOMMAND("gradient_setCoordinateMode", command_gradient_setCoordinateMode,
"^gradient_setCoordinateMode\\s+(\\w*)$",
"gradient_setCoordinateMode <coordinate method enum>",
"gradient_setCoordinateMode ObjectBoundingMode");
DECL_PAINTCOMMANDSECTION("drawing ops");
DECL_PAINTCOMMAND("drawPoint", command_drawPoint,
"^drawPoint\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"drawPoint <x> <y>",
"drawPoint 10.0 10.0");
DECL_PAINTCOMMAND("drawLine", command_drawLine,
"^drawLine\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"drawLine <x1> <y1> <x2> <y2>",
"drawLine 10.0 10.0 20.0 20.0");
DECL_PAINTCOMMAND("drawLines", command_drawLines,
"^drawLines\\s+\\[([\\w\\s\\-.]*)\\]$",
"drawLines <[ <l1x1> <l1y1> <l1x2> <l1y2> <l2x1> <l2y1> ... ]>",
"drawLines [ 10 10 50 10 50 20 10 20 ]");
DECL_PAINTCOMMAND("drawRect", command_drawRect,
"^drawRect\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"drawRect <x> <y> <w> <h>",
"drawRect 10.0 10.0 20.0 20.0");
DECL_PAINTCOMMAND("drawRoundRect", command_drawRoundRect,
"^drawRoundRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(-?\\w*)?\\s*(-?\\w*)?$",
"drawRoundRect <x> <y> <w> <h> [rx] [ry]",
"drawRoundRect 10 10 20 20 3 3");
DECL_PAINTCOMMAND("drawRoundedRect", command_drawRoundedRect,
"^drawRoundedRect\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s*(\\w*)?$",
"drawRoundedRect <x> <y> <w> <h> <rx> <ry> [SizeMode enum]",
"drawRoundedRect 10 10 20 20 4 4 AbsoluteSize");
DECL_PAINTCOMMAND("drawArc", command_drawArc,
"^drawArc\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
"drawArc <x> <y> <w> <h> <angleStart> <angleArc>\n - angles are expressed in 1/16th of degree",
"drawArc 10 10 20 20 0 5760");
DECL_PAINTCOMMAND("drawChord", command_drawChord,
"^drawChord\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
"drawChord <x> <y> <w> <h> <angleStart> <angleArc>\n - angles are expressed in 1/16th of degree",
"drawChord 10 10 20 20 0 5760");
DECL_PAINTCOMMAND("drawEllipse", command_drawEllipse,
"^drawEllipse\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"drawEllipse <x> <y> <w> <h>",
"drawEllipse 10.0 10.0 20.0 20.0");
DECL_PAINTCOMMAND("drawPath", command_drawPath,
"^drawPath\\s+(\\w*)$",
"drawPath <pathName>",
"drawPath mypath");
DECL_PAINTCOMMAND("drawPie", command_drawPie,
"^drawPie\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
"drawPie <x> <y> <w> <h> <angleStart> <angleArc>\n - angles are expressed in 1/16th of degree",
"drawPie 10 10 20 20 0 5760");
DECL_PAINTCOMMAND("drawPixmap", command_drawPixmap,
"^drawPixmap\\s+([\\w.:\\-/]*)"
"\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?" // target rect
"\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?$", // source rect
"drawPixmap <filename> <tx> <ty> <tw> <th> <sx> <sy> <sw> <sh>"
"\n- where t means target and s means source"
"\n- a width or height of -1 means maximum space",
"drawPixmap :/images/face.png 0 0 -1 -1 0 0 -1 -1");
DECL_PAINTCOMMAND("drawImage", command_drawImage,
"^drawImage\\s+([\\w.:\\/]*)"
"\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?" // target rect
"\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?\\s*(-?[\\w.]*)?$", // source rect
"drawImage <filename> <tx> <ty> <tw> <th> <sx> <sy> <sw> <sh>"
"\n- where t means target and s means source"
"\n- a width or height of -1 means maximum space",
"drawImage :/images/face.png 0 0 -1 -1 0 0 -1 -1");
DECL_PAINTCOMMAND("drawPolygon", command_drawPolygon,
"^drawPolygon\\s+\\[([\\w\\s\\-.]*)\\]\\s*(\\w*)$",
"drawPolygon <[ <x1> <y1> ... <xn> <yn> ]> <Winding|OddEven>",
"drawPolygon [ 1 4 6 8 5 3 ] Winding");
DECL_PAINTCOMMAND("drawConvexPolygon", command_drawConvexPolygon,
"^drawConvexPolygon\\s+\\[([\\w\\s-.]*)\\]$",
"drawConvexPolygon <[ <x1> <y1> ... <xn> <yn> ]>",
"drawConvexPolygon [ 1 4 6 8 5 3 ]");
DECL_PAINTCOMMAND("drawPolyline", command_drawPolyline,
"^drawPolyline\\s+\\[([\\w\\s\\-.]*)\\]$",
"drawPolyline <[ <x1> <y1> ... <xn> <yn> ]>",
"drawPolyline [ 1 4 6 8 5 3 ]");
DECL_PAINTCOMMAND("drawText", command_drawText,
"^drawText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$",
"drawText <x> <y> <text>",
"drawText 10 10 \"my text\"");
DECL_PAINTCOMMAND("drawStaticText", command_drawStaticText,
"^drawStaticText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$",
"drawStaticText <x> <y> <text>",
"drawStaticText 10 10 \"my text\"");
DECL_PAINTCOMMAND("drawGlyphRun", command_drawGlyphRun,
"^drawGlyphRun\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$",
"drawGlyphRun <x> <y> <text> - Will create glyph run using QTextLayout and draw this",
"drawGlyphRun 10 10 \"my text\"");
DECL_PAINTCOMMAND("drawTextDocument", command_drawTextDocument,
"^drawTextDocument\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$",
"drawTextDocument <x> <y> <html>",
"drawTextDocument 10 10 \"html\"");
DECL_PAINTCOMMAND("drawTiledPixmap", command_drawTiledPixmap,
"^drawTiledPixmap\\s+([\\w.:\\/]*)"
"\\s+(-?\\w*)\\s+(-?\\w*)\\s*(-?\\w*)\\s*(-?\\w*)"
"\\s*(-?\\w*)\\s*(-?\\w*)$",
"drawTiledPixmap <tile image filename> <tx> <ty> <tx> <ty> <sx> <sy>"
"\n - where t means tile"
"\n - and s is an offset in the tile",
"drawTiledPixmap :/images/alpha.png ");
DECL_PAINTCOMMAND("fillRect", command_fillRect,
"^fillRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(\\w*)?$",
"fillRect <x> <y> <w> <h> [color]\n - Uses current brush if no color given",
"fillRect 10 10 20 20 blue");
DECL_PAINTCOMMAND("fillRectF", command_fillRectF,
"^fillRectF\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s*(\\w*)?$",
"fillRectF <x> <y> <w> <h> [color]\n - Uses current brush if no color given",
"fillRectF 10.5 10.5 20.2 20.2 blue");
DECL_PAINTCOMMAND("drawPixmapFragments", command_drawPixmapFragments,
"^drawPixmapFragments\\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]*)?\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?"
"\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?$",
"drawPixmapFragments <image filename> <count>"
" <centerx0> <centery0> <x0> <y0> <w0> <h0> <sx0> <sy0> <r0> <o0>"
" <centerx1> <centery1> <x1> <y1> <w1> ..."
"\n - where count is 1 or 2, and followed by centerPos, sourceRect, scaleX, scaleY, rotation, opacity <count> times",
"drawPixmapFragments :/images/sign.png 1 50 50 10 10 60 60 10 10 30 1");
DECL_PAINTCOMMANDSECTION("painterPaths");
DECL_PAINTCOMMAND("path_moveTo", command_path_moveTo,
"^path_moveTo\\s+([.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"path_moveTo <pathName> <x> <y>",
"path_moveTo mypath 1.0 1.0");
DECL_PAINTCOMMAND("path_lineTo", command_path_lineTo,
"^path_lineTo\\s+([.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"path_lineTo <pathName> <x> <y>",
"path_lineTo mypath 1.0 1.0");
DECL_PAINTCOMMAND("path_addEllipse", command_path_addEllipse,
"^path_addEllipse\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"path_addEllipse <pathName> <x1> <y1> <x2> <y2>",
"path_addEllipse mypath 10.0 10.0 20.0 20.0");
DECL_PAINTCOMMAND("path_addPolygon", command_path_addPolygon,
"^path_addPolygon\\s+(\\w*)\\s+\\[([\\w\\s]*)\\]\\s*(\\w*)$",
"path_addPolygon <pathName> <[ <x1> <y1> ... <xn> <yn> ]>",
"path_addPolygon mypath [ 1 4 6 8 5 3 ]");
DECL_PAINTCOMMAND("path_addRect", command_path_addRect,
"^path_addRect\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"path_addRect <pathName> <x1> <y1> <x2> <y2>",
"path_addRect mypath 10.0 10.0 20.0 20.0");
DECL_PAINTCOMMAND("path_addText", command_path_addText,
"^path_addText\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+\"(.*)\"$",
"path_addText <pathName> <x> <y> <text>",
"path_addText mypath 10.0 20.0 \"some text\"");
DECL_PAINTCOMMAND("path_arcTo", command_path_arcTo,
"^path_arcTo\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"path_arcTo <pathName> <x> <y> <w> <h> <angleStart> <angleArc>\n - angles are expressed in degrees",
"path_arcTo mypath 0.0 0.0 10.0 10.0 0.0 360.0");
DECL_PAINTCOMMAND("path_cubicTo", command_path_cubicTo,
"^path_cubicTo\\s+(\\w*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"path_cubicTo <pathName> <x1> <y1> <x2> <y2> <x3> <y3>",
"path_cubicTo mypath 0.0 0.0 10.0 10.0 20.0 20.0");
DECL_PAINTCOMMAND("path_closeSubpath", command_path_closeSubpath,
"^path_closeSubpath\\s+(\\w*)$",
"path_closeSubpath <pathName>",
"path_closeSubpath mypath");
DECL_PAINTCOMMAND("path_createOutline", command_path_createOutline,
"^path_createOutline\\s+(\\w*)\\s+(\\w*)$",
"path_createOutline <pathName> <newName>",
"path_createOutline mypath myoutline");
DECL_PAINTCOMMAND("path_debugPrint", command_path_debugPrint,
"^path_debugPrint\\s+(\\w*)$",
"path_debugPrint <pathName>",
"path_debugPrint mypath");
DECL_PAINTCOMMANDSECTION("regions");
DECL_PAINTCOMMAND("region_addRect", command_region_addRect,
"^region_addRect\\s+(\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
"region_addRect <regionName> <x1> <y1> <x2> <y2>",
"region_addRect myregion 0.0 0.0 10.0 10.0");
DECL_PAINTCOMMAND("region_addEllipse", command_region_addEllipse,
"^region_addEllipse\\s+(\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$",
"region_addEllipse <regionName> <x1> <y1> <x2> <y2>",
"region_addEllipse myregion 0.0 0.0 10.0 10.0");
DECL_PAINTCOMMANDSECTION("clipping");
DECL_PAINTCOMMAND("region_getClipRegion", command_region_getClipRegion,
"^region_getClipRegion\\s+(\\w*)$",
"region_getClipRegion <regionName>",
"region_getClipRegion myregion");
DECL_PAINTCOMMAND("setClipRegion", command_setClipRegion,
"^setClipRegion\\s+(\\w*)\\s*(\\w*)$",
"setClipRegion <regionName> <clip operation enum>",
"setClipRegion myregion ReplaceClip");
DECL_PAINTCOMMAND("path_getClipPath", command_path_getClipPath,
"^path_getClipPath\\s+([\\w0-9]*)$",
"path_getClipPath <pathName>",
"path_getClipPath mypath");
DECL_PAINTCOMMAND("setClipPath", command_setClipPath,
"^setClipPath\\s+(\\w*)\\s*(\\w*)$",
"setClipPath <pathName> <clip operation enum>",
"setClipPath mypath ReplaceClip");
DECL_PAINTCOMMAND("setClipRect", command_setClipRect,
"^setClipRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(\\w*)$",
"setClipRect <x> <y> <w> <h> <clip operation enum>",
"setClipRect 0 0 10 10 ReplaceClip");
DECL_PAINTCOMMAND("setClipRectF", command_setClipRectF,
"^setClipRectF\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s*(\\w.*)$",
"setClipRectF <x> <y> <w> <h> <clip operation enum>",
"setClipRectF 0.1 0.2 10.3 10.4 ReplaceClip");
DECL_PAINTCOMMAND("setClipping", command_setClipping,
"^setClipping\\s+(\\w*)$",
"setClipping <true|false>",
"setClipping true");
DECL_PAINTCOMMANDSECTION("surface");
DECL_PAINTCOMMAND("surface_begin", command_surface_begin,
"^surface_begin\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"surface_begin <x> <y> <w> <h>",
"surface_begin 0.0 0.0 10.0 10.0");
DECL_PAINTCOMMAND("surface_end", command_surface_end,
"^surface_end$",
"surface_end",
"surface_end");
DECL_PAINTCOMMANDSECTION("painter states");
DECL_PAINTCOMMAND("restore", command_restore,
"^restore$",
"restore",
"restore");
DECL_PAINTCOMMAND("save", command_save,
"^save$",
"save",
"save");
DECL_PAINTCOMMANDSECTION("pixmaps'n'images");
DECL_PAINTCOMMAND("pixmap_load", command_pixmap_load,
"^pixmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
"pixmap_load <image filename> <pixmapName>",
"pixmap_load :/images/face.png myPixmap");
DECL_PAINTCOMMAND("pixmap_setMask", command_pixmap_setMask,
"^pixmap_setMask\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]*)$",
"pixmap_setMask <pixmapName> <bitmap filename>",
"pixmap_setMask myPixmap :/images/bitmap.png");
DECL_PAINTCOMMAND("bitmap_load", command_bitmap_load,
"^bitmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
"bitmap_load <bitmap filename> <bitmapName>\n - note that the image is stored as a pixmap",
"bitmap_load :/images/bitmap.png myBitmap");
DECL_PAINTCOMMAND("pixmap_setDevicePixelRatio", command_pixmap_setDevicePixelRatio,
"^pixmap_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$",
"pixmap_setDevicePixelRatio <pixmapName> <dpr>",
"pixmap_setDevicePixelRatio myPixmap 2.0");
DECL_PAINTCOMMAND("image_convertToFormat", command_image_convertToFormat,
"^image_convertToFormat\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]+)\\s+([\\w0-9_]*)$",
"image_convertToFormat <sourceImageName> <destImageName> <image format enum>",
"image_convertToFormat myImage myNewImage Indexed8");
DECL_PAINTCOMMAND("image_load", command_image_load,
"^image_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
"image_load <filename> <imageName>",
"image_load :/images/face.png myImage");
DECL_PAINTCOMMAND("image_setColor", command_image_setColor,
"^image_setColor\\s+([\\w.:\\/]*)\\s+([0-9]*)\\s+#([0-9]*)$",
"image_setColor <imageName> <index> <color>",
"image_setColor myImage 0 black");
DECL_PAINTCOMMAND("image_setColorCount", command_image_setColorCount,
"^image_setColorCount\\s+([\\w.:\\/]*)\\s+([0-9]*)$",
"image_setColorCount <imageName> <nbColors>",
"image_setColorCount myImage 128");
DECL_PAINTCOMMAND("image_setDevicePixelRatio", command_image_setDevicePixelRatio,
"^image_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$",
"image_setDevicePixelRatio <imageName> <dpr>",
"image_setDevicePixelRatio myImage 2.0");
DECL_PAINTCOMMANDSECTION("transformations");
DECL_PAINTCOMMAND("resetMatrix", command_resetMatrix,
"^resetMatrix$",
"resetMatrix",
"resetMatrix");
DECL_PAINTCOMMAND("setMatrix", command_setMatrix,
"^setMatrix\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$",
"setMatrix <m11> <m12> <m13> <m21> <m22> <m23> <m31> <m32> <m33>",
"setMatrix 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0");
DECL_PAINTCOMMAND("translate", command_translate,
"^translate\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"translate <tx> <ty>",
"translate 10.0 10.0");
DECL_PAINTCOMMAND("rotate", command_rotate,
"^rotate\\s+(-?[\\w.]*)$",
"rotate <angle>\n - with angle in degrees",
"rotate 30.0");
DECL_PAINTCOMMAND("rotate_x", command_rotate_x,
"^rotate_x\\s+(-?[\\w.]*)$",
"rotate_x <angle>\n - with angle in degrees",
"rotate_x 30.0");
DECL_PAINTCOMMAND("rotate_y", command_rotate_y,
"^rotate_y\\s+(-?[\\w.]*)$",
"rotate_y <angle>\n - with angle in degrees",
"rotate_y 30.0");
DECL_PAINTCOMMAND("scale", command_scale,
"^scale\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$",
"scale <sx> <sy>",
"scale 2.0 1.0");
DECL_PAINTCOMMAND("mapQuadToQuad", command_mapQuadToQuad,
"^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]*)$",
"mapQuadToQuad <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4> <x5> <y5> <x6> <y6> <x7> <y7> <x8> <y8>"
"\n - where vertices 1 to 4 defines the source quad and 5 to 8 the destination quad",
"mapQuadToQuad 0.0 0.0 1.0 1.0 0.0 0.0 -1.0 -1.0");
// populate the command lookup hash
for (int i=0; i<s_commandInfoTable.size(); i++) {
// and pre-optimize the regexps.
s_commandInfoTable.at(i).regExp.optimize();
if (s_commandInfoTable.at(i).isSectionHeader() ||
s_commandInfoTable.at(i).identifier == QLatin1String("comment") ||
s_commandInfoTable.at(i).identifier == QLatin1String("noop"))
continue;
s_commandHash.insert(s_commandInfoTable.at(i).identifier, i);
}
// populate the enums list
ADD_ENUMLIST("brush styles", brushStyleTable);
ADD_ENUMLIST("pen styles", penStyleTable);
ADD_ENUMLIST("font weights", fontWeightTable);
ADD_ENUMLIST("font hintings", fontHintingTable);
ADD_ENUMLIST("clip operations", clipOperationTable);
ADD_ENUMLIST("spread methods", spreadMethodTable);
ADD_ENUMLIST("composition modes", compositionModeTable);
ADD_ENUMLIST("image formats", imageFormatTable);
ADD_ENUMLIST("coordinate modes", coordinateMethodTable);
ADD_ENUMLIST("size modes", sizeModeTable);
ADD_ENUMLIST("render hints", renderHintTable);
}
#undef DECL_PAINTCOMMAND
#undef ADD_ENUMLIST
/*********************************************************************************
** utility
**********************************************************************************/
template <typename T> T PaintCommands::image_load(const QString &filepath)
{
T t(filepath);
if (t.isNull())
t = T(":images/" + filepath);
if (t.isNull())
t = T("images/" + filepath);
if (t.isNull()) {
QFileInfo fi(filepath);
QDir dir = fi.absoluteDir();
dir.cdUp();
dir.cd("images");
QString fileName = dir.absolutePath() + QLatin1Char('/') + fi.fileName();
t = T(fileName);
if (t.isNull() && !fileName.endsWith(".png")) {
fileName.append(".png");
t = T(fileName);
}
}
return t;
}
/*********************************************************************************
** setters
**********************************************************************************/
void PaintCommands::insertAt(int commandIndex, const QStringList &newCommands)
{
int index = 0;
int left = newCommands.size();
while (left--)
m_commands.insert(++commandIndex, newCommands.at(index++));
}
/*********************************************************************************
** run
**********************************************************************************/
void PaintCommands::runCommand(const QString &scriptLine)
{
static QRegularExpression separators("\\s");
if (scriptLine.isEmpty()) {
command_noop(QRegularExpressionMatch());
return;
}
if (scriptLine.startsWith('#')) {
command_comment(QRegularExpressionMatch());
return;
}
QString firstWord = scriptLine.section(separators, 0, 0);
const QList<int> indices = s_commandHash.values(firstWord);
for (int idx : indices) {
PaintCommandInfos command = s_commandInfoTable.at(idx);
Q_ASSERT(command.regExp.isValid());
QRegularExpressionMatch match = command.regExp.match(scriptLine);
if (match.hasMatch()) {
(this->*(command.paintMethod))(match);
return;
}
}
qWarning("ERROR: unknown command or argument syntax error in \"%s\"", qPrintable(scriptLine));
}
void PaintCommands::runCommands()
{
staticInit();
int width = m_painter->window().width();
int height = m_painter->window().height();
if (width <= 0)
width = 800;
if (height <= 0)
height = 800;
m_pathMap.clear();
m_imageMap.clear();
m_pixmapMap.clear();
m_regionMap.clear();
m_gradientStops.clear();
m_blockMap.clear();
// paint background
if (m_checkers_background) {
QPixmap pm(20, 20);
pm.fill(Qt::white);
QPainter pt(&pm);
pt.fillRect(0, 0, 10, 10, QColor::fromRgba(0xffdfdfdf));
pt.fillRect(10, 10, 10, 10, QColor::fromRgba(0xffdfdfdf));
pt.end();
m_painter->drawTiledPixmap(0, 0, width, height, pm);
} else {
m_painter->fillRect(0, 0, width, height, Qt::white);
}
// run each command
m_abort = false;
for (int i=0; i<m_commands.size() && !m_abort; ++i) {
const QString &commandNow = m_commands.at(i);
m_currentCommand = commandNow;
m_currentCommandIndex = i;
runCommand(commandNow.trimmed());
}
}
/*********************************************************************************
** conversions
**********************************************************************************/
int PaintCommands::convertToInt(const QString &str)
{
return qRound(convertToDouble(str));
}
float PaintCommands::convertToFloat(const QString &str)
{
return float(convertToDouble(str));
}
double PaintCommands::convertToDouble(const QString &str)
{
static QRegularExpression re("cp([0-9])([xy])");
if (str.toLower() == "width") {
if (m_painter->device()->devType() == Qt::Widget)
return m_painter->window().width();
else
return 800;
}
if (str.toLower() == "height") {
if (m_painter->device()->devType() == Qt::Widget)
return m_painter->window().height();
else
return 800;
}
QRegularExpressionMatch match = re.match(str);
if (match.hasMatch()) {
int index = match.captured(1).toInt();
bool is_it_x = match.captured(2) == "x";
if (index < 0 || index >= m_controlPoints.size()) {
qWarning("ERROR: control point index=%d is out of bounds", index);
return 0;
}
return is_it_x ? m_controlPoints.at(index).x() : m_controlPoints.at(index).y();
}
return str.toDouble();
}
QColor PaintCommands::convertToColor(const QString &str)
{
static QRegularExpression alphaColorRe("#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})");
static QRegularExpression opaqueColorRe("#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})");
Q_ASSERT(alphaColorRe.isValid());
Q_ASSERT(opaqueColorRe.isValid());
QRegularExpressionMatch alphaColor = alphaColorRe.match(str);
QRegularExpressionMatch opaqueColor = opaqueColorRe.match(str);
if (alphaColor.hasMatch()) {
return QColor(alphaColor.captured(2).toInt(0, 16),
alphaColor.captured(3).toInt(0, 16),
alphaColor.captured(4).toInt(0, 16),
alphaColor.captured(1).toInt(0, 16));
} else if (opaqueColor.hasMatch()) {
return QColor(opaqueColor.captured(1).toInt(0, 16),
opaqueColor.captured(2).toInt(0, 16),
opaqueColor.captured(3).toInt(0, 16));
}
return QColor(str);
}
/*********************************************************************************
** command implementations
**********************************************************************************/
void PaintCommands::command_comment(QRegularExpressionMatch)
{
if (m_verboseMode)
printf(" -(lance) comment: %s\n", qPrintable(m_currentCommand));
}
/***************************************************************************************************/
void PaintCommands::command_import(QRegularExpressionMatch re)
{
QString importFile(re.captured(1));
QFileInfo fi(m_filepath);
QDir dir = fi.absoluteDir();
QFile *file = new QFile(dir.absolutePath() + QDir::separator() + importFile);
if (importFile.isEmpty() || !file->exists()) {
dir.cdUp();
dir.cd("data");
dir.cd("qps");
delete file;
file = new QFile(dir.absolutePath() + QDir::separator() + importFile);
}
if (importFile.isEmpty() || !file->exists()) {
dir.cdUp();
dir.cd("images");
delete file;
file = new QFile(dir.absolutePath() + QDir::separator() + importFile);
}
if (importFile.isEmpty() || !file->exists()) {
printf(" - importing non-existing file at line %d (%s)\n", m_currentCommandIndex,
qPrintable(file->fileName()));
delete file;
return;
}
if (!file->open(QIODevice::ReadOnly)) {
printf(" - failed to read file: '%s'\n", qPrintable(file->fileName()));
delete file;
return;
}
if (m_verboseMode)
printf(" -(lance) importing file at line %d (%s)\n", m_currentCommandIndex,
qPrintable(fi.fileName()));
QFileInfo fileinfo(*file);
m_commands[m_currentCommandIndex] = QLatin1String("# import file (") + fileinfo.fileName()
+ QLatin1String(") start");
QString rawContent = QString::fromUtf8(file->readAll());
QStringList importedData = rawContent.split('\n', Qt::SkipEmptyParts);
importedData.append(QLatin1String("# import file (") + fileinfo.fileName() + QLatin1String(") end ---"));
insertAt(m_currentCommandIndex, importedData);
if (m_verboseMode) {
printf(" -(lance) Command buffer now looks like:\n");
for (int i = 0; i < m_commands.size(); ++i)
printf(" ---> {%s}\n", qPrintable(m_commands.at(i)));
}
delete file;
}
/***************************************************************************************************/
void PaintCommands::command_begin_block(QRegularExpressionMatch re)
{
const QString &blockName = re.captured(1);
if (m_verboseMode)
printf(" -(lance) begin_block (%s)\n", qPrintable(blockName));
if (m_blockMap.contains(blockName))
qFatal("Two blocks named (%s)", qPrintable(blockName));
m_commands[m_currentCommandIndex] = QLatin1String("# begin block (") + blockName + QLatin1Char(')');
QStringList newBlock;
int i = m_currentCommandIndex + 1;
for (; i < m_commands.size(); ++i) {
const QString &nextCmd = m_commands.at(i);
if (nextCmd.startsWith("end_block")) {
m_commands[i] = QLatin1String("# end block (") + blockName + QLatin1Char(')');
break;
}
newBlock += nextCmd;
}
if (m_verboseMode)
for (int j = 0; j < newBlock.size(); ++j)
printf(" %d: %s\n", j, qPrintable(newBlock.at(j)));
if (i >= m_commands.size())
printf(" - Warning! Block doesn't have an 'end_block' marker!\n");
m_blockMap.insert(blockName, newBlock);
}
/***************************************************************************************************/
void PaintCommands::command_end_block(QRegularExpressionMatch)
{
printf(" - end_block should be consumed by begin_block command.\n");
printf(" You will never see this if your block markers are in sync\n");
printf(" (noop)\n");
}
/***************************************************************************************************/
void PaintCommands::command_repeat_block(QRegularExpressionMatch re)
{
QString blockName = re.captured(1);
if (m_verboseMode)
printf(" -(lance) repeating block (%s)\n", qPrintable(blockName));
QStringList block = m_blockMap.value(blockName);
if (block.isEmpty()) {
printf(" - repeated block (%s) is empty!\n", qPrintable(blockName));
return;
}
m_commands[m_currentCommandIndex] = QLatin1String("# repeated block (") + blockName + QLatin1Char(')');
insertAt(m_currentCommandIndex, block);
}
/***************************************************************************************************/
void PaintCommands::command_drawLine(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x1 = convertToDouble(caps.at(1));
double y1 = convertToDouble(caps.at(2));
double x2 = convertToDouble(caps.at(3));
double y2 = convertToDouble(caps.at(4));
if (m_verboseMode)
printf(" -(lance) drawLine((%.2f, %.2f), (%.2f, %.2f))\n", x1, y1, x2, y2);
m_painter->drawLine(QLineF(x1, y1, x2, y2));
}
/***************************************************************************************************/
void PaintCommands::command_drawLines(QRegularExpressionMatch re)
{
static QRegularExpression separators("\\s");
QStringList numbers = re.captured(1).split(separators, Qt::SkipEmptyParts);
QList<QLineF> array;
for (int i = 0; i + 3 < numbers.size(); i += 4) {
QPointF pt1(numbers.at(i).toFloat(), numbers.at(i + 1).toFloat());
QPointF pt2(numbers.at(i + 2).toFloat(), numbers.at(i + 3).toFloat());
array.append(QLineF(pt1, pt2));
}
if (m_verboseMode)
printf(" -(lance) drawLines(size=%zd)\n", size_t(array.size()));
m_painter->drawLines(array);
}
/***************************************************************************************************/
void PaintCommands::command_drawPath(QRegularExpressionMatch re)
{
if (m_verboseMode)
printf(" -(lance) drawPath(name=%s)\n", qPrintable(re.captured(1)));
QPainterPath &path = m_pathMap[re.captured(1)];
m_painter->drawPath(path);
}
/***************************************************************************************************/
void PaintCommands::command_drawPixmap(QRegularExpressionMatch re)
{
QPixmap pm;
pm = m_pixmapMap[re.captured(1)]; // try cache first
if (pm.isNull())
pm = image_load<QPixmap>(re.captured(1));
if (pm.isNull()) {
QFileInfo fi(m_filepath);
QDir dir = fi.absoluteDir();
dir.cdUp();
dir.cd("images");
QString fileName = dir.absolutePath() + QLatin1Char('/') + re.captured(1);
pm = QPixmap(fileName);
if (pm.isNull() && !fileName.endsWith(".png")) {
fileName.append(".png");
pm = QPixmap(fileName);
}
}
if (pm.isNull()) {
fprintf(stderr, "ERROR(drawPixmap): failed to load pixmap: '%s'\n",
qPrintable(re.captured(1)));
return;
}
qreal tx = convertToFloat(re.captured(2));
qreal ty = convertToFloat(re.captured(3));
qreal tw = convertToFloat(re.captured(4));
qreal th = convertToFloat(re.captured(5));
qreal sx = convertToFloat(re.captured(6));
qreal sy = convertToFloat(re.captured(7));
qreal sw = convertToFloat(re.captured(8));
qreal sh = convertToFloat(re.captured(9));
if (tw == 0) tw = -1;
if (th == 0) th = -1;
if (sw == 0) sw = -1;
if (sh == 0) sh = -1;
if (m_verboseMode)
printf(" -(lance) drawPixmap('%s' dim=(%d, %d), depth=%d, (%f, %f, %f, %f), (%f, %f, %f, %f)\n",
qPrintable(re.captured(1)), pm.width(), pm.height(), pm.depth(),
tx, ty, tw, th, sx, sy, sw, sh);
if (!re.capturedLength(4)) // at most two coordinates specified
m_painter->drawPixmap(QPointF(tx, ty), pm);
else
m_painter->drawPixmap(QRectF(tx, ty, tw, th), pm, QRectF(sx, sy, sw, sh));
}
/***************************************************************************************************/
void PaintCommands::command_drawImage(QRegularExpressionMatch re)
{
QImage im;
im = m_imageMap[re.captured(1)]; // try cache first
if (im.isNull())
im = image_load<QImage>(re.captured(1));
if (im.isNull()) {
QFileInfo fi(m_filepath);
QDir dir = fi.absoluteDir();
dir.cdUp();
dir.cd("images");
QString fileName = dir.absolutePath() + QLatin1Char('/') + re.captured(1);
im = QImage(fileName);
if (im.isNull() && !fileName.endsWith(".png")) {
fileName.append(".png");
im = QImage(fileName);
}
}
if (im.isNull()) {
fprintf(stderr, "ERROR(drawImage): failed to load image: '%s'\n", qPrintable(re.captured(1)));
return;
}
qreal tx = convertToFloat(re.captured(2));
qreal ty = convertToFloat(re.captured(3));
qreal tw = convertToFloat(re.captured(4));
qreal th = convertToFloat(re.captured(5));
qreal sx = convertToFloat(re.captured(6));
qreal sy = convertToFloat(re.captured(7));
qreal sw = convertToFloat(re.captured(8));
qreal sh = convertToFloat(re.captured(9));
if (tw == 0) tw = -1;
if (th == 0) th = -1;
if (sw == 0) sw = -1;
if (sh == 0) sh = -1;
if (m_verboseMode)
printf(" -(lance) drawImage('%s' dim=(%d, %d), (%f, %f, %f, %f), (%f, %f, %f, %f)\n",
qPrintable(re.captured(1)), im.width(), im.height(), tx, ty, tw, th, sx, sy, sw, sh);
if (!re.capturedLength(4)) // at most two coordinates specified
m_painter->drawImage(QPointF(tx, ty), im);
else
m_painter->drawImage(QRectF(tx, ty, tw, th), im, QRectF(sx, sy, sw, sh));
}
/***************************************************************************************************/
void PaintCommands::command_drawTiledPixmap(QRegularExpressionMatch re)
{
QPixmap pm;
pm = m_pixmapMap[re.captured(1)]; // try cache first
if (pm.isNull())
pm = image_load<QPixmap>(re.captured(1));
if (pm.isNull()) {
QFileInfo fi(m_filepath);
QDir dir = fi.absoluteDir();
dir.cdUp();
dir.cd("images");
QString fileName = dir.absolutePath() + QLatin1Char('/') + re.captured(1);
pm = QPixmap(fileName);
if (pm.isNull() && !fileName.endsWith(".png")) {
fileName.append(".png");
pm = QPixmap(fileName);
}
}
if (pm.isNull()) {
fprintf(stderr, "ERROR(drawTiledPixmap): failed to load pixmap: '%s'\n",
qPrintable(re.captured(1)));
return;
}
int tx = convertToInt(re.captured(2));
int ty = convertToInt(re.captured(3));
int tw = convertToInt(re.captured(4));
int th = convertToInt(re.captured(5));
int sx = convertToInt(re.captured(6));
int sy = convertToInt(re.captured(7));
if (tw == 0) tw = -1;
if (th == 0) th = -1;
if (m_verboseMode)
printf(" -(lance) drawTiledPixmap('%s' dim=(%d, %d), (%d, %d, %d, %d), (%d, %d)\n",
qPrintable(re.captured(1)), pm.width(), pm.height(), tx, ty, tw, th, sx, sy);
m_painter->drawTiledPixmap(tx, ty, tw, th, pm, sx, sy);
}
/***************************************************************************************************/
void PaintCommands::command_drawPoint(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
float x = convertToFloat(caps.at(1));
float y = convertToFloat(caps.at(2));
if (m_verboseMode)
printf(" -(lance) drawPoint(%.2f, %.2f)\n", x, y);
m_painter->drawPoint(QPointF(x, y));
}
/***************************************************************************************************/
void PaintCommands::command_drawPolygon(QRegularExpressionMatch re)
{
static QRegularExpression separators("\\s");
QStringList caps = re.capturedTexts();
QString cap = caps.at(1);
QStringList numbers = cap.split(separators, Qt::SkipEmptyParts);
QPolygonF array;
for (int i=0; i + 1<numbers.size(); i+=2)
array.append(QPointF(convertToDouble(numbers.at(i)), convertToDouble(numbers.at(i+1))));
if (m_verboseMode)
printf(" -(lance) drawPolygon(size=%zd)\n", size_t(array.size()));
m_painter->drawPolygon(array, caps.at(2).toLower() == "winding" ? Qt::WindingFill : Qt::OddEvenFill);
}
/***************************************************************************************************/
void PaintCommands::command_drawPolyline(QRegularExpressionMatch re)
{
static QRegularExpression separators("\\s");
QStringList numbers = re.captured(1).split(separators, Qt::SkipEmptyParts);
QPolygonF array;
for (int i=0; i + 1<numbers.size(); i+=2)
array.append(QPointF(numbers.at(i).toFloat(),numbers.at(i+1).toFloat()));
if (m_verboseMode)
printf(" -(lance) drawPolyline(size=%zd)\n", size_t(array.size()));
m_painter->drawPolyline(array.toPolygon());
}
/***************************************************************************************************/
void PaintCommands::command_drawRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
float x = convertToFloat(caps.at(1));
float y = convertToFloat(caps.at(2));
float w = convertToFloat(caps.at(3));
float h = convertToFloat(caps.at(4));
if (m_verboseMode)
printf(" -(lance) drawRect(%.2f, %.2f, %.2f, %.2f)\n", x, y, w, h);
m_painter->drawRect(QRectF(x, y, w, h));
}
/***************************************************************************************************/
void PaintCommands::command_drawRoundedRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
float x = convertToFloat(caps.at(1));
float y = convertToFloat(caps.at(2));
float w = convertToFloat(caps.at(3));
float h = convertToFloat(caps.at(4));
float xr = convertToFloat(caps.at(5));
float yr = convertToFloat(caps.at(6));
int mode = translateEnum(sizeModeTable, caps.at(7), sizeof(sizeModeTable)/sizeof(char *));
if (mode < 0)
mode = Qt::AbsoluteSize;
if (m_verboseMode)
printf(" -(lance) drawRoundRect(%f, %f, %f, %f, %f, %f, %s)\n", x, y, w, h, xr, yr, mode ? "RelativeSize" : "AbsoluteSize");
m_painter->drawRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::SizeMode(mode));
}
/***************************************************************************************************/
void PaintCommands::command_drawRoundRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
int w = convertToInt(caps.at(3));
int h = convertToInt(caps.at(4));
int xs = caps.at(5).isEmpty() ? 50 : convertToInt(caps.at(5));
int ys = caps.at(6).isEmpty() ? 50 : convertToInt(caps.at(6));
if (m_verboseMode)
printf(" -(lance) drawRoundRect(%d, %d, %d, %d, [%d, %d])\n", x, y, w, h, xs, ys);
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
m_painter->drawRoundedRect(x, y, w, h, xs, ys, Qt::RelativeSize);
QT_WARNING_POP
}
/***************************************************************************************************/
void PaintCommands::command_drawEllipse(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
float x = convertToFloat(caps.at(1));
float y = convertToFloat(caps.at(2));
float w = convertToFloat(caps.at(3));
float h = convertToFloat(caps.at(4));
if (m_verboseMode)
printf(" -(lance) drawEllipse(%.2f, %.2f, %.2f, %.2f)\n", x, y, w, h);
m_painter->drawEllipse(QRectF(x, y, w, h));
}
/***************************************************************************************************/
void PaintCommands::command_drawPie(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
int w = convertToInt(caps.at(3));
int h = convertToInt(caps.at(4));
int angle = convertToInt(caps.at(5));
int sweep = convertToInt(caps.at(6));
if (m_verboseMode)
printf(" -(lance) drawPie(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
m_painter->drawPie(x, y, w, h, angle, sweep);
}
/***************************************************************************************************/
void PaintCommands::command_drawChord(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
int w = convertToInt(caps.at(3));
int h = convertToInt(caps.at(4));
int angle = convertToInt(caps.at(5));
int sweep = convertToInt(caps.at(6));
if (m_verboseMode)
printf(" -(lance) drawChord(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
m_painter->drawChord(x, y, w, h, angle, sweep);
}
/***************************************************************************************************/
void PaintCommands::command_drawArc(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
int w = convertToInt(caps.at(3));
int h = convertToInt(caps.at(4));
int angle = convertToInt(caps.at(5));
int sweep = convertToInt(caps.at(6));
if (m_verboseMode)
printf(" -(lance) drawArc(%d, %d, %d, %d, %d, %d)\n", x, y, w, h, angle, sweep);
m_painter->drawArc(x, y, w, h, angle, sweep);
}
/***************************************************************************************************/
void PaintCommands::command_drawText(QRegularExpressionMatch re)
{
if (!m_shouldDrawText)
return;
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
QString txt = caps.at(3);
if (m_verboseMode)
printf(" -(lance) drawText(%d, %d, %s)\n", x, y, qPrintable(txt));
m_painter->drawText(x, y, txt);
}
void PaintCommands::command_drawStaticText(QRegularExpressionMatch re)
{
if (!m_shouldDrawText)
return;
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
QString txt = caps.at(3);
if (m_verboseMode)
printf(" -(lance) drawStaticText(%d, %d, %s)\n", x, y, qPrintable(txt));
m_painter->drawStaticText(x, y, QStaticText(txt));
}
void PaintCommands::command_drawGlyphRun(QRegularExpressionMatch re)
{
if (!m_shouldDrawText)
return;
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
QString txt = caps.at(3);
if (m_verboseMode)
printf(" -(lance) drawGlyphRun(%d, %d, %s)\n", x, y, qPrintable(txt));
QTextLayout layout;
layout.setFont(m_painter->font());
layout.setText(txt);
layout.beginLayout();
qreal lineY = 0.0;
forever {
QTextLine line = layout.createLine();
if (!line.isValid())
break;
line.setPosition(QPointF(0.0, lineY));
lineY += line.height();
}
layout.endLayout();
QList<QGlyphRun> glyphRuns = layout.glyphRuns();
for (const QGlyphRun &glyphRun : glyphRuns)
m_painter->drawGlyphRun(QPointF(x, y), glyphRun);
}
void PaintCommands::command_drawTextDocument(QRegularExpressionMatch re)
{
if (!m_shouldDrawText)
return;
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
QString txt = caps.at(3);
if (m_verboseMode)
printf(" -(lance) drawTextDocument(%d, %d, %s)\n", x, y, qPrintable(txt));
QTextDocument doc;
doc.setBaseUrl(QUrl::fromLocalFile(QDir::currentPath() + QLatin1String("/")));
doc.setHtml(txt);
m_painter->save();
m_painter->translate(x, y);
doc.drawContents(m_painter);
m_painter->restore();
}
/***************************************************************************************************/
void PaintCommands::command_fillRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
int w = convertToInt(caps.at(3));
int h = convertToInt(caps.at(4));
if (!caps.at(5).isEmpty()) {
QColor color = convertToColor(caps.at(5));
if (m_verboseMode)
printf(" -(lance) fillRect(%d, %d, %d, %d, %s)\n", x, y, w, h, qPrintable(color.name()));
m_painter->fillRect(x, y, w, h, color);
} else {
if (m_verboseMode)
printf(" -(lance) fillRect(%d, %d, %d, %d)\n", x, y, w, h);
m_painter->fillRect(x, y, w, h, m_painter->brush());
}
}
void PaintCommands::command_fillRectF(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x = convertToDouble(caps.at(1));
double y = convertToDouble(caps.at(2));
double w = convertToDouble(caps.at(3));
double h = convertToDouble(caps.at(4));
if (!caps.at(5).isEmpty()) {
QColor color = convertToColor(caps.at(5));
if (m_verboseMode)
printf(" -(lance) fillRectF(%.2f, %.2f, %.2f, %.2f, %s)\n", x, y, w, h, qPrintable(color.name()));
m_painter->fillRect(QRectF(x, y, w, h), color);
} else {
if (m_verboseMode)
printf(" -(lance) fillRectF(%.2f, %.2f, %.2f, %.2f)\n", x, y, w, h);
m_painter->fillRect(QRectF(x, y, w, h), m_painter->brush());
}
}
void PaintCommands::command_drawPixmapFragments(QRegularExpressionMatch re)
{
QPixmap pm;
pm = m_pixmapMap[re.captured(1)]; // try cache first
if (pm.isNull())
pm = image_load<QPixmap>(re.captured(1));
if (pm.isNull()) {
QFileInfo fi(m_filepath);
QDir dir = fi.absoluteDir();
dir.cdUp();
dir.cd("images");
QString fileName = dir.absolutePath() + QLatin1Char('/') + re.captured(1);
pm = QPixmap(fileName);
if (pm.isNull() && !fileName.endsWith(".png")) {
fileName.append(".png");
pm = QPixmap(fileName);
}
}
if (pm.isNull()) {
fprintf(stderr, "ERROR(drawPixmapFragments): failed to load pixmap: '%s'\n",
qPrintable(re.captured(1)));
return;
}
int count = convertToInt(re.captured(2));
struct Fragment {
double posx;
double posy;
double srcx;
double srcy;
double srcw;
double srch;
double sx;
double sy;
double rotation;
double opacity;
};
QList<Fragment> fragments;
for (int i = 0; i < count; ++i) {
int captureIndexStart = 3 + i * 10;
if (re.hasCaptured(captureIndexStart)) {
Fragment f;
f.posx = convertToDouble(re.captured(captureIndexStart));
f.posy = convertToDouble(re.captured(captureIndexStart + 1));
f.srcx = convertToDouble(re.captured(captureIndexStart + 2));
f.srcy = convertToDouble(re.captured(captureIndexStart + 3));
f.srcw = convertToDouble(re.captured(captureIndexStart + 4));
f.srch = convertToDouble(re.captured(captureIndexStart + 5));
f.sx = convertToDouble(re.captured(captureIndexStart + 6));
f.sy = convertToDouble(re.captured(captureIndexStart + 7));
f.rotation = convertToDouble(re.captured(captureIndexStart + 8));
f.opacity = convertToDouble(re.captured(captureIndexStart + 9));
fragments.append(f);
} else {
break;
}
}
if (m_verboseMode) {
printf(" -(lance) drawPixmapFragments('%s' count=%d ",
qPrintable(re.captured(1)), int(fragments.count()));
for (int i = 0; i < fragments.count(); ++i) {
printf("pos=(%.2f, %.2f) srcrect=(%.2f %.2f %.2f %.2f) scale=(%.2f %.2f) rotation=%.2f opacity=%.2f ",
fragments[i].posx, fragments[i].posy,
fragments[i].srcx, fragments[i].srcy, fragments[i].srcw, fragments[i].srch,
fragments[i].sx, fragments[i].sy,
fragments[i].rotation,
fragments[i].opacity);
}
printf("\n");
}
QList<QPainter::PixmapFragment> pixmapFragments;
for (int i = 0; i < fragments.count(); ++i) {
pixmapFragments.append(
QPainter::PixmapFragment::create(QPointF(fragments[i].posx, fragments[i].posy),
QRectF(fragments[i].srcx, fragments[i].srcy, fragments[i].srcw, fragments[i].srch),
fragments[i].sx, fragments[i].sy,
fragments[i].rotation,
fragments[i].opacity));
}
m_painter->drawPixmapFragments(pixmapFragments.constData(), pixmapFragments.count(), pm);
}
/***************************************************************************************************/
void PaintCommands::command_noop(QRegularExpressionMatch)
{
if (m_verboseMode)
printf(" -(lance) noop: %s\n", qPrintable(m_currentCommand));
if (!m_currentCommand.trimmed().isEmpty()) {
fprintf(stderr, "unknown command: '%s'\n", qPrintable(m_currentCommand.trimmed()));
}
}
/***************************************************************************************************/
void PaintCommands::command_path_addText(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x = convertToDouble(caps.at(2));
double y = convertToDouble(caps.at(3));
QString text = caps.at(4);
if (m_verboseMode)
printf(" -(lance) path_addText(%s, %.2f, %.2f, text=%s\n", qPrintable(name), x, y, qPrintable(text));
m_pathMap[name].addText(x, y, m_painter->font(), text);
}
/***************************************************************************************************/
void PaintCommands::command_path_addEllipse(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x = convertToDouble(caps.at(2));
double y = convertToDouble(caps.at(3));
double w = convertToDouble(caps.at(4));
double h = convertToDouble(caps.at(5));
if (m_verboseMode)
printf(" -(lance) path_addEllipse(%s, %.2f, %.2f, %.2f, %.2f)\n", qPrintable(name), x, y, w, h);
m_pathMap[name].addEllipse(x, y, w, h);
}
/***************************************************************************************************/
void PaintCommands::command_path_addRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x = convertToDouble(caps.at(2));
double y = convertToDouble(caps.at(3));
double w = convertToDouble(caps.at(4));
double h = convertToDouble(caps.at(5));
if (m_verboseMode)
printf(" -(lance) path_addRect(%s, %.2f, %.2f, %.2f, %.2f)\n", qPrintable(name), x, y, w, h);
m_pathMap[name].addRect(x, y, w, h);
}
/***************************************************************************************************/
void PaintCommands::command_path_addPolygon(QRegularExpressionMatch re)
{
static QRegularExpression separators("\\s");
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
QString cap = caps.at(2);
QStringList numbers = cap.split(separators, Qt::SkipEmptyParts);
QPolygonF array;
for (int i=0; i + 1<numbers.size(); i+=2)
array.append(QPointF(numbers.at(i).toFloat(),numbers.at(i+1).toFloat()));
if (m_verboseMode)
printf(" -(lance) path_addPolygon(name=%s, size=%zd)\n", qPrintable(name), size_t(array.size()));
m_pathMap[name].addPolygon(array);
}
/***************************************************************************************************/
void PaintCommands::command_path_arcTo(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x = convertToDouble(caps.at(2));
double y = convertToDouble(caps.at(3));
double w = convertToDouble(caps.at(4));
double h = convertToDouble(caps.at(5));
double angle = convertToDouble(caps.at(6));
double length = convertToDouble(caps.at(7));
if (m_verboseMode)
printf(" -(lance) path_arcTo(%s, %.2f, %.2f, %.2f, %.2f, angle=%.2f, len=%.2f)\n", qPrintable(name), x, y, w, h, angle, length);
m_pathMap[name].arcTo(x, y, w, h, angle, length);
}
/***************************************************************************************************/
void PaintCommands::command_path_createOutline(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
QString newName = caps.at(2);
QPen pen = m_painter->pen();
if (m_verboseMode)
printf(" -(lance) path_createOutline(%s, name=%s, width=%d)\n",
qPrintable(name), qPrintable(newName), pen.width());
if (!m_pathMap.contains(name)) {
fprintf(stderr, "createOutline(), unknown path: %s\n", qPrintable(name));
return;
}
QPainterPathStroker stroker;
stroker.setWidth(pen.widthF());
stroker.setDashPattern(pen.style());
stroker.setCapStyle(pen.capStyle());
stroker.setJoinStyle(pen.joinStyle());
m_pathMap[newName] = stroker.createStroke(m_pathMap[name]);
}
/***************************************************************************************************/
void PaintCommands::command_path_cubicTo(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x1 = convertToDouble(caps.at(2));
double y1 = convertToDouble(caps.at(3));
double x2 = convertToDouble(caps.at(4));
double y2 = convertToDouble(caps.at(5));
double x3 = convertToDouble(caps.at(6));
double y3 = convertToDouble(caps.at(7));
if (m_verboseMode)
printf(" -(lance) path_cubicTo(%s, (%.2f, %.2f), (%.2f, %.2f), (%.2f, %.2f))\n", qPrintable(name), x1, y1, x2, y2, x3, y3);
m_pathMap[name].cubicTo(x1, y1, x2, y2, x3, y3);
}
/***************************************************************************************************/
void PaintCommands::command_path_moveTo(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x1 = convertToDouble(caps.at(2));
double y1 = convertToDouble(caps.at(3));
if (m_verboseMode)
printf(" -(lance) path_moveTo(%s, (%.2f, %.2f))\n", qPrintable(name), x1, y1);
m_pathMap[name].moveTo(x1, y1);
}
/***************************************************************************************************/
void PaintCommands::command_path_lineTo(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double x1 = convertToDouble(caps.at(2));
double y1 = convertToDouble(caps.at(3));
if (m_verboseMode)
printf(" -(lance) path_lineTo(%s, (%.2f, %.2f))\n", qPrintable(name), x1, y1);
m_pathMap[name].lineTo(x1, y1);
}
/***************************************************************************************************/
void PaintCommands::command_path_setFillRule(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
bool winding = caps.at(2).toLower() == "winding";
if (m_verboseMode)
printf(" -(lance) path_setFillRule(name=%s, winding=%d)\n", qPrintable(name), winding);
m_pathMap[name].setFillRule(winding ? Qt::WindingFill : Qt::OddEvenFill);
}
/***************************************************************************************************/
void PaintCommands::command_path_closeSubpath(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
if (m_verboseMode)
printf(" -(lance) path_closeSubpath(name=%s)\n", qPrintable(name));
m_pathMap[name].closeSubpath();
}
/***************************************************************************************************/
void PaintCommands::command_path_getClipPath(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
if (m_verboseMode)
printf(" -(lance) path_closeSubpath(name=%s)\n", qPrintable(name));
m_pathMap[name] = m_painter->clipPath();
}
/***************************************************************************************************/
static void qt_debug_path(const QPainterPath &path, const QString &name)
{
const char *names[] = {
"MoveTo ",
"LineTo ",
"CurveTo ",
"CurveToData"
};
printf("\nQPainterPath (%s): elementCount=%d\n", qPrintable(name), path.elementCount());
for (int i=0; i<path.elementCount(); ++i) {
const QPainterPath::Element &e = path.elementAt(i);
Q_ASSERT(e.type >= 0 && e.type <= QPainterPath::CurveToDataElement);
printf(" - %3d:: %s, (%.2f, %.2f)\n", i, names[e.type], e.x, e.y);
}
}
/***************************************************************************************************/
void PaintCommands::command_path_debugPrint(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
qt_debug_path(m_pathMap[name], name);
}
/***************************************************************************************************/
void PaintCommands::command_region_addRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
int x = convertToInt(caps.at(2));
int y = convertToInt(caps.at(3));
int w = convertToInt(caps.at(4));
int h = convertToInt(caps.at(5));
if (m_verboseMode)
printf(" -(lance) region_addRect(%s, %d, %d, %d, %d)\n", qPrintable(name), x, y, w, h);
m_regionMap[name] += QRect(x, y, w, h);
}
/***************************************************************************************************/
void PaintCommands::command_region_addEllipse(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
int x = convertToInt(caps.at(2));
int y = convertToInt(caps.at(3));
int w = convertToInt(caps.at(4));
int h = convertToInt(caps.at(5));
if (m_verboseMode)
printf(" -(lance) region_addEllipse(%s, %d, %d, %d, %d)\n", qPrintable(name), x, y, w, h);
m_regionMap[name] += QRegion(x, y, w, h, QRegion::Ellipse);
}
/***************************************************************************************************/
void PaintCommands::command_region_getClipRegion(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
QRegion region = m_painter->clipRegion();
if (m_verboseMode)
printf(" -(lance) region_getClipRegion(name=%s), bounds=[%d, %d, %d, %d]\n", qPrintable(name),
region.boundingRect().x(),
region.boundingRect().y(),
region.boundingRect().width(),
region.boundingRect().height());
m_regionMap[name] = region;
}
/***************************************************************************************************/
void PaintCommands::command_resetMatrix(QRegularExpressionMatch)
{
if (m_verboseMode)
printf(" -(lance) resetMatrix()\n");
m_painter->resetTransform();
}
/***************************************************************************************************/
void PaintCommands::command_restore(QRegularExpressionMatch)
{
if (m_verboseMode)
printf(" -(lance) restore()\n");
m_painter->restore();
}
/***************************************************************************************************/
void PaintCommands::command_rotate(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double angle = convertToDouble(caps.at(1));
if (m_verboseMode)
printf(" -(lance) rotate(%.2f)\n", angle);
m_painter->rotate(angle);
}
/***************************************************************************************************/
void PaintCommands::command_rotate_x(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double angle = convertToDouble(caps.at(1));
if (m_verboseMode)
printf(" -(lance) rotate_x(%.2f)\n", angle);
QTransform transform;
transform.rotate(angle, Qt::XAxis);
m_painter->setTransform(transform, true);
}
/***************************************************************************************************/
void PaintCommands::command_rotate_y(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double angle = convertToDouble(caps.at(1));
if (m_verboseMode)
printf(" -(lance) rotate_y(%.2f)\n", angle);
QTransform transform;
transform.rotate(angle, Qt::YAxis);
m_painter->setTransform(transform, true);
}
/***************************************************************************************************/
void PaintCommands::command_save(QRegularExpressionMatch)
{
if (m_verboseMode)
printf(" -(lance) save()\n");
m_painter->save();
}
/***************************************************************************************************/
void PaintCommands::command_mapQuadToQuad(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x1 = convertToDouble(caps.at(1));
double y1 = convertToDouble(caps.at(2));
double x2 = convertToDouble(caps.at(3));
double y2 = convertToDouble(caps.at(4));
double x3 = convertToDouble(caps.at(5));
double y3 = convertToDouble(caps.at(6));
double x4 = convertToDouble(caps.at(7));
double y4 = convertToDouble(caps.at(8));
QPolygonF poly1(4);
poly1[0] = QPointF(x1, y1);
poly1[1] = QPointF(x2, y2);
poly1[2] = QPointF(x3, y3);
poly1[3] = QPointF(x4, y4);
double x5 = convertToDouble(caps.at(9));
double y5 = convertToDouble(caps.at(10));
double x6 = convertToDouble(caps.at(11));
double y6 = convertToDouble(caps.at(12));
double x7 = convertToDouble(caps.at(13));
double y7 = convertToDouble(caps.at(14));
double x8 = convertToDouble(caps.at(15));
double y8 = convertToDouble(caps.at(16));
QPolygonF poly2(4);
poly2[0] = QPointF(x5, y5);
poly2[1] = QPointF(x6, y6);
poly2[2] = QPointF(x7, y7);
poly2[3] = QPointF(x8, y8);
if (m_verboseMode)
printf(" -(lance) mapQuadToQuad(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ->\n\t"
",%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8);
QTransform trans;
if (!QTransform::quadToQuad(poly1, poly2, trans)) {
qWarning("Couldn't perform quad to quad transformation!");
}
m_painter->setTransform(trans, true);
}
/***************************************************************************************************/
void PaintCommands::command_setMatrix(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double m11 = convertToDouble(caps.at(1));
double m12 = convertToDouble(caps.at(2));
double m13 = convertToDouble(caps.at(3));
double m21 = convertToDouble(caps.at(4));
double m22 = convertToDouble(caps.at(5));
double m23 = convertToDouble(caps.at(6));
double m31 = convertToDouble(caps.at(7));
double m32 = convertToDouble(caps.at(8));
double m33 = convertToDouble(caps.at(9));
if (m_verboseMode)
printf(" -(lance) setMatrix(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
m11, m12, m13, m21, m22, m23, m31, m32, m33);
QTransform trans;
trans.setMatrix(m11, m12, m13,
m21, m22, m23,
m31, m32, m33);
m_painter->setTransform(trans, true);
}
/***************************************************************************************************/
void PaintCommands::command_scale(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double sx = convertToDouble(caps.at(1));
double sy = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) scale(%.2f, %.2f)\n", sx, sy);
m_painter->scale(sx, sy);
}
/***************************************************************************************************/
void PaintCommands::command_setBackground(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QColor color = convertToColor(caps.at(1));
QString pattern = caps.at(2);
int style = translateEnum(brushStyleTable, pattern, Qt::LinearGradientPattern);
if (style < 0)
style = Qt::SolidPattern;
if (m_verboseMode)
printf(" -(lance) setBackground(%s, %s)\n", qPrintable(color.name()), qPrintable(pattern));
m_painter->setBackground(QBrush(color, Qt::BrushStyle(style)));
}
/***************************************************************************************************/
void PaintCommands::command_setOpacity(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double opacity = convertToDouble(caps.at(1));
if (m_verboseMode)
printf(" -(lance) setOpacity(%lf)\n", opacity);
m_painter->setOpacity(opacity);
}
/***************************************************************************************************/
void PaintCommands::command_setBgMode(QRegularExpressionMatch re)
{
QString cap = re.captured(2);
Qt::BGMode mode = Qt::TransparentMode;
if (cap.toLower() == QLatin1String("opaquemode") || cap.toLower() == QLatin1String("opaque"))
mode = Qt::OpaqueMode;
if (m_verboseMode)
printf(" -(lance) setBackgroundMode(%s)\n", mode == Qt::OpaqueMode ? "OpaqueMode" : "TransparentMode");
m_painter->setBackgroundMode(mode);
}
/***************************************************************************************************/
void PaintCommands::command_setBrush(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QImage img = m_imageMap[caps.at(1)]; // try cache first
if (img.isNull())
img = image_load<QImage>(caps.at(1));
if (!img.isNull()) { // Assume image brush
if (m_verboseMode)
printf(" -(lance) setBrush(image=%s, width=%d, height=%d)\n",
qPrintable(caps.at(1)), img.width(), img.height());
m_painter->setBrush(QBrush(img));
} else if (caps.at(1).toLower() == "nobrush") {
m_painter->setBrush(Qt::NoBrush);
if (m_verboseMode)
printf(" -(lance) setBrush(Qt::NoBrush)\n");
} else {
QColor color = convertToColor(caps.at(1));
QString pattern = caps.at(2);
int style = translateEnum(brushStyleTable, pattern, Qt::LinearGradientPattern);
if (style < 0)
style = Qt::SolidPattern;
if (m_verboseMode)
printf(" -(lance) setBrush(%s, %s (%d))\n", qPrintable(color.name()), qPrintable(pattern), style);
m_painter->setBrush(QBrush(color, Qt::BrushStyle(style)));
}
}
/***************************************************************************************************/
void PaintCommands::command_setBrushOrigin(QRegularExpressionMatch re)
{
int x = convertToInt(re.captured(1));
int y = convertToInt(re.captured(2));
if (m_verboseMode)
printf(" -(lance) setBrushOrigin(%d, %d)\n", x, y);
m_painter->setBrushOrigin(x, y);
}
/***************************************************************************************************/
void PaintCommands::command_brushTranslate(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double dx = convertToDouble(caps.at(1));
double dy = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) brushTranslate(%f, %f)\n", dx, dy);
QBrush new_brush = m_painter->brush();
QTransform brush_matrix = new_brush.transform();
brush_matrix.translate(dx, dy);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
}
/***************************************************************************************************/
void PaintCommands::command_brushScale(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double sx = convertToDouble(caps.at(1));
double sy = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) brushScale(%f, %f)\n", sx, sy);
QBrush new_brush = m_painter->brush();
QTransform brush_matrix = new_brush.transform();
brush_matrix.scale(sx, sy);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
}
/***************************************************************************************************/
void PaintCommands::command_brushRotate(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double rot = convertToDouble(caps.at(1));
if (m_verboseMode)
printf(" -(lance) brushScale(%f)\n", rot);
QBrush new_brush = m_painter->brush();
QTransform brush_matrix = new_brush.transform();
brush_matrix.rotate(rot);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
}
/***************************************************************************************************/
void PaintCommands::command_brushShear(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double sx = convertToDouble(caps.at(1));
double sy = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) brushShear(%f, %f)\n", sx, sy);
QBrush new_brush = m_painter->brush();
QTransform brush_matrix = new_brush.transform();
brush_matrix.shear(sx, sy);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
}
/***************************************************************************************************/
void PaintCommands::command_setClipping(QRegularExpressionMatch re)
{
bool clipping = re.captured(1).toLower() == "true";
if (m_verboseMode)
printf(" -(lance) setClipping(%d)\n", clipping);
m_painter->setClipping(clipping);
}
/***************************************************************************************************/
void PaintCommands::command_setClipRect(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
int x = convertToInt(caps.at(1));
int y = convertToInt(caps.at(2));
int w = convertToInt(caps.at(3));
int h = convertToInt(caps.at(4));
int combine = translateEnum(clipOperationTable, caps.at(5), Qt::IntersectClip + 1);
if (combine == -1)
combine = Qt::ReplaceClip;
if (m_verboseMode)
printf(" -(lance) setClipRect(%d, %d, %d, %d), %s\n", x, y, w, h, clipOperationTable[combine]);
m_painter->setClipRect(x, y, w, h, Qt::ClipOperation(combine));
}
/***************************************************************************************************/
void PaintCommands::command_setClipRectF(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x = convertToDouble(caps.at(1));
double y = convertToDouble(caps.at(2));
double w = convertToDouble(caps.at(3));
double h = convertToDouble(caps.at(4));
int combine = translateEnum(clipOperationTable, caps.at(5), Qt::IntersectClip + 1);
if (combine == -1)
combine = Qt::ReplaceClip;
if (m_verboseMode)
printf(" -(lance) setClipRectF(%f, %f, %f, %f), %s\n", x, y, w, h, clipOperationTable[combine]);
m_painter->setClipRect(QRectF(x, y, w, h), Qt::ClipOperation(combine));
}
/***************************************************************************************************/
void PaintCommands::command_setClipPath(QRegularExpressionMatch re)
{
int combine = translateEnum(clipOperationTable, re.captured(2), Qt::IntersectClip + 1);
if (combine == -1)
combine = Qt::ReplaceClip;
if (m_verboseMode)
printf(" -(lance) setClipPath(name=%s), %s\n", qPrintable(re.captured(1)), clipOperationTable[combine]);
if (!m_pathMap.contains(re.captured(1)))
fprintf(stderr, " - setClipPath, no such path");
m_painter->setClipPath(m_pathMap[re.captured(1)], Qt::ClipOperation(combine));
}
/***************************************************************************************************/
void PaintCommands::command_setClipRegion(QRegularExpressionMatch re)
{
int combine = translateEnum(clipOperationTable, re.captured(2), Qt::IntersectClip + 1);
if (combine == -1)
combine = Qt::ReplaceClip;
QRegion r = m_regionMap[re.captured(1)];
if (m_verboseMode)
printf(" -(lance) setClipRegion(name=%s), bounds=[%d, %d, %d, %d], %s\n",
qPrintable(re.captured(1)),
r.boundingRect().x(),
r.boundingRect().y(),
r.boundingRect().width(),
r.boundingRect().height(),
clipOperationTable[combine]);
m_painter->setClipRegion(m_regionMap[re.captured(1)], Qt::ClipOperation(combine));
}
/***************************************************************************************************/
void PaintCommands::command_setFont(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString family = caps.at(1);
int size = -1; // Default
QString sizeArg = caps.at(2);
if (!sizeArg.isEmpty())
size = convertToInt(caps.at(2));
int weight = -1; // Default
QString weightArg = caps.at(3);
if (!weightArg.isEmpty()) {
weight = translateEnum(fontWeightTable, weightArg.toLower(), 5);
if (weight != -1) {
switch (weight) {
case 0: weight = QFont::Light; break;
case 1: weight = QFont::Normal; break;
case 2: weight = QFont::DemiBold; break;
case 3: weight = QFont::Bold; break;
case 4: weight = QFont::Black; break;
}
} else {
weight = convertToInt(weightArg);
}
}
bool italic = caps.at(4).toLower() == "true" || caps.at(4).toLower() == "italic";
QFont font(family, size, weight, italic);
int hinting = translateEnum(fontHintingTable, caps.at(5), 4);
if (hinting == -1)
hinting = 0;
else
font.setHintingPreference(QFont::HintingPreference(hinting));
bool underline = caps.at(6).toLower() == "true" || caps.at(6).toLower() == "underline";
bool strikeOut = caps.at(7).toLower() == "true" || caps.at(7).toLower() == "strikeout";
bool overline = caps.at(8).toLower() == "true" || caps.at(8).toLower() == "overline";
font.setUnderline(underline);
font.setStrikeOut(strikeOut);
font.setOverline(overline);
int capitalization = translateEnum(fontCapitalizationTable, caps.at(9), 5);
if (capitalization == -1)
capitalization = 0;
else
font.setCapitalization(QFont::Capitalization(capitalization));
if (m_verboseMode)
printf(" -(lance) setFont(family=%s, size=%d, weight=%d, italic=%d hinting=%s\n",
qPrintable(family), size, weight, italic, fontHintingTable[hinting]);
m_painter->setFont(font);
}
/***************************************************************************************************/
void PaintCommands::command_setPen(QRegularExpressionMatch re)
{
QString cap = re.captured(1);
int style = translateEnum(penStyleTable, cap, Qt::DashDotDotLine + 1);
if (style >= 0) {
if (m_verboseMode)
printf(" -(lance) setPen(%s)\n", qPrintable(cap));
m_painter->setPen(Qt::PenStyle(style));
} else if (cap.toLower() == "brush") {
QPen pen(m_painter->brush(), 0);
if (m_verboseMode) {
printf(" -(lance) setPen(brush), style=%d, color=%08x\n",
pen.brush().style(), pen.color().rgba());
}
m_painter->setPen(pen);
} else {
QColor color = convertToColor(cap);
if (m_verboseMode)
printf(" -(lance) setPen(%s)\n", qPrintable(color.name()));
m_painter->setPen(color);
}
}
/***************************************************************************************************/
void PaintCommands::command_setPen2(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QBrush brush;
if (caps.at(1).toLower() == "brush")
brush = m_painter->brush();
else
brush = convertToColor(caps.at(1));
double width = convertToDouble(caps.at(2));
int penStyle = translateEnum(penStyleTable, caps.at(3), Qt::DashDotDotLine + 1);
if (penStyle < 0)
penStyle = Qt::SolidLine;
Qt::PenCapStyle capStyle = Qt::SquareCap;
if (caps.at(4).toLower() == "flatcap") capStyle = Qt::FlatCap;
else if (caps.at(4).toLower() == "squarecap") capStyle = Qt::SquareCap;
else if (caps.at(4).toLower() == "roundcap") capStyle = Qt::RoundCap;
else if (!caps.at(4).isEmpty())
fprintf(stderr, "ERROR: setPen, unknown capStyle: %s\n", qPrintable(caps.at(4)));
Qt::PenJoinStyle joinStyle = Qt::BevelJoin;
if (caps.at(5).toLower() == "miterjoin") joinStyle = Qt::MiterJoin;
else if (caps.at(5).toLower() == "beveljoin") joinStyle = Qt::BevelJoin;
else if (caps.at(5).toLower() == "roundjoin") joinStyle = Qt::RoundJoin;
else if (!caps.at(5).isEmpty())
fprintf(stderr, "ERROR: setPen, unknown joinStyle: %s\n", qPrintable(caps.at(5)));
if (m_verboseMode)
printf(" -(lance) setPen(%s, width=%f, style=%d, cap=%d, join=%d)\n",
qPrintable(brush.color().name()), width, penStyle, capStyle, joinStyle);
m_painter->setPen(QPen(brush, width, Qt::PenStyle(penStyle), capStyle, joinStyle));
}
/***************************************************************************************************/
void PaintCommands::command_setRenderHint(QRegularExpressionMatch re)
{
QString hintString = re.captured(1).toLower();
QString setting = re.captured(2).toLower();
bool on = setting.isEmpty() || setting == "true" || setting == "on";
QPainter::RenderHint hint;
int hintIdx = -1;
if (hintString.contains("antialiasing")) {
hintIdx = 0;
hint = QPainter::Antialiasing;
} else if (hintString.contains("smoothpixmaptransform")) {
hintIdx = 1;
hint = QPainter::SmoothPixmapTransform;
} else if (hintString.contains("noncosmeticbrushpatterns")) {
hintIdx = 2;
hint = QPainter::NonCosmeticBrushPatterns;
}
if (hintIdx >= 0) {
if (m_verboseMode)
printf(" -(lance) setRenderHint %s %s\n", renderHintTable[hintIdx], on ? "true" : "false");
m_painter->setRenderHint(hint, on);
} else {
fprintf(stderr, "ERROR(setRenderHint): unknown hint '%s'\n", qPrintable(re.captured(1)));
}
}
/***************************************************************************************************/
void PaintCommands::command_clearRenderHint(QRegularExpressionMatch /*re*/)
{
m_painter->setRenderHint(QPainter::Antialiasing, false);
m_painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
m_painter->setRenderHint(QPainter::NonCosmeticBrushPatterns, false);
if (m_verboseMode)
printf(" -(lance) clearRenderHint\n");
}
/***************************************************************************************************/
void PaintCommands::command_setCompositionMode(QRegularExpressionMatch re)
{
QString modeString = re.captured(1).toLower();
int mode = translateEnum(compositionModeTable, modeString, 33);
if (mode < 0 || mode > QPainter::RasterOp_SourceAndNotDestination) {
fprintf(stderr, "ERROR: invalid mode: %s\n", qPrintable(modeString));
return;
}
if (m_verboseMode)
printf(" -(lance) setCompositionMode: %d: %s\n", mode, qPrintable(modeString));
m_painter->setCompositionMode(QPainter::CompositionMode(mode));
}
/***************************************************************************************************/
void PaintCommands::command_translate(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double dx = convertToDouble(caps.at(1));
double dy = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) translate(%f, %f)\n", dx, dy);
m_painter->translate(dx, dy);
}
/***************************************************************************************************/
void PaintCommands::command_pixmap_load(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString fileName = caps.at(1);
QString name = caps.at(2);
if (name.isEmpty())
name = fileName;
QImage im = image_load<QImage>(fileName);
QPixmap px = QPixmap::fromImage(im, Qt::OrderedDither | Qt::OrderedAlphaDither);
if (m_verboseMode)
printf(" -(lance) pixmap_load(%s as %s), size=[%d, %d], depth=%d\n",
qPrintable(fileName), qPrintable(name),
px.width(), px.height(), px.depth());
m_pixmapMap[name] = px;
}
/***************************************************************************************************/
void PaintCommands::command_bitmap_load(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString fileName = caps.at(1);
QString name = caps.at(2);
if (name.isEmpty())
name = fileName;
QBitmap bm = image_load<QBitmap>(fileName);
if (m_verboseMode)
printf(" -(lance) bitmap_load(%s as %s), size=[%d, %d], depth=%d\n",
qPrintable(fileName), qPrintable(name),
bm.width(), bm.height(), bm.depth());
m_pixmapMap[name] = bm;
}
void PaintCommands::command_pixmap_setDevicePixelRatio(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double dpr = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) pixmap_setDevicePixelRatio(%s), %.1f -> %.1f\n",
qPrintable(name), m_pixmapMap[name].devicePixelRatio(), dpr);
m_pixmapMap[name].setDevicePixelRatio(dpr);
}
/***************************************************************************************************/
void PaintCommands::command_pixmap_setMask(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QBitmap mask = image_load<QBitmap>(caps.at(2));
if (m_verboseMode)
printf(" -(lance) pixmap_setMask(%s, %s)\n", qPrintable(caps.at(1)), qPrintable(caps.at(2)));
if (!m_pixmapMap[caps.at(1)].isNull())
m_pixmapMap[caps.at(1)].setMask(mask);
}
/***************************************************************************************************/
void PaintCommands::command_image_load(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString fileName = caps.at(1);
QString name = caps.at(2);
if (name.isEmpty())
name = fileName;
QImage image = image_load<QImage>(fileName);
if (m_verboseMode)
printf(" -(lance) image_load(%s as %s), size=[%d, %d], format=%d\n",
qPrintable(fileName), qPrintable(name),
image.width(), image.height(), image.format());
m_imageMap[name] = image;
}
/***************************************************************************************************/
void PaintCommands::command_image_setColorCount(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
int count = convertToInt(caps.at(2));
if (m_verboseMode)
printf(" -(lance) image_setColorCount(%s), %d -> %d\n",
qPrintable(name), m_imageMap[name].colorCount(), count);
m_imageMap[name].setColorCount(count);
}
/***************************************************************************************************/
void PaintCommands::command_image_setColor(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
int index = convertToInt(caps.at(2));
QColor color = convertToColor(caps.at(3));
if (m_verboseMode)
printf(" -(lance) image_setColor(%s), %d = %08x\n", qPrintable(name), index, color.rgba());
m_imageMap[name].setColor(index, color.rgba());
}
/***************************************************************************************************/
void PaintCommands::command_image_setDevicePixelRatio(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double dpr = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) image_setDevicePixelRatio(%s), %.1f -> %.1f\n",
qPrintable(name), m_imageMap[name].devicePixelRatio(), dpr);
m_imageMap[name].setDevicePixelRatio(dpr);
}
/***************************************************************************************************/
void PaintCommands::command_abort(QRegularExpressionMatch)
{
m_abort = true;
}
/***************************************************************************************************/
void PaintCommands::command_gradient_clearStops(QRegularExpressionMatch)
{
if (m_verboseMode)
printf(" -(lance) gradient_clearStops\n");
m_gradientStops.clear();
}
/***************************************************************************************************/
void PaintCommands::command_gradient_appendStop(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double pos = convertToDouble(caps.at(1));
QColor color = convertToColor(caps.at(2));
if (m_verboseMode)
printf(" -(lance) gradient_appendStop(%.2f, %x)\n", pos, color.rgba());
m_gradientStops << QGradientStop(pos, color);
}
/***************************************************************************************************/
void PaintCommands::command_gradient_setLinear(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x1 = convertToDouble(caps.at(1));
double y1 = convertToDouble(caps.at(2));
double x2 = convertToDouble(caps.at(3));
double y2 = convertToDouble(caps.at(4));
if (m_verboseMode)
printf(" -(lance) gradient_setLinear (%.2f, %.2f), (%.2f, %.2f), spread=%d\n",
x1, y1, x2, y2, m_gradientSpread);
QLinearGradient lg(QPointF(x1, y1), QPointF(x2, y2));
lg.setStops(m_gradientStops);
lg.setSpread(m_gradientSpread);
lg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(lg);
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
m_painter->setBrush(brush);
}
/***************************************************************************************************/
void PaintCommands::command_gradient_setLinearPen(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x1 = convertToDouble(caps.at(1));
double y1 = convertToDouble(caps.at(2));
double x2 = convertToDouble(caps.at(3));
double y2 = convertToDouble(caps.at(4));
if (m_verboseMode)
printf(" -(lance) gradient_setLinear (%.2f, %.2f), (%.2f, %.2f), spread=%d\n",
x1, y1, x2, y2, m_gradientSpread);
QLinearGradient lg(QPointF(x1, y1), QPointF(x2, y2));
lg.setStops(m_gradientStops);
lg.setSpread(m_gradientSpread);
lg.setCoordinateMode(m_gradientCoordinate);
QPen pen = m_painter->pen();
pen.setBrush(lg);
m_painter->setPen(pen);
}
/***************************************************************************************************/
void PaintCommands::command_gradient_setRadial(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double cx = convertToDouble(caps.at(1));
double cy = convertToDouble(caps.at(2));
double rad = convertToDouble(caps.at(3));
double fx = convertToDouble(caps.at(4));
double fy = convertToDouble(caps.at(5));
if (m_verboseMode)
printf(" -(lance) gradient_setRadial center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), "
"spread=%d\n",
cx, cy, rad, fx, fy, m_gradientSpread);
QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy));
rg.setStops(m_gradientStops);
rg.setSpread(m_gradientSpread);
rg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(rg);
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
m_painter->setBrush(brush);
}
/***************************************************************************************************/
void PaintCommands::command_gradient_setRadialExtended(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double cx = convertToDouble(caps.at(1));
double cy = convertToDouble(caps.at(2));
double rad = convertToDouble(caps.at(3));
double fx = convertToDouble(caps.at(4));
double fy = convertToDouble(caps.at(5));
double frad = convertToDouble(caps.at(6));
if (m_verboseMode)
printf(" -(lance) gradient_setRadialExtended center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), "
"focal radius=%.2f, spread=%d\n",
cx, cy, rad, fx, fy, frad, m_gradientSpread);
QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy), frad);
rg.setStops(m_gradientStops);
rg.setSpread(m_gradientSpread);
rg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(rg);
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
m_painter->setBrush(brush);
}
/***************************************************************************************************/
void PaintCommands::command_gradient_setConical(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double cx = convertToDouble(caps.at(1));
double cy = convertToDouble(caps.at(2));
double angle = convertToDouble(caps.at(3));
if (m_verboseMode) {
printf(" -(lance) gradient_setConical center=(%.2f, %.2f), angle=%.2f\n, spread=%d",
cx, cy, angle, m_gradientSpread);
}
QConicalGradient cg(QPointF(cx, cy), angle);
cg.setStops(m_gradientStops);
cg.setSpread(m_gradientSpread);
cg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(cg);
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
m_painter->setBrush(brush);
}
/***************************************************************************************************/
void PaintCommands::command_gradient_setSpread(QRegularExpressionMatch re)
{
int spreadMethod = translateEnum(spreadMethodTable, re.captured(1), 3);
if (m_verboseMode)
printf(" -(lance) gradient_setSpread %d=[%s]\n", spreadMethod, spreadMethodTable[spreadMethod]);
m_gradientSpread = QGradient::Spread(spreadMethod);
}
void PaintCommands::command_gradient_setCoordinateMode(QRegularExpressionMatch re)
{
int coord = translateEnum(coordinateMethodTable, re.captured(1), 4);
if (m_verboseMode)
printf(" -(lance) gradient_setCoordinateMode %d=[%s]\n", coord,
coordinateMethodTable[coord]);
m_gradientCoordinate = QGradient::CoordinateMode(coord);
}
/***************************************************************************************************/
void PaintCommands::command_surface_begin(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double x = convertToDouble(caps.at(1));
double y = convertToDouble(caps.at(2));
double w = convertToDouble(caps.at(3));
double h = convertToDouble(caps.at(4));
if (m_surface_painter) {
fprintf(stderr, "ERROR: surface already active");
return;
}
if (m_verboseMode)
printf(" -(lance) surface_begin, pos=[%.2f, %.2f], size=[%.2f, %.2f]\n", x, y, w, h);
m_surface_painter = m_painter;
if (m_type == OpenGLType || m_type == OpenGLBufferType) {
#ifndef QT_NO_OPENGL
m_default_glcontext = QOpenGLContext::currentContext();
m_surface_glcontext = new QOpenGLContext();
// Pick up the format from the current context; this is especially
// important in order to pick the right version/profile to test.
m_surface_glcontext->setFormat(m_default_glcontext->format());
m_surface_glcontext->create();
m_surface_glcontext->makeCurrent(m_default_glcontext->surface());
QOpenGLFramebufferObjectFormat fmt; // ###TBD: get format from caller
fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
fmt.setSamples(4);
m_surface_glbuffer = new QOpenGLFramebufferObject(qRound(w), qRound(h), fmt);
m_surface_glbuffer->bind();
m_surface_glpaintdevice = new QOpenGLPaintDevice(qRound(w), qRound(h));
m_painter = new QPainter(m_surface_glpaintdevice);
m_painter->save();
m_painter->setCompositionMode(QPainter::CompositionMode_Clear);
m_painter->fillRect(QRect(0, 0, qRound(w), qRound(h)), Qt::transparent);
m_painter->restore();
#endif
} else {
QImage::Format surface_format;
if (QImage::toPixelFormat(m_format).alphaUsage() != QPixelFormat::UsesAlpha)
surface_format = qt_alphaVersion(m_format);
else
surface_format = m_format;
m_surface_image = QImage(qRound(w), qRound(h), surface_format);
m_surface_image.fill(0);
m_painter = new QPainter(&m_surface_image);
}
m_surface_rect = QRectF(x, y, w, h);
}
/***************************************************************************************************/
void PaintCommands::command_surface_end(QRegularExpressionMatch)
{
if (!m_surface_painter) {
fprintf(stderr, "ERROR: surface not active");
return;
}
if (m_verboseMode)
printf(" -(lance) surface_end, pos=[%.2f, %.2f], size=[%.2f, %.2f]\n",
m_surface_rect.x(),
m_surface_rect.y(),
m_surface_rect.width(),
m_surface_rect.height());
m_painter->end();
delete m_painter;
m_painter = m_surface_painter;
m_surface_painter = 0;
if (m_type == OpenGLType || m_type == OpenGLBufferType) {
#ifndef QT_NO_OPENGL
QImage new_image = m_surface_glbuffer->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
delete m_surface_glpaintdevice;
m_surface_glpaintdevice = 0;
delete m_surface_glbuffer;
m_surface_glbuffer = 0;
delete m_surface_glcontext;
m_surface_glcontext = 0;
m_default_glcontext->makeCurrent(m_default_glcontext->surface());
m_painter->drawImage(m_surface_rect, new_image);
// Flush the pipeline:
m_painter->beginNativePainting();
m_painter->endNativePainting();
#endif
} else {
m_painter->drawImage(m_surface_rect, m_surface_image);
m_surface_image = QImage();
}
m_surface_rect = QRectF();
}
/***************************************************************************************************/
void PaintCommands::command_image_convertToFormat(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString srcName = caps.at(1);
QString destName = caps.at(2);
if (!m_imageMap.contains(srcName)) {
fprintf(stderr, "ERROR(convertToFormat): no such image '%s'\n", qPrintable(srcName));
return;
}
int format = translateEnum(imageFormatTable, caps.at(3), QImage::NImageFormats);
if (format < 0 || format >= QImage::NImageFormats) {
fprintf(stderr, "ERROR(convertToFormat): invalid format %d = '%s'\n",
format, qPrintable(caps.at(3)));
return;
}
QImage src = m_imageMap[srcName];
QImage dest = src.convertToFormat(QImage::Format(format),
Qt::OrderedAlphaDither | Qt::OrderedDither);
if (m_verboseMode) {
printf(" -(lance) convertToFormat %s:%d -> %s:%d\n",
qPrintable(srcName), src.format(),
qPrintable(destName), dest.format());
}
m_imageMap[destName] = dest;
}
/***************************************************************************************************/
void PaintCommands::command_textlayout_draw(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString text = caps.at(1);
double width = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) textlayout_draw text='%s', width=%f\n",
qPrintable(text), width);
QFont copy = m_painter->font();
copy.setPointSize(10);
QTextLayout layout(text, copy, m_painter->device());
layout.beginLayout();
double y_offset = 0;
while (true) {
QTextLine line = layout.createLine();
if (!line.isValid())
break;
line.setLineWidth(width);
line.setPosition(QPointF(0, y_offset));
y_offset += line.height();
}
layout.draw(m_painter, QPointF(0, 0));
}
/***************************************************************************************************/
void PaintCommands::command_pen_setDashOffset(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
double offset = convertToDouble(caps.at(1));
if (m_verboseMode)
printf(" -(lance) setDashOffset(%lf)\n", offset);
QPen p = m_painter->pen();
p.setDashOffset(offset);
m_painter->setPen(p);
}
/***************************************************************************************************/
void PaintCommands::command_pen_setDashPattern(QRegularExpressionMatch re)
{
static QRegularExpression separators("\\s");
QStringList caps = re.capturedTexts();
QString cap = caps.at(1);
QStringList numbers = cap.split(separators, Qt::SkipEmptyParts);
QList<qreal> pattern;
for (int i=0; i<numbers.size(); ++i)
pattern.append(convertToDouble(numbers.at(i)));
if (m_verboseMode)
printf(" -(lance) pen_setDashPattern(size=%zd)\n", size_t(pattern.size()));
QPen p = m_painter->pen();
p.setDashPattern(pattern);
m_painter->setPen(p);
}
/***************************************************************************************************/
void PaintCommands::command_pen_setCosmetic(QRegularExpressionMatch re)
{
QString hm = re.capturedTexts().at(1);
bool on = hm == "true" || hm == "yes" || hm == "on";
if (m_verboseMode) {
printf(" -(lance) pen_setCosmetic(%s)\n", on ? "true" : "false");
}
QPen p = m_painter->pen();
p.setCosmetic(on);
m_painter->setPen(p);
}
/***************************************************************************************************/
void PaintCommands::command_drawConvexPolygon(QRegularExpressionMatch re)
{
static QRegularExpression separators("\\s");
QStringList caps = re.capturedTexts();
QString cap = caps.at(1);
QStringList numbers = cap.split(separators, Qt::SkipEmptyParts);
QPolygonF array;
for (int i=0; i + 1<numbers.size(); i+=2)
array.append(QPointF(convertToDouble(numbers.at(i)), convertToDouble(numbers.at(i+1))));
if (m_verboseMode)
printf(" -(lance) drawConvexPolygon(size=%zd)\n", size_t(array.size()));
m_painter->drawConvexPolygon(array);
}