// 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 #include #include #include #include #include #include #include #include #include #include #include #ifndef QT_NO_OPENGL #include #include #include #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 PaintCommands::s_commandInfoTable = QList(); QList > PaintCommands::s_enumsTable = QList >(); QMultiHash 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", "import \"myfile.qrc\""); DECL_PAINTCOMMAND("begin_block", command_begin_block, "^begin_block\\s+(\\w*)$", "begin_block ", "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 ", "repeat_block blockName"); DECL_PAINTCOMMAND("textlayout_draw", command_textlayout_draw, "^textlayout_draw\\s+\"(.*)\"\\s+([0-9.]*)$", "textlayout_draw ", "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 ", "setBackgroundMode TransparentMode"); DECL_PAINTCOMMAND("setBackground", command_setBackground, "^setBackground\\s+#?(\\w*)\\s*(\\w*)?$", "setBackground [brush style enum]", "setBackground black SolidPattern"); DECL_PAINTCOMMAND("setOpacity", command_setOpacity, "^setOpacity\\s+(-?\\d*\\.?\\d*)$", "setOpacity \n - opacity is in [0,1]", "setOpacity 1.0"); DECL_PAINTCOMMAND("path_setFillRule", command_path_setFillRule, "^path_setFillRule\\s+(\\w*)\\s+(\\w*)$", "path_setFillRule [Winding|OddEven]", "path_setFillRule pathName Winding"); DECL_PAINTCOMMAND("setBrush", command_setBrush, "^setBrush\\s+(#?[\\w.:\\/]*)\\s*(\\w*)?$", "setBrush \nsetBrush noBrush\nsetBrush ", "setBrush white SolidPattern"); DECL_PAINTCOMMAND("setBrushOrigin", command_setBrushOrigin, "^setBrushOrigin\\s*(-?\\w*)\\s+(-?\\w*)$", "setBrushOrigin ", "setBrushOrigin 0 0"); DECL_PAINTCOMMAND("brushTranslate", command_brushTranslate, "^brushTranslate\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "brushTranslate ", "brushTranslate 0.0 0.0"); DECL_PAINTCOMMAND("brushScale", command_brushScale, "^brushScale\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "brushScale ", "brushScale 0.0 0.0"); DECL_PAINTCOMMAND("brushRotate", command_brushRotate, "^brushRotate\\s+(-?[\\w.]*)$", "brushRotate \n - angle in degrees", "brushRotate 0.0"); DECL_PAINTCOMMAND("brushShear", command_brushShear, "^brushShear\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "brushShear ", "brushShear 0.0 0.0"); DECL_PAINTCOMMAND("setCompositionMode", command_setCompositionMode, "^setCompositionMode\\s+([\\w_0-9]*)$", "setCompositionMode ", "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 [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 \nsetPen \nsetPen brush", "setPen black"); DECL_PAINTCOMMAND("setPen", command_setPen2, "^setPen\\s+(#?\\w*)\\s+([\\w.]+)\\s*(\\w*)\\s*(\\w*)\\s*(\\w*)$", "setPen brush| [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 \n", "pen_setDashOffset 1.0"); DECL_PAINTCOMMAND("pen_setDashPattern", command_pen_setDashPattern, "^pen_setDashPattern\\s+\\[([\\w\\s.]*)\\]$", "pen_setDashPattern <[ ... ]>", "pen_setDashPattern [ 2 1 4 1 3 3 ]"); DECL_PAINTCOMMAND("pen_setCosmetic", command_pen_setCosmetic, "^pen_setCosmetic\\s+(\\w*)$", "pen_setCosmetic ", "pen_setCosmetic true"); DECL_PAINTCOMMAND("setRenderHint", command_setRenderHint, "^setRenderHint\\s+([\\w_0-9]*)\\s*(\\w*)$", "setRenderHint ", "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 ", "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 \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 ", "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 \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 \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 ", "gradient_setLinearPen 1.0 1.0 2.0 2.0"); DECL_PAINTCOMMAND("gradient_setSpread", command_gradient_setSpread, "^gradient_setSpread\\s+(\\w*)$", "gradient_setSpread ", "gradient_setSpread PadSpread"); DECL_PAINTCOMMAND("gradient_setCoordinateMode", command_gradient_setCoordinateMode, "^gradient_setCoordinateMode\\s+(\\w*)$", "gradient_setCoordinateMode ", "gradient_setCoordinateMode ObjectBoundingMode"); DECL_PAINTCOMMANDSECTION("drawing ops"); DECL_PAINTCOMMAND("drawPoint", command_drawPoint, "^drawPoint\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "drawPoint ", "drawPoint 10.0 10.0"); DECL_PAINTCOMMAND("drawLine", command_drawLine, "^drawLine\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "drawLine ", "drawLine 10.0 10.0 20.0 20.0"); DECL_PAINTCOMMAND("drawLines", command_drawLines, "^drawLines\\s+\\[([\\w\\s\\-.]*)\\]$", "drawLines <[ ... ]>", "drawLines [ 10 10 50 10 50 20 10 20 ]"); DECL_PAINTCOMMAND("drawRect", command_drawRect, "^drawRect\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "drawRect ", "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 [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 [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 \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 \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 ", "drawEllipse 10.0 10.0 20.0 20.0"); DECL_PAINTCOMMAND("drawPath", command_drawPath, "^drawPath\\s+(\\w*)$", "drawPath ", "drawPath mypath"); DECL_PAINTCOMMAND("drawPie", command_drawPie, "^drawPie\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)$", "drawPie \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 " "\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 " "\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 <[ ... ]> ", "drawPolygon [ 1 4 6 8 5 3 ] Winding"); DECL_PAINTCOMMAND("drawConvexPolygon", command_drawConvexPolygon, "^drawConvexPolygon\\s+\\[([\\w\\s-.]*)\\]$", "drawConvexPolygon <[ ... ]>", "drawConvexPolygon [ 1 4 6 8 5 3 ]"); DECL_PAINTCOMMAND("drawPolyline", command_drawPolyline, "^drawPolyline\\s+\\[([\\w\\s\\-.]*)\\]$", "drawPolyline <[ ... ]>", "drawPolyline [ 1 4 6 8 5 3 ]"); DECL_PAINTCOMMAND("drawText", command_drawText, "^drawText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$", "drawText ", "drawText 10 10 \"my text\""); DECL_PAINTCOMMAND("drawStaticText", command_drawStaticText, "^drawStaticText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$", "drawStaticText ", "drawStaticText 10 10 \"my text\""); DECL_PAINTCOMMAND("drawGlyphRun", command_drawGlyphRun, "^drawGlyphRun\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$", "drawGlyphRun - 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 ", "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 " "\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 [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 [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 " " " " ..." "\n - where count is 1 or 2, and followed by centerPos, sourceRect, scaleX, scaleY, rotation, opacity 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 ", "path_moveTo mypath 1.0 1.0"); DECL_PAINTCOMMAND("path_lineTo", command_path_lineTo, "^path_lineTo\\s+([.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)$", "path_lineTo ", "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 ", "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 <[ ... ]>", "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 ", "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 ", "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 \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 ", "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 ", "path_closeSubpath mypath"); DECL_PAINTCOMMAND("path_createOutline", command_path_createOutline, "^path_createOutline\\s+(\\w*)\\s+(\\w*)$", "path_createOutline ", "path_createOutline mypath myoutline"); DECL_PAINTCOMMAND("path_debugPrint", command_path_debugPrint, "^path_debugPrint\\s+(\\w*)$", "path_debugPrint ", "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 ", "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 ", "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 ", "region_getClipRegion myregion"); DECL_PAINTCOMMAND("setClipRegion", command_setClipRegion, "^setClipRegion\\s+(\\w*)\\s*(\\w*)$", "setClipRegion ", "setClipRegion myregion ReplaceClip"); DECL_PAINTCOMMAND("path_getClipPath", command_path_getClipPath, "^path_getClipPath\\s+([\\w0-9]*)$", "path_getClipPath ", "path_getClipPath mypath"); DECL_PAINTCOMMAND("setClipPath", command_setClipPath, "^setClipPath\\s+(\\w*)\\s*(\\w*)$", "setClipPath ", "setClipPath mypath ReplaceClip"); DECL_PAINTCOMMAND("setClipRect", command_setClipRect, "^setClipRect\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s+(-?\\w*)\\s*(\\w*)$", "setClipRect ", "setClipRect 0 0 10 10 ReplaceClip"); DECL_PAINTCOMMAND("setClipRectF", command_setClipRectF, "^setClipRectF\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s*(\\w.*)$", "setClipRectF ", "setClipRectF 0.1 0.2 10.3 10.4 ReplaceClip"); DECL_PAINTCOMMAND("setClipping", command_setClipping, "^setClipping\\s+(\\w*)$", "setClipping ", "setClipping true"); DECL_PAINTCOMMANDSECTION("surface"); DECL_PAINTCOMMAND("surface_begin", command_surface_begin, "^surface_begin\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "surface_begin ", "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 ", "pixmap_load :/images/face.png myPixmap"); DECL_PAINTCOMMAND("pixmap_setMask", command_pixmap_setMask, "^pixmap_setMask\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]*)$", "pixmap_setMask ", "pixmap_setMask myPixmap :/images/bitmap.png"); DECL_PAINTCOMMAND("bitmap_load", command_bitmap_load, "^bitmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$", "bitmap_load \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 ", "pixmap_setDevicePixelRatio myPixmap 2.0"); DECL_PAINTCOMMAND("image_convertToFormat", command_image_convertToFormat, "^image_convertToFormat\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]+)\\s+([\\w0-9_]*)$", "image_convertToFormat ", "image_convertToFormat myImage myNewImage Indexed8"); DECL_PAINTCOMMAND("image_load", command_image_load, "^image_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$", "image_load ", "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 ", "image_setColor myImage 0 black"); DECL_PAINTCOMMAND("image_setColorCount", command_image_setColorCount, "^image_setColorCount\\s+([\\w.:\\/]*)\\s+([0-9]*)$", "image_setColorCount ", "image_setColorCount myImage 128"); DECL_PAINTCOMMAND("image_setDevicePixelRatio", command_image_setDevicePixelRatio, "^image_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$", "image_setDevicePixelRatio ", "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 ", "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 ", "translate 10.0 10.0"); DECL_PAINTCOMMAND("rotate", command_rotate, "^rotate\\s+(-?[\\w.]*)$", "rotate \n - with angle in degrees", "rotate 30.0"); DECL_PAINTCOMMAND("rotate_x", command_rotate_x, "^rotate_x\\s+(-?[\\w.]*)$", "rotate_x \n - with angle in degrees", "rotate_x 30.0"); DECL_PAINTCOMMAND("rotate_y", command_rotate_y, "^rotate_y\\s+(-?[\\w.]*)$", "rotate_y \n - with angle in degrees", "rotate_y 30.0"); DECL_PAINTCOMMAND("scale", command_scale, "^scale\\s+(-?[\\w.]*)\\s+(-?[\\w.]*)$", "scale ", "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 " "\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 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); QList indices = s_commandHash.values(firstWord); foreach(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; idevice()->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 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(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(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(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 + 1drawPolygon(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 + 1drawPolyline(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 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(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 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.srcx = 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 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 + 1pen(); 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= 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(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(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(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(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(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 pattern; for (int i=0; ipen(); 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 + 1drawConvexPolygon(array); }