8#include <private/qtquickglobal_p.h>
9#include <private/qquickcontext2dtexture_p.h>
10#include <private/qquickitem_p.h>
11#if QT_CONFIG(quick_shadereffect)
12#include <QtQuick/private/qquickshadereffectsource_p.h>
14#include <qsgrendererinterface.h>
16#include <QtQuick/private/qsgcontext_p.h>
17#include <private/qquicksvgparser_p.h>
18#if QT_CONFIG(quick_path)
19#include <private/qquickpath_p.h>
21#include <private/qquickimage_p_p.h>
25#include <qqmlengine.h>
26#include <private/qv4domerrors_p.h>
27#include <private/qv4engine_p.h>
28#include <private/qv4object_p.h>
29#include <private/qv4qobjectwrapper_p.h>
30#include <private/qquickwindow_p.h>
32#include <private/qv4value_p.h>
33#include <private/qv4functionobject_p.h>
34#include <private/qv4objectproto_p.h>
35#include <private/qv4scopedvalue_p.h>
36#include <private/qlocale_tools_p.h>
38#include <QtCore/qmath.h>
39#include <QtCore/qvector.h>
40#include <QtCore/private/qnumeric_p.h>
41#include <QtCore/QRunnable>
42#include <QtGui/qguiapplication.h>
43#include <private/qguiapplication_p.h>
44#include <qpa/qplatformintegration.h>
46#include <private/qsgdefaultrendercontext_p.h>
48#include <QtCore/qpointer.h>
51#if defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
95#define CHECK_CONTEXT(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
96 THROW_GENERIC_ERROR("Not a Context2D object");
98#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
99 THROW_GENERIC_ERROR("Not a Context2D object");
100#define qClamp(val, min, max) qMin(qMax(val, min), max)
101#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0
&& c <= 9
))
104 QByteArray str = name.toQString().toUtf8();
106 char *p = str.data();
107 int len = str.size();
109 if (!p || len > 255 || len <= 7)
110 return QColor::fromString(p);
112 bool isRgb(
false), isHsl(
false), hasAlpha(
false);
115 while (isspace(*p)) p++;
116 if (strncmp(p,
"rgb", 3) == 0)
118 else if (strncmp(p,
"hsl", 3) == 0)
121 return QColor::fromString(p);
124 hasAlpha = (*p ==
'a') ?
true :
false;
130 int rh, gs, bl, alpha = 255;
133 while (isspace(*p)) p++;
134 rh = strtol(p, &p, 10);
136 rh = qRound(rh/100.0 * 255);
139 if (*p++ !=
',')
return QColor();
142 while (isspace(*p)) p++;
143 gs = strtol(p, &p, 10);
145 gs = qRound(gs/100.0 * 255);
148 if (*p++ !=
',')
return QColor();
151 while (isspace(*p)) p++;
152 bl = strtol(p, &p, 10);
154 bl = qRound(bl/100.0 * 255);
159 if (*p++!=
',')
return QColor();
160 while (isspace(*p)) p++;
162 alpha = qRound(qstrtod(p,
const_cast<
const char **>(&p), &ok) * 255);
165 if (*p !=
')')
return QColor();
167 return QColor::fromRgba(qRgba(
qClamp(rh, 0, 255),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255)));
169 return QColor::fromHsl(
qClamp(rh, 0, 359),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255));
177 float size = fontSizeToken.trimmed().toFloat(&ok);
181 qWarning().nospace() <<
"Context2D: A font size of " << fontSizeToken <<
" is invalid.";
186
187
188
189
192 const QStringView trimmedToken = fontSizeToken.trimmed();
193 const QStringView unitStr = trimmedToken.right(2);
194 const QStringView value = trimmedToken.left(trimmedToken.size() - 2);
197 if (unitStr == QLatin1String(
"px")) {
198 size = qParseFontSizeFromToken(value, ok);
200 font.setPixelSize(size);
203 }
else if (unitStr == QLatin1String(
"pt")) {
204 size = qParseFontSizeFromToken(value, ok);
206 font.setPointSize(size);
210 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
216
217
218
219
222 QStringList extractedFamilies;
224 QString currentFamily;
225 for (
int index = 0; index < fontFamiliesString.size(); ++index) {
226 const QChar ch = fontFamiliesString.at(index);
227 if (ch == u'"' || ch == u'\'') {
228 if (quoteIndex == -1) {
231 if (ch == fontFamiliesString.at(quoteIndex)) {
233 const QString family = fontFamiliesString.mid(quoteIndex + 1, index - quoteIndex - 1).toString();
234 extractedFamilies.push_back(family);
235 currentFamily.clear();
238 qWarning().nospace() <<
"Context2D: Mismatched quote in font string.";
239 return QStringList();
242 }
else if (ch == u' ' && quoteIndex == -1) {
244 if (!currentFamily.isEmpty()) {
246 extractedFamilies.push_back(currentFamily);
247 currentFamily.clear();
250 currentFamily.push_back(ch);
253 if (!currentFamily.isEmpty()) {
254 if (quoteIndex == -1) {
256 extractedFamilies.push_back(currentFamily);
258 qWarning().nospace() <<
"Context2D: Unclosed quote in font string.";
259 return QStringList();
262 if (extractedFamilies.isEmpty()) {
263 qWarning().nospace() <<
"Context2D: Missing or misplaced font family in font string"
264 <<
" (it must come after the font size).";
266 return extractedFamilies;
270
271
272
273
274
275
276
277
280 for (
const QString &fontFamilyToken : fontFamilyTokens) {
281 if (QFontDatabase::hasFamily(fontFamilyToken)) {
282 font.setFamily(fontFamilyToken);
288 if (fontFamilyToken.compare(QLatin1String(
"serif")) == 0) {
289 styleHint = QFont::Serif;
290 }
else if (fontFamilyToken.compare(QLatin1String(
"sans-serif")) == 0) {
291 styleHint = QFont::SansSerif;
292 }
else if (fontFamilyToken.compare(QLatin1String(
"cursive")) == 0) {
293 styleHint = QFont::Cursive;
294 }
else if (fontFamilyToken.compare(QLatin1String(
"monospace")) == 0) {
295 styleHint = QFont::Monospace;
296 }
else if (fontFamilyToken.compare(QLatin1String(
"fantasy")) == 0) {
297 styleHint = QFont::Fantasy;
299 if (styleHint != -1) {
301 tmp.setStyleHint(
static_cast<QFont::StyleHint>(styleHint));
302 font.setFamily(tmp.defaultFamily());
307 qWarning(
"Context2D: The font families specified are invalid: %s", qPrintable(fontFamilyTokens.join(QString()).trimmed()));
319#define Q_TRY_SET_TOKEN(token, value, setStatement) if
320 (!(usedTokens & token)) {
323}else {
324 qWarning().nospace() << "Context2D: Duplicate token " << QLatin1String(value) << " found in font string.";
325 return currentFont; \
326}
329
330
331
332
334 if (fontString.isEmpty()) {
335 qWarning().nospace() <<
"Context2D: Font string is empty.";
341 int fontSizeEnd = fontString.indexOf(QLatin1String(
"px"));
342 if (fontSizeEnd == -1)
343 fontSizeEnd = fontString.indexOf(QLatin1String(
"pt"));
344 if (fontSizeEnd == -1) {
345 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
349 int fontSizeStart = fontString.lastIndexOf(u' ', fontSizeEnd);
350 if (fontSizeStart == -1) {
363 if (!qSetFontSizeFromToken(newFont, QStringView{fontString}.mid(fontSizeStart, fontSizeEnd - fontSizeStart)))
367 QString remainingFontString = fontString;
368 remainingFontString.remove(fontSizeStart, fontSizeEnd - fontSizeStart);
369 QStringView remainingFontStringRef(remainingFontString);
372 const QStringView fontFamiliesString = remainingFontStringRef.mid(fontSizeStart);
373 remainingFontStringRef.truncate(fontSizeStart);
374 QStringList fontFamilies = qExtractFontFamiliesFromString(fontFamiliesString);
375 if (fontFamilies.isEmpty()) {
378 if (!qSetFontFamilyFromTokens(newFont, fontFamilies))
382 const QStringView trimmedTokensStr = remainingFontStringRef.trimmed();
383 if (trimmedTokensStr.isEmpty()) {
387 const auto tokens = trimmedTokensStr.split(QLatin1Char(
' '));
391 for (
const QStringView &token : tokens) {
392 if (token.compare(QLatin1String(
"normal")) == 0) {
393 if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
395 if (!(usedTokens & FontStyle)) {
397 usedTokens = usedTokens | FontStyle;
398 }
else if (!(usedTokens & FontVariant)) {
400 usedTokens |= FontVariant;
401 }
else if (!(usedTokens & FontWeight)) {
403 usedTokens |= FontWeight;
406 qWarning().nospace() <<
"Context2D: Duplicate token \"normal\" found in font string.";
409 }
else if (token.compare(QLatin1String(
"bold")) == 0) {
411 }
else if (token.compare(QLatin1String(
"italic")) == 0) {
412 Q_TRY_SET_TOKEN(FontStyle,
"italic", newFont.setStyle(QFont::StyleItalic))
413 }
else if (token.compare(QLatin1String(
"oblique")) == 0) {
414 Q_TRY_SET_TOKEN(FontStyle,
"oblique", newFont.setStyle(QFont::StyleOblique))
415 }
else if (token.compare(QLatin1String(
"small-caps")) == 0) {
416 Q_TRY_SET_TOKEN(FontVariant,
"small-caps", newFont.setCapitalization(QFont::SmallCaps))
418 bool conversionOk =
false;
419 int weight = token.toInt(&conversionOk);
422 newFont.setWeight(QFont::Weight(weight)))
425 qWarning().nospace() <<
"Context2D: Invalid or misplaced token " << token
426 <<
" found in font string.";
467 *m_context = context;
469 m_context =
new QPointer<QQuickContext2D>(context);
473 QPointer<QQuickContext2D>* m_context;
477 void init() { Object::init(); }
501 auto *mm = internalClass->engine->memoryManager;
502 mm->changeUnmanagedHeapSizeUsage(-image->sizeInBytes());
514 static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
516 Object::markObjects(that, markStack);
562#if QT_CONFIG(quick_path)
703 int delta = radius ? radius : qFloor(qSqrt(weights.size()) / qreal(2));
704 int filterDim = 2 * delta + 1;
706 QImage dst = QImage(src.size(), src.format());
709 int h = src.height();
711 const QRgb *sr = (
const QRgb *)(src.constBits());
712 int srcStride = src.bytesPerLine() / 4;
714 QRgb *dr = (QRgb*)dst.bits();
715 int dstStride = dst.bytesPerLine() / 4;
717 for (
int y = 0; y < h; ++y) {
718 for (
int x = 0; x < w; ++x) {
732 for (
int cy = 0; cy < filterDim; ++cy) {
733 int scy = sy + cy - delta;
735 if (scy < 0 || scy >= h)
738 const QRgb *sry = sr + scy * srcStride;
740 for (
int cx = 0; cx < filterDim; ++cx) {
741 int scx = sx + cx - delta;
743 if (scx < 0 || scx >= w)
746 const QRgb col = sry[scx];
750 green += qGreen(col);
752 alpha += qAlpha(col);
754 qreal wt = weights[cy * filterDim + cx];
756 redF += qRed(col) * wt;
757 greenF += qGreen(col) * wt;
758 blueF += qBlue(col) * wt;
759 alphaF += qAlpha(col) * wt;
765 dr[x] = qRgba(qRound(red * weights[0]), qRound(green * weights[0]), qRound(blue * weights[0]), qRound(alpha * weights[0]));
767 dr[x] = qRgba(qRound(redF), qRound(greenF), qRound(blueF), qRound(alphaF));
778 int passes = quality? 3: 1;
779 int filterSize = 2 * radius + 1;
780 for (
int i = 0; i < passes; ++i)
781 image = qt_image_convolute_filter(image, QList<qreal>() << 1.0 / (filterSize * filterSize), radius);
786 if (compositeOperator == QLatin1String(
"source-over")) {
787 return QPainter::CompositionMode_SourceOver;
788 }
else if (compositeOperator == QLatin1String(
"source-out")) {
789 return QPainter::CompositionMode_SourceOut;
790 }
else if (compositeOperator == QLatin1String(
"source-in")) {
791 return QPainter::CompositionMode_SourceIn;
792 }
else if (compositeOperator == QLatin1String(
"source-atop")) {
793 return QPainter::CompositionMode_SourceAtop;
794 }
else if (compositeOperator == QLatin1String(
"destination-atop")) {
795 return QPainter::CompositionMode_DestinationAtop;
796 }
else if (compositeOperator == QLatin1String(
"destination-in")) {
797 return QPainter::CompositionMode_DestinationIn;
798 }
else if (compositeOperator == QLatin1String(
"destination-out")) {
799 return QPainter::CompositionMode_DestinationOut;
800 }
else if (compositeOperator == QLatin1String(
"destination-over")) {
801 return QPainter::CompositionMode_DestinationOver;
802 }
else if (compositeOperator == QLatin1String(
"lighter")) {
803 return QPainter::CompositionMode_Plus;
804 }
else if (compositeOperator == QLatin1String(
"copy")) {
805 return QPainter::CompositionMode_Source;
806 }
else if (compositeOperator == QLatin1String(
"xor")) {
807 return QPainter::CompositionMode_Xor;
808 }
else if (compositeOperator == QLatin1String(
"qt-clear")) {
809 return QPainter::CompositionMode_Clear;
810 }
else if (compositeOperator == QLatin1String(
"qt-destination")) {
811 return QPainter::CompositionMode_Destination;
812 }
else if (compositeOperator == QLatin1String(
"qt-multiply")) {
813 return QPainter::CompositionMode_Multiply;
814 }
else if (compositeOperator == QLatin1String(
"qt-screen")) {
815 return QPainter::CompositionMode_Screen;
816 }
else if (compositeOperator == QLatin1String(
"qt-overlay")) {
817 return QPainter::CompositionMode_Overlay;
818 }
else if (compositeOperator == QLatin1String(
"qt-darken")) {
819 return QPainter::CompositionMode_Darken;
820 }
else if (compositeOperator == QLatin1String(
"qt-lighten")) {
821 return QPainter::CompositionMode_Lighten;
822 }
else if (compositeOperator == QLatin1String(
"qt-color-dodge")) {
823 return QPainter::CompositionMode_ColorDodge;
824 }
else if (compositeOperator == QLatin1String(
"qt-color-burn")) {
825 return QPainter::CompositionMode_ColorBurn;
826 }
else if (compositeOperator == QLatin1String(
"qt-hard-light")) {
827 return QPainter::CompositionMode_HardLight;
828 }
else if (compositeOperator == QLatin1String(
"qt-soft-light")) {
829 return QPainter::CompositionMode_SoftLight;
830 }
else if (compositeOperator == QLatin1String(
"qt-difference")) {
831 return QPainter::CompositionMode_Difference;
832 }
else if (compositeOperator == QLatin1String(
"qt-exclusion")) {
833 return QPainter::CompositionMode_Exclusion;
835 return QPainter::CompositionMode_SourceOver;
841 case QPainter::CompositionMode_SourceOver:
842 return QStringLiteral(
"source-over");
843 case QPainter::CompositionMode_DestinationOver:
844 return QStringLiteral(
"destination-over");
845 case QPainter::CompositionMode_Clear:
846 return QStringLiteral(
"qt-clear");
847 case QPainter::CompositionMode_Source:
848 return QStringLiteral(
"copy");
849 case QPainter::CompositionMode_Destination:
850 return QStringLiteral(
"qt-destination");
851 case QPainter::CompositionMode_SourceIn:
852 return QStringLiteral(
"source-in");
853 case QPainter::CompositionMode_DestinationIn:
854 return QStringLiteral(
"destination-in");
855 case QPainter::CompositionMode_SourceOut:
856 return QStringLiteral(
"source-out");
857 case QPainter::CompositionMode_DestinationOut:
858 return QStringLiteral(
"destination-out");
859 case QPainter::CompositionMode_SourceAtop:
860 return QStringLiteral(
"source-atop");
861 case QPainter::CompositionMode_DestinationAtop:
862 return QStringLiteral(
"destination-atop");
863 case QPainter::CompositionMode_Xor:
864 return QStringLiteral(
"xor");
865 case QPainter::CompositionMode_Plus:
866 return QStringLiteral(
"lighter");
867 case QPainter::CompositionMode_Multiply:
868 return QStringLiteral(
"qt-multiply");
869 case QPainter::CompositionMode_Screen:
870 return QStringLiteral(
"qt-screen");
871 case QPainter::CompositionMode_Overlay:
872 return QStringLiteral(
"qt-overlay");
873 case QPainter::CompositionMode_Darken:
874 return QStringLiteral(
"qt-darken");
875 case QPainter::CompositionMode_Lighten:
876 return QStringLiteral(
"lighter");
877 case QPainter::CompositionMode_ColorDodge:
878 return QStringLiteral(
"qt-color-dodge");
879 case QPainter::CompositionMode_ColorBurn:
880 return QStringLiteral(
"qt-color-burn");
881 case QPainter::CompositionMode_HardLight:
882 return QStringLiteral(
"qt-hard-light");
883 case QPainter::CompositionMode_SoftLight:
884 return QStringLiteral(
"qt-soft-light");
885 case QPainter::CompositionMode_Difference:
886 return QStringLiteral(
"qt-difference");
887 case QPainter::CompositionMode_Exclusion:
888 return QStringLiteral(
"qt-exclusion");
901 static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, Value *receiver);
910 QV4::Scope scope(internalClass->engine);
911 QV4::ScopedObject o(scope,
this);
912 o->setArrayType(QV4::Heap::ArrayData::Custom);
930 pixelData = QV4::Value::undefinedValue();
932 QV4::Scope scope(internalClass->engine);
933 QV4::ScopedObject o(scope,
this);
935 o->defineAccessorProperty(QStringLiteral(
"width"), ::QQuickJSContext2DImageData::method_get_width,
nullptr);
936 o->defineAccessorProperty(QStringLiteral(
"height"), ::QQuickJSContext2DImageData::method_get_height,
nullptr);
937 o->defineAccessorProperty(QStringLiteral(
"data"), ::QQuickJSContext2DImageData::method_get_data,
nullptr);
944 QV4::Scope scope(v4);
946 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DPixelData>());
947 v4->memoryManager->changeUnmanagedHeapSizeUsage(image.sizeInBytes());
948 QV4::ScopedObject p(scope, ed->pixelArrayProto.value());
949 pixelData->setPrototypeOf(p);
951 if (image.isNull()) {
952 *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32);
953 pixelData->d()->image->fill(0x00000000);
956 Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatio())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatio())) <= 1);
957 *pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? std::move(image) : std::move(image).convertToFormat(QImage::Format_ARGB32);
960 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DImageData>());
961 imageData->d()->pixelData = pixelData.asReturnedValue();
962 return imageData.asReturnedValue();
968
969
970
971
972
973QV4::ReturnedValue
QQuickJSContext2DPrototype::method_get_canvas(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
976 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
979 RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context()->canvas()));
983
984
985
986
987
988QV4::ReturnedValue
QQuickJSContext2DPrototype::method_restore(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
991 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
994 r->d()->context()->popState();
995 RETURN_RESULT(thisObject->asReturnedValue());
999
1000
1001
1004 QV4::Scope scope(b);
1005 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1008 r->d()->context()->reset();
1010 RETURN_RESULT(thisObject->asReturnedValue());
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1045 QV4::Scope scope(b);
1046 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1049 r->d()->context()->pushState();
1051 RETURN_RESULT(*thisObject);
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rotate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1074 QV4::Scope scope(b);
1075 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1079 r->d()->context()->rotate(argv[0].toNumber());
1080 RETURN_RESULT(*thisObject);
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100QV4::ReturnedValue
QQuickJSContext2DPrototype::method_scale(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1102 QV4::Scope scope(b);
1103 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1108 r->d()->context()->scale(argv[0].toNumber(), argv[1].toNumber());
1109 RETURN_RESULT(*thisObject);
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1151 QV4::Scope scope(b);
1152 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1157 r->d()->context()->setTransform( argv[0].toNumber()
1158 , argv[1].toNumber()
1159 , argv[2].toNumber()
1160 , argv[3].toNumber()
1161 , argv[4].toNumber()
1162 , argv[5].toNumber());
1164 RETURN_RESULT(*thisObject);
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182QV4::ReturnedValue
QQuickJSContext2DPrototype::method_transform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1184 QV4::Scope scope(b);
1185 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1189 r->d()->context()->transform( argv[0].toNumber()
1190 , argv[1].toNumber()
1191 , argv[2].toNumber()
1192 , argv[3].toNumber()
1193 , argv[4].toNumber()
1194 , argv[5].toNumber());
1196 RETURN_RESULT(*thisObject);
1201
1202
1203
1204
1205
1206
1207
1208
1209QV4::ReturnedValue
QQuickJSContext2DPrototype::method_translate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1211 QV4::Scope scope(b);
1212 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1216 r->d()->context()->translate(argv[0].toNumber(), argv[1].toNumber());
1217 RETURN_RESULT(*thisObject);
1223
1224
1225
1226
1227
1228
1229
1230QV4::ReturnedValue
QQuickJSContext2DPrototype::method_resetTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1232 QV4::Scope scope(b);
1233 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1236 r->d()->context()->setTransform(1, 0, 0, 1, 0, 0);
1238 RETURN_RESULT(*thisObject);
1244
1245
1246
1247
1248
1249QV4::ReturnedValue
QQuickJSContext2DPrototype::method_shear(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1251 QV4::Scope scope(b);
1252 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1256 r->d()->context()->shear(argv[0].toNumber(), argv[1].toNumber());
1258 RETURN_RESULT(*thisObject);
1264
1265
1266
1267
1268
1269
1270QV4::ReturnedValue
QQuickJSContext2D::method_get_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1272 QV4::Scope scope(b);
1273 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1276 RETURN_RESULT(QV4::Encode(r->d()->context()->state.globalAlpha));
1279QV4::ReturnedValue
QQuickJSContext2D::method_set_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1281 QV4::Scope scope(b);
1282 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1285 double globalAlpha = argc ? argv[0].toNumber() : qt_qnan();
1288 if (!qt_is_finite(globalAlpha))
1291 if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context()->state.globalAlpha != globalAlpha) {
1292 r->d()->context()->state.globalAlpha = globalAlpha;
1293 r->d()->context()->buffer()->setGlobalAlpha(r->d()->context()->state.globalAlpha);
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376QV4::ReturnedValue
QQuickJSContext2D::method_get_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1378 QV4::Scope scope(b);
1379 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1382 RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context()->state.globalCompositeOperation)));
1385QV4::ReturnedValue
QQuickJSContext2D::method_set_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1387 QV4::Scope scope(b);
1388 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1394 QString mode = argv[0].toQString();
1395 QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
1396 if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String(
"source-over"))
1399 if (cm != r->d()->context()->state.globalCompositeOperation) {
1400 r->d()->context()->state.globalCompositeOperation = cm;
1401 r->d()->context()->buffer()->setGlobalCompositeOperation(cm);
1409 if (color.isValid()) {
1410 if (color.alpha() == 255)
1411 return color.name();
1412 QString alphaString = QString::number(color.alphaF(),
'f');
1413 while (alphaString.endsWith(QLatin1Char(
'0')))
1414 alphaString.chop(1);
1415 if (alphaString.endsWith(QLatin1Char(
'.')))
1416 alphaString += QLatin1Char(
'0');
1417 return QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445QV4::ReturnedValue
QQuickJSContext2D::method_get_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1447 QV4::Scope scope(b);
1448 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1451 if (
auto str = makeColorString(r->d()->context()->state.fillStyle.color().toRgb()); !str.isEmpty())
1452 RETURN_RESULT(scope.engine->newString(std::move(str)));
1453 RETURN_RESULT(r->d()->context()->m_fillStyle.value());
1456QV4::ReturnedValue
QQuickJSContext2D::method_set_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1458 QV4::Scope scope(b);
1459 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1462 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1464 if (value->as<Object>()) {
1465 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1466 if (color.isValid()) {
1467 r->d()->context()->state.fillStyle = color;
1468 r->d()->context()->buffer()->setFillStyle(color);
1469 r->d()->context()->m_fillStyle.set(scope.engine, value);
1471 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1472 if (style && *style->d()->brush != r->d()->context()->state.fillStyle) {
1473 r->d()->context()->state.fillStyle = *style->d()->brush;
1474 r->d()->context()->buffer()->setFillStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1475 r->d()->context()->m_fillStyle.set(scope.engine, value);
1476 r->d()->context()->state.fillPatternRepeatX = style->d()->patternRepeatX;
1477 r->d()->context()->state.fillPatternRepeatY = style->d()->patternRepeatY;
1480 }
else if (value->isString()) {
1481 QColor color = qt_color_from_string(value);
1482 if (color.isValid() && r->d()->context()->state.fillStyle != QBrush(color)) {
1483 r->d()->context()->state.fillStyle = QBrush(color);
1484 r->d()->context()->buffer()->setFillStyle(r->d()->context()->state.fillStyle);
1485 r->d()->context()->m_fillStyle.set(scope.engine, value);
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503QV4::ReturnedValue
QQuickJSContext2D::method_get_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1505 QV4::Scope scope(b);
1506 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1509 RETURN_RESULT(scope.engine->fromVariant(r->d()->context()->state.fillRule));
1512QV4::ReturnedValue
QQuickJSContext2D::method_set_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1514 QV4::Scope scope(b);
1515 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1518 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1520 if ((value->isString() && value->toQString() == QLatin1String(
"WindingFill"))
1521 || (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
1522 r->d()->context()->state.fillRule = Qt::WindingFill;
1523 }
else if ((value->isString() && value->toQStringNoThrow() == QLatin1String(
"OddEvenFill"))
1524 || (value->isInt32() && value->integerValue() == Qt::OddEvenFill)) {
1525 r->d()->context()->state.fillRule = Qt::OddEvenFill;
1529 r->d()->context()->m_path.setFillRule(r->d()->context()->state.fillRule);
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545QV4::ReturnedValue
QQuickJSContext2D::method_get_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1547 QV4::Scope scope(b);
1548 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1551 if (
auto str = makeColorString(r->d()->context()->state.strokeStyle.color().toRgb()); !str.isEmpty())
1552 RETURN_RESULT(scope.engine->newString(std::move(str)));
1553 RETURN_RESULT(r->d()->context()->m_strokeStyle.value());
1556QV4::ReturnedValue
QQuickJSContext2D::method_set_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1558 QV4::Scope scope(b);
1559 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1562 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1564 if (value->as<Object>()) {
1565 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1566 if (color.isValid()) {
1567 r->d()->context()->state.strokeStyle = color;
1568 r->d()->context()->buffer()->setStrokeStyle(color);
1569 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1571 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1572 if (style && *style->d()->brush != r->d()->context()->state.strokeStyle) {
1573 r->d()->context()->state.strokeStyle = *style->d()->brush;
1574 r->d()->context()->buffer()->setStrokeStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1575 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1576 r->d()->context()->state.strokePatternRepeatX = style->d()->patternRepeatX;
1577 r->d()->context()->state.strokePatternRepeatY = style->d()->patternRepeatY;
1578 }
else if (!style && r->d()->context()->state.strokeStyle != QBrush(QColor())) {
1581 r->d()->context()->state.strokeStyle = QBrush(QColor());
1582 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1583 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1586 }
else if (value->isString()) {
1587 QColor color = qt_color_from_string(value);
1588 if (color.isValid() && r->d()->context()->state.strokeStyle != QBrush(color)) {
1589 r->d()->context()->state.strokeStyle = QBrush(color);
1590 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1591 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1614QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createLinearGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1616 QV4::Scope scope(b);
1617 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1621 qreal x0 = argv[0].toNumber();
1622 qreal y0 = argv[1].toNumber();
1623 qreal x1 = argv[2].toNumber();
1624 qreal y1 = argv[3].toNumber();
1626 if (!qt_is_finite(x0)
1627 || !qt_is_finite(y0)
1628 || !qt_is_finite(x1)
1629 || !qt_is_finite(y1)) {
1630 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createLinearGradient(): Incorrect arguments")
1634 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1635 QV4::ScopedObject p(scope, ed->gradientProto.value());
1636 gradient->setPrototypeOf(p);
1637 *gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
1638 RETURN_RESULT(*gradient);
1641 RETURN_RESULT(*thisObject);
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1661QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createRadialGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1663 QV4::Scope scope(b);
1664 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1668 qreal x0 = argv[0].toNumber();
1669 qreal y0 = argv[1].toNumber();
1670 qreal r0 = argv[2].toNumber();
1671 qreal x1 = argv[3].toNumber();
1672 qreal y1 = argv[4].toNumber();
1673 qreal r1 = argv[5].toNumber();
1675 if (!qt_is_finite(x0)
1676 || !qt_is_finite(y0)
1677 || !qt_is_finite(x1)
1678 || !qt_is_finite(r0)
1679 || !qt_is_finite(r1)
1680 || !qt_is_finite(y1)) {
1681 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createRadialGradient(): Incorrect arguments")
1684 if (r0 < 0 || r1 < 0)
1685 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createRadialGradient(): Incorrect arguments")
1689 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1690 QV4::ScopedObject p(scope, ed->gradientProto.value());
1691 gradient->setPrototypeOf(p);
1692 *gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r1, QPointF(x0, y0), r0);
1693 RETURN_RESULT(*gradient);
1696 RETURN_RESULT(*thisObject);
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1715QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createConicalGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1717 QV4::Scope scope(b);
1718 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1722 qreal x = argv[0].toNumber();
1723 qreal y = argv[1].toNumber();
1724 qreal angle = qRadiansToDegrees(argv[2].toNumber());
1725 if (!qt_is_finite(x) || !qt_is_finite(y)) {
1726 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createConicalGradient(): Incorrect arguments");
1729 if (!qt_is_finite(angle)) {
1730 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createConicalGradient(): Incorrect arguments");
1735 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1736 QV4::ScopedObject p(scope, ed->gradientProto.value());
1737 gradient->setPrototypeOf(p);
1738 *gradient->d()->brush = QConicalGradient(x, y, angle);
1739 RETURN_RESULT(*gradient);
1742 RETURN_RESULT(*thisObject);
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createPattern(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1791 QV4::Scope scope(b);
1792 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1796 QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1798 QColor color = QV4::ExecutionEngine::toVariant(
1799 argv[0], QMetaType::fromType<QColor>()).value<QColor>();
1800 if (color.isValid()) {
1801 int patternMode = argv[1].toInt32();
1802 Qt::BrushStyle style = Qt::SolidPattern;
1803 if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
1804 style =
static_cast<Qt::BrushStyle>(patternMode);
1806 *pattern->d()->brush = QBrush(color, style);
1808 QImage patternTexture;
1810 if (
const QV4::Object *o = argv[0].as<Object>()) {
1811 QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral(
"data")));
1812 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
1814 patternTexture = *pixelData->d()->image;
1817 patternTexture = r->d()->context()->createPixmap(QUrl(argv[0].toQStringNoThrow()))->image();
1820 if (!patternTexture.isNull()) {
1821 pattern->d()->brush->setTextureImage(patternTexture);
1823 QString repetition = argv[1].toQStringNoThrow();
1824 if (repetition == QLatin1String(
"repeat") || repetition.isEmpty()) {
1825 pattern->d()->patternRepeatX =
true;
1826 pattern->d()->patternRepeatY =
true;
1827 }
else if (repetition == QLatin1String(
"repeat-x")) {
1828 pattern->d()->patternRepeatX =
true;
1829 pattern->d()->patternRepeatY =
false;
1830 }
else if (repetition == QLatin1String(
"repeat-y")) {
1831 pattern->d()->patternRepeatX =
false;
1832 pattern->d()->patternRepeatY =
true;
1833 }
else if (repetition == QLatin1String(
"no-repeat")) {
1834 pattern->d()->patternRepeatX =
false;
1835 pattern->d()->patternRepeatY =
false;
1843 RETURN_RESULT(*pattern);
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868QV4::ReturnedValue
QQuickJSContext2D::method_get_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1870 QV4::Scope scope(b);
1871 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1874 switch (r->d()->context()->state.lineCap) {
1876 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1878 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"square")));
1883 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"butt")));
1886QV4::ReturnedValue
QQuickJSContext2D::method_set_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1889 return QV4::Encode::undefined();
1891 QV4::Scope scope(b);
1892 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1895 QString lineCap = argv[0].toQString();
1896 Qt::PenCapStyle cap;
1897 if (lineCap == QLatin1String(
"round"))
1899 else if (lineCap == QLatin1String(
"butt"))
1901 else if (lineCap == QLatin1String(
"square"))
1902 cap = Qt::SquareCap;
1906 if (cap != r->d()->context()->state.lineCap) {
1907 r->d()->context()->state.lineCap = cap;
1908 r->d()->context()->buffer()->setLineCap(cap);
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929QV4::ReturnedValue
QQuickJSContext2D::method_get_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1931 QV4::Scope scope(b);
1932 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1935 switch (r->d()->context()->state.lineJoin) {
1937 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1939 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bevel")));
1944 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"miter")));
1947QV4::ReturnedValue
QQuickJSContext2D::method_set_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1949 QV4::Scope scope(b);
1950 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1956 QString lineJoin = argv[0].toQString();
1957 Qt::PenJoinStyle join;
1958 if (lineJoin == QLatin1String(
"round"))
1959 join = Qt::RoundJoin;
1960 else if (lineJoin == QLatin1String(
"bevel"))
1961 join = Qt::BevelJoin;
1962 else if (lineJoin == QLatin1String(
"miter"))
1963 join = Qt::SvgMiterJoin;
1967 if (join != r->d()->context()->state.lineJoin) {
1968 r->d()->context()->state.lineJoin = join;
1969 r->d()->context()->buffer()->setLineJoin(join);
1975
1976
1977
1978QV4::ReturnedValue
QQuickJSContext2D::method_get_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1980 QV4::Scope scope(b);
1981 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1984 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineWidth));
1987QV4::ReturnedValue
QQuickJSContext2D::method_set_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1989 QV4::Scope scope(b);
1990 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1993 qreal w = argc ? argv[0].toNumber() : -1;
1995 if (w > 0 && qt_is_finite(w) && w != r->d()->context()->state.lineWidth) {
1996 r->d()->context()->state.lineWidth = w;
1997 r->d()->context()->buffer()->setLineWidth(w);
2003
2004
2005
2006
2007QV4::ReturnedValue
QQuickJSContext2D::method_get_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2009 QV4::Scope scope(b);
2010 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2013 RETURN_RESULT(QV4::Encode(r->d()->context()->state.miterLimit));
2016QV4::ReturnedValue
QQuickJSContext2D::method_set_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2018 QV4::Scope scope(b);
2019 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2022 qreal ml = argc ? argv[0].toNumber() : -1;
2024 if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context()->state.miterLimit) {
2025 r->d()->context()->state.miterLimit = ml;
2026 r->d()->context()->buffer()->setMiterLimit(ml);
2032
2033
2034
2035
2036
2037
2038QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2040 QV4::Scope scope(b);
2041 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2044 const QList<qreal> pattern = r->d()->context()->state.lineDash;
2045 QV4::ScopedArrayObject array(scope, scope.engine->newArrayObject(pattern.size()));
2046 array->arrayReserve(pattern.size());
2047 for (
int i = 0; i < pattern.size(); i++)
2048 array->put(i, QV4::Value::fromDouble(pattern[i]));
2050 array->setArrayLengthUnchecked(pattern.size());
2052 RETURN_RESULT(*array);
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2081 QV4::Scope scope(b);
2082 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2088 QV4::ScopedArrayObject array(scope, argv[0]);
2092 QV4::ScopedValue v(scope);
2093 const uint arrayLength = array->getLength();
2094 QList<qreal> dashes;
2095 dashes.reserve(arrayLength);
2096 for (uint i = 0; i < arrayLength; ++i) {
2098 const double number = v->toNumber();
2100 if (!qt_is_finite(number) || (number < 0))
2103 dashes.append(v->toNumber());
2105 if (dashes.size() % 2 != 0) {
2109 r->d()->context()->state.lineDash = dashes;
2110 r->d()->context()->buffer()->setLineDash(dashes);
2116
2117
2118
2119
2120
2121
2122
2123
2124QV4::ReturnedValue
QQuickJSContext2D::method_get_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2126 QV4::Scope scope(b);
2127 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2130 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineDashOffset));
2133QV4::ReturnedValue
QQuickJSContext2D::method_set_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2135 QV4::Scope scope(b);
2136 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2139 const qreal offset = argc ? argv[0].toNumber() : -1;
2141 if (qt_is_finite(offset) && offset != r->d()->context()->state.lineDashOffset) {
2142 r->d()->context()->state.lineDashOffset = offset;
2143 r->d()->context()->buffer()->setLineDashOffset(offset);
2151
2152
2153
2154QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2156 QV4::Scope scope(b);
2157 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2160 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowBlur));
2163QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2165 QV4::Scope scope(b);
2166 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2169 qreal blur = argc ? argv[0].toNumber() : -1;
2171 if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context()->state.shadowBlur) {
2172 r->d()->context()->state.shadowBlur = blur;
2173 r->d()->context()->buffer()->setShadowBlur(blur);
2179
2180
2181
2182QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2184 QV4::Scope scope(b);
2185 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2188 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.shadowColor.name()));
2191QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2193 QV4::Scope scope(b);
2194 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2199 color = qt_color_from_string(argv[0]);
2201 if (color.isValid() && color != r->d()->context()->state.shadowColor) {
2202 r->d()->context()->state.shadowColor = color;
2203 r->d()->context()->buffer()->setShadowColor(color);
2210
2211
2212
2213
2214
2215QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2217 QV4::Scope scope(b);
2218 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2221 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetX));
2224QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2226 QV4::Scope scope(b);
2227 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2230 qreal offsetX = argc ? argv[0].toNumber() : qt_qnan();
2231 if (qt_is_finite(offsetX) && offsetX != r->d()->context()->state.shadowOffsetX) {
2232 r->d()->context()->state.shadowOffsetX = offsetX;
2233 r->d()->context()->buffer()->setShadowOffsetX(offsetX);
2238
2239
2240
2241
2242
2243QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2245 QV4::Scope scope(b);
2246 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2249 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetY));
2252QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2254 QV4::Scope scope(b);
2255 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2258 qreal offsetY = argc ? argv[0].toNumber() : qt_qnan();
2259 if (qt_is_finite(offsetY) && offsetY != r->d()->context()->state.shadowOffsetY) {
2260 r->d()->context()->state.shadowOffsetY = offsetY;
2261 r->d()->context()->buffer()->setShadowOffsetY(offsetY);
2266#if QT_CONFIG(quick_path)
2267QV4::ReturnedValue QQuickJSContext2D::method_get_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2269 QV4::Scope scope(b);
2270 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2273 RETURN_RESULT(r->d()->context()->m_v4path.value());
2276QV4::ReturnedValue QQuickJSContext2D::method_set_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2278 QV4::Scope scope(b);
2279 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2280 CHECK_CONTEXT_SETTER(r)
2282 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
2283 r->d()->context()->beginPath();
2284 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
2285 if (!!qobjectWrapper) {
2286 if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
2287 r->d()->context()->m_path = path->path();
2289 QString path =value->toQStringNoThrow();
2290 QQuickSvgParser::parsePathDataFast(path, r->d()->context()->m_path);
2292 r->d()->context()->m_v4path.set(scope.engine, value);
2299
2300
2301
2302
2303
2304QV4::ReturnedValue
QQuickJSContext2DPrototype::method_clearRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2306 QV4::Scope scope(b);
2307 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2312 r->d()->context()->clearRect(argv[0].toNumber(),
2315 argv[3].toNumber());
2317 RETURN_RESULT(*thisObject);
2321
2322
2323
2324
2325
2326
2327QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2329 QV4::Scope scope(b);
2330 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2334 r->d()->context()->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2335 RETURN_RESULT(*thisObject);
2340
2341
2342
2343
2344
2345
2346
2347QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2349 QV4::Scope scope(b);
2350 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2354 r->d()->context()->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2356 RETURN_RESULT(*thisObject);
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arc(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2383 QV4::Scope scope(b);
2384 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2388 bool antiClockwise =
false;
2391 antiClockwise = argv[5].toBoolean();
2393 qreal radius = argv[2].toNumber();
2395 if (qt_is_finite(radius) && radius < 0)
2396 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2398 r->d()->context()->arc(argv[0].toNumber(),
2406 RETURN_RESULT(*thisObject);
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arcTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2435 QV4::Scope scope(b);
2436 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2440 qreal radius = argv[4].toNumber();
2442 if (qt_is_finite(radius) && radius < 0)
2443 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2445 r->d()->context()->arcTo(argv[0].toNumber(),
2452 RETURN_RESULT(*thisObject);
2457
2458
2459
2460
2461QV4::ReturnedValue
QQuickJSContext2DPrototype::method_beginPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2463 QV4::Scope scope(b);
2464 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2467 r->d()->context()->beginPath();
2469 RETURN_RESULT(*thisObject);
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495QV4::ReturnedValue
QQuickJSContext2DPrototype::method_bezierCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2497 QV4::Scope scope(b);
2498 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2502 qreal cp1x = argv[0].toNumber();
2503 qreal cp1y = argv[1].toNumber();
2504 qreal cp2x = argv[2].toNumber();
2505 qreal cp2y = argv[3].toNumber();
2506 qreal x = argv[4].toNumber();
2507 qreal y = argv[5].toNumber();
2509 if (!qt_is_finite(cp1x) || !qt_is_finite(cp1y) || !qt_is_finite(cp2x) || !qt_is_finite(cp2y) || !qt_is_finite(x) || !qt_is_finite(y))
2512 r->d()->context()->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
2514 RETURN_RESULT(*thisObject);
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2543 QV4::Scope scope(b);
2544 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2547 r->d()->context()->clip();
2548 RETURN_RESULT(*thisObject);
2552
2553
2554
2555
2556
2557
2558QV4::ReturnedValue
QQuickJSContext2DPrototype::method_closePath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2560 QV4::Scope scope(b);
2561 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2564 r->d()->context()->closePath();
2566 RETURN_RESULT(*thisObject);
2570
2571
2572
2573
2574
2575
2576
2577
2580 QV4::Scope scope(b);
2581 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2583 r->d()->context()->fill();
2584 RETURN_RESULT(*thisObject);
2588
2589
2590
2591
2592QV4::ReturnedValue
QQuickJSContext2DPrototype::method_lineTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2594 QV4::Scope scope(b);
2595 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2599 qreal x = argv[0].toNumber();
2600 qreal y = argv[1].toNumber();
2602 if (!qt_is_finite(x) || !qt_is_finite(y))
2605 r->d()->context()->lineTo(x, y);
2608 RETURN_RESULT(*thisObject);
2612
2613
2614
2615
2616QV4::ReturnedValue
QQuickJSContext2DPrototype::method_moveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2618 QV4::Scope scope(b);
2619 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2623 qreal x = argv[0].toNumber();
2624 qreal y = argv[1].toNumber();
2626 if (!qt_is_finite(x) || !qt_is_finite(y))
2628 r->d()->context()->moveTo(x, y);
2631 RETURN_RESULT(*thisObject);
2635
2636
2637
2638
2639
2640
2641
2642QV4::ReturnedValue
QQuickJSContext2DPrototype::method_quadraticCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2644 QV4::Scope scope(b);
2645 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2649 qreal cpx = argv[0].toNumber();
2650 qreal cpy = argv[1].toNumber();
2651 qreal x = argv[2].toNumber();
2652 qreal y = argv[3].toNumber();
2654 if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
2657 r->d()->context()->quadraticCurveTo(cpx, cpy, x, y);
2660 RETURN_RESULT(*thisObject);
2664
2665
2666
2667
2668
2669QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2671 QV4::Scope scope(b);
2672 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2676 r->d()->context()->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2677 RETURN_RESULT(*thisObject);
2682
2683
2684
2685
2686
2687
2688QV4::ReturnedValue
QQuickJSContext2DPrototype::method_roundedRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2690 QV4::Scope scope(b);
2691 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2695 r->d()->context()->roundedRect(argv[0].toNumber()
2696 , argv[1].toNumber()
2697 , argv[2].toNumber()
2698 , argv[3].toNumber()
2699 , argv[4].toNumber()
2700 , argv[5].toNumber());
2701 RETURN_RESULT(*thisObject);
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715QV4::ReturnedValue
QQuickJSContext2DPrototype::method_ellipse(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2717 QV4::Scope scope(b);
2718 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2722 r->d()->context()->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2724 RETURN_RESULT(*thisObject);
2729
2730
2731
2732
2733
2734
2735
2736
2737QV4::ReturnedValue
QQuickJSContext2DPrototype::method_text(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2739 QV4::Scope scope(b);
2740 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2744 qreal x = argv[1].toNumber();
2745 qreal y = argv[2].toNumber();
2747 if (!qt_is_finite(x) || !qt_is_finite(y))
2749 r->d()->context()->text(argv[0].toQStringNoThrow(), x, y);
2752 RETURN_RESULT(*thisObject);
2756
2757
2758
2759
2760
2761
2764 QV4::Scope scope(b);
2765 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2768 r->d()->context()->stroke();
2769 RETURN_RESULT(*thisObject);
2774
2775
2776
2777
2778
2779
2780QV4::ReturnedValue
QQuickJSContext2DPrototype::method_isPointInPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2782 QV4::Scope scope(b);
2783 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2786 bool pointInPath =
false;
2788 pointInPath = r->d()->context()->isPointInPath(argv[0].toNumber(), argv[1].toNumber());
2789 RETURN_RESULT(QV4::Value::fromBoolean(pointInPath).asReturnedValue());
2794 QV4::Scope scope(b);
2795 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::drawFocusRing is not supported");
2798QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setCaretSelectionRect(
const QV4::FunctionObject *b,
const QV4::Value *,
const QV4::Value *,
int)
2800 QV4::Scope scope(b);
2801 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::setCaretSelectionRect is not supported");
2806 QV4::Scope scope(b);
2807 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::caretBlinkRate is not supported");
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833QV4::ReturnedValue
QQuickJSContext2D::method_get_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2835 QV4::Scope scope(b);
2836 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2839 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.font.toString()));
2842QV4::ReturnedValue
QQuickJSContext2D::method_set_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2844 QV4::Scope scope(b);
2845 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2848 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2849 if (scope.hasException())
2851 QFont font = qt_font_from_string(s->toQString(), r->d()->context()->state.font);
2852 if (font != r->d()->context()->state.font) {
2853 r->d()->context()->state.font = font;
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873QV4::ReturnedValue
QQuickJSContext2D::method_get_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2875 QV4::Scope scope(b);
2876 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2879 switch (r->d()->context()->state.textAlign) {
2881 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"end")));
2883 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"left")));
2885 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"right")));
2887 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"center")));
2892 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"start")));
2895QV4::ReturnedValue
QQuickJSContext2D::method_set_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2897 QV4::Scope scope(b);
2898 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2901 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2902 if (scope.hasException())
2904 QString textAlign = s->toQString();
2907 if (textAlign == QLatin1String(
"start"))
2909 else if (textAlign == QLatin1String(
"end"))
2911 else if (textAlign == QLatin1String(
"left"))
2913 else if (textAlign == QLatin1String(
"right"))
2915 else if (textAlign == QLatin1String(
"center"))
2920 if (ta != r->d()->context()->state.textAlign)
2921 r->d()->context()->state.textAlign = ta;
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940QV4::ReturnedValue
QQuickJSContext2D::method_get_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2942 QV4::Scope scope(b);
2943 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2946 switch (r->d()->context()->state.textBaseline) {
2947 case QQuickContext2D::Hanging:
2948 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"hanging")));
2949 case QQuickContext2D::Top:
2950 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"top")));
2951 case QQuickContext2D::Bottom:
2952 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bottom")));
2953 case QQuickContext2D::Middle:
2954 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"middle")));
2955 case QQuickContext2D::Alphabetic:
2959 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"alphabetic")));
2962QV4::ReturnedValue
QQuickJSContext2D::method_set_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2964 QV4::Scope scope(b);
2965 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2967 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2968 if (scope.hasException())
2970 QString textBaseline = s->toQString();
2972 QQuickContext2D::TextBaseLineType tb;
2973 if (textBaseline == QLatin1String(
"alphabetic"))
2974 tb = QQuickContext2D::Alphabetic;
2975 else if (textBaseline == QLatin1String(
"hanging"))
2976 tb = QQuickContext2D::Hanging;
2977 else if (textBaseline == QLatin1String(
"top"))
2978 tb = QQuickContext2D::Top;
2979 else if (textBaseline == QLatin1String(
"bottom"))
2980 tb = QQuickContext2D::Bottom;
2981 else if (textBaseline == QLatin1String(
"middle"))
2982 tb = QQuickContext2D::Middle;
2986 if (tb != r->d()->context()->state.textBaseline)
2987 r->d()->context()->state.textBaseline = tb;
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3004 QV4::Scope scope(b);
3005 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3009 qreal x = argv[1].toNumber();
3010 qreal y = argv[2].toNumber();
3011 if (!qt_is_finite(x) || !qt_is_finite(y))
3013 QPainterPath textPath = r->d()->context()->createTextGlyphs(x, y, argv[0].toQStringNoThrow());
3014 r->d()->context()->buffer()->fill(textPath);
3017 RETURN_RESULT(*thisObject);
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3031 QV4::Scope scope(b);
3032 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3036 r->d()->context()->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(),
false);
3038 RETURN_RESULT(*thisObject);
3042
3043
3044
3045
3046
3047
3048QV4::ReturnedValue
QQuickJSContext2DPrototype::method_measureText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3050 QV4::Scope scope(b);
3051 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3055 QFontMetrics fm(r->d()->context()->state.font);
3056 uint width = fm.horizontalAdvance(argv[0].toQStringNoThrow());
3057 QV4::ScopedObject tm(scope, scope.engine->newObject());
3058 tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral(
"width"))).getPointer(),
3059 QV4::ScopedValue(scope, QV4::Value::fromDouble(width)));
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124QV4::ReturnedValue
QQuickJSContext2DPrototype::method_drawImage(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3126 QV4::Scope scope(b);
3127 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3130 qreal sx, sy, sw, sh, dx, dy, dw, dh;
3136 if (!r->d()->context()->state.invertibleCTM)
3139 QQmlRefPointer<QQuickCanvasPixmap> pixmap;
3141 QV4::ScopedValue arg(scope, argv[0]);
3142 if (arg->isString()) {
3143 QUrl url(arg->toQString());
3145 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3147 pixmap = r->d()->context()->createPixmap(url);
3148 }
else if (arg->isObject()) {
3149 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, arg);
3150 if (!!qobjectWrapper) {
3151 if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
3152 pixmap = r->d()->context()->createPixmap(imageItem->source());
3154 QImage img = canvas->toImage();
3156 pixmap.adopt(
new QQuickCanvasPixmap(img));
3158 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3161 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
3163 QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3164 if (pix && !pix->d()->image->isNull()) {
3165 pixmap.adopt(
new QQuickCanvasPixmap(*pix->d()->image));
3167 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3170 QUrl url(arg->toQStringNoThrow());
3172 pixmap = r->d()->context()->createPixmap(url);
3174 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3178 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3181 if (pixmap.isNull() || !pixmap->isValid())
3185 sx = argv[1].toNumber();
3186 sy = argv[2].toNumber();
3187 sw = argv[3].toNumber();
3188 sh = argv[4].toNumber();
3189 dx = argv[5].toNumber();
3190 dy = argv[6].toNumber();
3191 dw = argv[7].toNumber();
3192 dh = argv[8].toNumber();
3193 }
else if (argc >= 5) {
3196 sw = pixmap->width();
3197 sh = pixmap->height();
3198 dx = argv[1].toNumber();
3199 dy = argv[2].toNumber();
3200 dw = argv[3].toNumber();
3201 dh = argv[4].toNumber();
3202 }
else if (argc >= 3) {
3203 dx = argv[1].toNumber();
3204 dy = argv[2].toNumber();
3207 sw = pixmap->width();
3208 sh = pixmap->height();
3215 if (!qt_is_finite(sx)
3216 || !qt_is_finite(sy)
3217 || !qt_is_finite(sw)
3218 || !qt_is_finite(sh)
3219 || !qt_is_finite(dx)
3220 || !qt_is_finite(dy)
3221 || !qt_is_finite(dw)
3222 || !qt_is_finite(dh))
3229 || sx + sw > pixmap->width()
3230 || sy + sh > pixmap->height()
3231 || sx + sw < 0 || sy + sh < 0) {
3232 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"drawImage(), index size error");
3235 r->d()->context()->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
3237 RETURN_RESULT(*thisObject);
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3261
3262
3263
3264QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_width(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3266 QV4::Scope scope(b);
3267 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3270 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3271 int width = r ? r->d()->image->width() : 0;
3272 RETURN_RESULT(QV4::Encode(width));
3276
3277
3278
3279QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_height(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3281 QV4::Scope scope(b);
3282 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3285 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3286 int height = r ? r->d()->image->height() : 0;
3287 RETURN_RESULT(QV4::Encode(height));
3291
3292
3293
3294QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_data(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3296 QV4::Scope scope(b);
3297 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3300 RETURN_RESULT(imageData->d()->pixelData);
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3316
3317
3318
3319
3320
3321QV4::ReturnedValue
QQuickJSContext2DPixelData::proto_get_length(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3323 QV4::Scope scope(b);
3324 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>());
3325 if (!r || r->d()->image->isNull())
3328 RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4));
3331QV4::ReturnedValue
QQuickJSContext2DPixelData::virtualGet(
const QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value *receiver,
bool *hasProperty)
3333 if (!id.isArrayIndex())
3334 return QV4::Object::virtualGet(m, id, receiver, hasProperty);
3336 uint index = id.asArrayIndex();
3339 QV4::Scope scope(v4);
3340 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<
const QQuickJSContext2DPixelData *>(m));
3342 if (index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4)) {
3344 *hasProperty =
true;
3345 const quint32 w = r->d()->image->width();
3346 const quint32 row = (index / 4) / w;
3347 const quint32 col = (index / 4) % w;
3348 const QRgb* pixel =
reinterpret_cast<
const QRgb*>(r->d()->image->constScanLine(row));
3350 switch (index % 4) {
3352 return QV4::Encode(qRed(*pixel));
3354 return QV4::Encode(qGreen(*pixel));
3356 return QV4::Encode(qBlue(*pixel));
3358 return QV4::Encode(qAlpha(*pixel));
3363 *hasProperty =
false;
3364 return QV4::Encode::undefined();
3367bool QQuickJSContext2DPixelData::virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, QV4::Value *receiver)
3369 if (!id.isArrayIndex())
3370 return Object::virtualPut(m, id, value, receiver);
3374 QV4::Scope scope(v4);
3375 if (scope.hasException())
3378 uint index = id.asArrayIndex();
3379 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<QQuickJSContext2DPixelData *>(m));
3381 const int v = value.toInt32();
3382 if (r && index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4) && v >= 0 && v <= 255) {
3383 const quint32 w = r->d()->image->width();
3384 const quint32 row = (index / 4) / w;
3385 const quint32 col = (index / 4) % w;
3387 QRgb* pixel =
reinterpret_cast<QRgb*>(r->d()->image->scanLine(row));
3389 switch (index % 4) {
3391 *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
3394 *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
3397 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
3400 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
3409
3410
3411
3412
3414
3415
3416
3417
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3431 QV4::Scope scope(b);
3432 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3436 QV4::ScopedValue arg0(scope, argv[0]);
3437 QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
3439 QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3441 qreal w = pa->d()->image->width();
3442 qreal h = pa->d()->image->height();
3443 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3445 }
else if (arg0->isString()) {
3446 QImage image = r->d()->context()->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
3447 RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, std::move(image)));
3449 }
else if (argc == 2) {
3450 qreal w = argv[0].toNumber();
3451 qreal h = argv[1].toNumber();
3453 if (!qt_is_finite(w) || !qt_is_finite(h))
3454 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createImageData(): invalid arguments");
3457 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3459 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createImageData(): invalid arguments");
3465
3466
3467
3468
3469
3470QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3472 QV4::Scope scope(b);
3473 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3477 qreal x = argv[0].toNumber();
3478 qreal y = argv[1].toNumber();
3479 qreal w = argv[2].toNumber();
3480 qreal h = argv[3].toNumber();
3481 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3482 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"getImageData(): Invalid arguments");
3484 if (w <= 0 || h <= 0)
3485 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"getImageData(): Invalid arguments");
3487 QImage image = r->d()->context()->canvas()->toImage(QRectF(x, y, w, h));
3488 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, std::move(image)));
3490 RETURN_RESULT(QV4::Encode::null());
3494
3495
3496
3497
3498
3499
3500
3501
3502QV4::ReturnedValue
QQuickJSContext2DPrototype::method_putImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3504 QV4::Scope scope(b);
3505 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3510 QV4::ScopedValue arg0(scope, argv[0]);
3511 if (!arg0->isObject())
3512 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"Context2D::putImageData, the image data type mismatch");
3514 qreal dx = argv[1].toNumber();
3515 qreal dy = argv[2].toNumber();
3516 qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
3518 if (!qt_is_finite(dx) || !qt_is_finite(dy))
3519 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3521 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
3525 QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3527 w = pixelArray->d()->image->width();
3528 h = pixelArray->d()->image->height();
3531 dirtyX = argv[3].toNumber();
3532 dirtyY = argv[4].toNumber();
3533 dirtyWidth = argv[5].toNumber();
3534 dirtyHeight = argv[6].toNumber();
3536 if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
3537 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3540 if (dirtyWidth < 0) {
3541 dirtyX = dirtyX+dirtyWidth;
3542 dirtyWidth = -dirtyWidth;
3545 if (dirtyHeight < 0) {
3546 dirtyY = dirtyY+dirtyHeight;
3547 dirtyHeight = -dirtyHeight;
3551 dirtyWidth = dirtyWidth+dirtyX;
3556 dirtyHeight = dirtyHeight+dirtyY;
3560 if (dirtyX+dirtyWidth > w) {
3561 dirtyWidth = w - dirtyX;
3564 if (dirtyY+dirtyHeight > h) {
3565 dirtyHeight = h - dirtyY;
3568 if (dirtyWidth <=0 || dirtyHeight <= 0)
3577 QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
3578 r->d()->context()->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
3581 RETURN_RESULT(*thisObject);
3585
3586
3587
3588
3589
3590
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606QV4::ReturnedValue
QQuickContext2DStyle::gradient_proto_addColorStop(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3608 QV4::Scope scope(b);
3609 QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>());
3611 THROW_GENERIC_ERROR(
"Not a CanvasGradient object");
3615 if (!style->d()->brush->gradient())
3616 THROW_GENERIC_ERROR(
"Not a valid CanvasGradient object, can't get the gradient information");
3617 QGradient gradient = *(style->d()->brush->gradient());
3618 qreal pos = argv[0].toNumber();
3621 if (argv[1].as<Object>()) {
3622 color = QV4::ExecutionEngine::toVariant(
3623 argv[1], QMetaType::fromType<QColor>()).value<QColor>();
3625 color = qt_color_from_string(argv[1]);
3627 if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
3628 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"CanvasGradient: parameter offset out of range");
3631 if (color.isValid()) {
3632 gradient.setColorAt(pos, color);
3634 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"CanvasGradient: parameter color is not a valid color string");
3636 *style->d()->brush = gradient;
3639 return thisObject->asReturnedValue();
3644 if (!state.invertibleCTM)
3647 if (!qt_is_finite(x) || !qt_is_finite(y))
3650 QTransform newTransform = state.matrix;
3651 newTransform.scale(x, y);
3653 if (!newTransform.isInvertible()) {
3654 state.invertibleCTM =
false;
3658 state.matrix = newTransform;
3659 buffer()->updateMatrix(state.matrix);
3660 m_path = QTransform().scale(1.0 / x, 1.0 / y).map(m_path);
3665 if (!state.invertibleCTM)
3668 if (!qt_is_finite(angle))
3671 QTransform newTransform =state.matrix;
3672 newTransform.rotate(qRadiansToDegrees(angle));
3674 if (!newTransform.isInvertible()) {
3675 state.invertibleCTM =
false;
3679 state.matrix = newTransform;
3680 buffer()->updateMatrix(state.matrix);
3681 m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
3686 if (!state.invertibleCTM)
3689 if (!qt_is_finite(h) || !qt_is_finite(v))
3692 QTransform newTransform = state.matrix;
3693 newTransform.shear(h, v);
3695 if (!newTransform.isInvertible()) {
3696 state.invertibleCTM =
false;
3700 state.matrix = newTransform;
3701 buffer()->updateMatrix(state.matrix);
3702 m_path = QTransform().shear(-h, -v).map(m_path);
3707 if (!state.invertibleCTM)
3710 if (!qt_is_finite(x) || !qt_is_finite(y))
3713 QTransform newTransform = state.matrix;
3714 newTransform.translate(x, y);
3716 if (!newTransform.isInvertible()) {
3717 state.invertibleCTM =
false;
3721 state.matrix = newTransform;
3722 buffer()->updateMatrix(state.matrix);
3723 m_path = QTransform().translate(-x, -y).map(m_path);
3728 if (!state.invertibleCTM)
3731 if (!qt_is_finite(a) || !qt_is_finite(b) || !qt_is_finite(c) || !qt_is_finite(d) || !qt_is_finite(e) || !qt_is_finite(f))
3734 QTransform transform(a, b, c, d, e, f);
3735 QTransform newTransform = state.matrix * transform;
3737 if (!newTransform.isInvertible()) {
3738 state.invertibleCTM =
false;
3741 state.matrix = newTransform;
3742 buffer()->updateMatrix(state.matrix);
3743 m_path = transform.inverted().map(m_path);
3748 if (!qt_is_finite(a) || !qt_is_finite(b) || !qt_is_finite(c) || !qt_is_finite(d) || !qt_is_finite(e) || !qt_is_finite(f))
3751 QTransform ctm = state.matrix;
3752 if (!ctm.isInvertible())
3755 state.matrix = ctm.inverted() * state.matrix;
3756 m_path = ctm.map(m_path);
3757 state.invertibleCTM =
true;
3758 transform(a, b, c, d, e, f);
3763 if (!state.invertibleCTM)
3766 if (!m_path.elementCount())
3769 m_path.setFillRule(state.fillRule);
3775 if (!state.invertibleCTM)
3778 QPainterPath clipPath = m_path;
3779 clipPath.closeSubpath();
3781 state.clipPath = clipPath.intersected(state.clipPath);
3784 state.clipPath = clipPath;
3786 buffer()->clip(state.clip, state.clipPath);
3791 if (!state.invertibleCTM)
3794 if (!m_path.elementCount())
3802 if (!state.invertibleCTM)
3805 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3808 buffer()->fillRect(QRectF(x, y, w, h));
3813 if (!state.invertibleCTM)
3816 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3819 buffer()->strokeRect(QRectF(x, y, w, h));
3824 if (!state.invertibleCTM)
3827 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3830 buffer()->clearRect(QRectF(x, y, w, h));
3835 if (!state.invertibleCTM)
3838 if (!qt_is_finite(x) || !qt_is_finite(y))
3841 QPainterPath textPath = createTextGlyphs(x, y, text);
3851 if (!m_path.elementCount())
3853 m_path = QPainterPath();
3858 if (!m_path.elementCount())
3861 QRectF boundRect = m_path.boundingRect();
3862 if (boundRect.width() || boundRect.height())
3863 m_path.closeSubpath();
3870 if (!state.invertibleCTM)
3874 m_path.moveTo(QPointF(x, y));
3879 if (!state.invertibleCTM)
3884 if (!m_path.elementCount())
3886 else if (m_path.currentPosition() != pt)
3893 if (!state.invertibleCTM)
3896 if (!m_path.elementCount())
3897 m_path.moveTo(QPointF(cpx, cpy));
3900 if (m_path.currentPosition() != pt)
3901 m_path.quadTo(QPointF(cpx, cpy), pt);
3905 qreal cp2x, qreal cp2y,
3908 if (!state.invertibleCTM)
3911 if (!m_path.elementCount())
3912 m_path.moveTo(QPointF(cp1x, cp1y));
3915 if (m_path.currentPosition() != pt)
3916 m_path.cubicTo(QPointF(cp1x, cp1y), QPointF(cp2x, cp2y), pt);
3921 QPointF p0(m_path.currentPosition());
3923 QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
3924 QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
3925 qreal p1p0_length =
std::hypot(p1p0.x(), p1p0.y());
3926 qreal p1p2_length =
std::hypot(p1p2.x(), p1p2.y());
3928 qreal cos_phi = QPointF::dotProduct(p1p0, p1p2) / (p1p0_length * p1p2_length);
3933 if (qFuzzyCompare(
std::abs(cos_phi), qreal(1.0))) {
3938 qreal tangent = radius /
std::tan(
std::acos(cos_phi) / 2);
3939 qreal factor_p1p0 = tangent / p1p0_length;
3940 QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
3942 QPointF orth_p1p0(p1p0.y(), -p1p0.x());
3943 qreal orth_p1p0_length =
std::hypot(orth_p1p0.x(), orth_p1p0.y());
3944 qreal factor_ra = radius / orth_p1p0_length;
3947 qreal cos_alpha = QPointF::dotProduct(orth_p1p0, p1p2) / (orth_p1p0_length * p1p2_length);
3948 if (cos_alpha < 0.f)
3949 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3951 QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
3954 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3955 qreal sa =
std::atan2(orth_p1p0.y(), orth_p1p0.x());
3958 bool anticlockwise =
false;
3960 qreal factor_p1p2 = tangent / p1p2_length;
3961 QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
3962 QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
3963 qreal ea =
std::atan2(orth_p1p2.y(), orth_p1p2.x());
3964 if ((sa > ea) && ((sa - ea) <
M_PI))
3965 anticlockwise =
true;
3966 if ((sa < ea) && ((ea - sa) >
M_PI))
3967 anticlockwise =
true;
3969 arc(p.x(), p.y(), radius, sa, ea, anticlockwise);
3976 if (!state.invertibleCTM)
3979 if (!qt_is_finite(x1) || !qt_is_finite(y1) || !qt_is_finite(x2) || !qt_is_finite(y2) || !qt_is_finite(radius))
3983 QPointF end(x2, y2);
3985 if (!m_path.elementCount())
3987 else if (st == m_path.currentPosition() || st == end || !radius)
3990 addArcTo(st, end, radius);
3995 if (!state.invertibleCTM)
3997 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4001 m_path.moveTo(x, y);
4004 m_path.addRect(x, y, w, h);
4011 if (!state.invertibleCTM)
4014 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h) || !qt_is_finite(xr) || !qt_is_finite(yr))
4018 m_path.moveTo(x, y);
4021 m_path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
4027 if (!state.invertibleCTM)
4030 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4034 m_path.moveTo(x, y);
4038 m_path.addEllipse(x, y, w, h);
4043 if (!state.invertibleCTM)
4047 path.addText(x, y, state.font, str);
4048 m_path.addPath(path);
4053 if (!state.invertibleCTM)
4056 if (!qt_is_finite(xc) || !qt_is_finite(yc) || !qt_is_finite(sar) || !qt_is_finite(ear) || !qt_is_finite(radius))
4070 antiClockWise = !antiClockWise;
4073 float sa = qRadiansToDegrees(sar);
4074 float ea = qRadiansToDegrees(ear);
4078 double xs = xc - radius;
4079 double ys = yc - radius;
4080 double width = radius*2;
4081 double height = radius*2;
4082 if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
4088 if (!antiClockWise && (ea < sa)) {
4090 }
else if (antiClockWise && (sa < ea)) {
4095 if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
4096 qFuzzyCompare(qAbs(span), 360))) {
4102 if (!m_path.elementCount())
4103 m_path.arcMoveTo(xs, ys, width, height, sa);
4105 m_path.lineTo(xc, yc);
4109 m_path.arcTo(xs, ys, width, height, sa, span);
4112int baseLineOffset(QQuickContext2D::TextBaseLineType value,
const QFontMetrics &metrics)
4116 case QQuickContext2D::Top:
4117 case QQuickContext2D::Hanging:
4119 case QQuickContext2D::Middle:
4120 offset = (metrics.ascent() >> 1) + metrics.height() - metrics.ascent();
4122 case QQuickContext2D::Alphabetic:
4123 offset = metrics.ascent();
4125 case QQuickContext2D::Bottom:
4126 offset = metrics.height();
4135 if (value == QQuickContext2D::Start)
4136 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Left : QQuickContext2D::Right;
4137 else if (value == QQuickContext2D::End)
4138 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Right: QQuickContext2D::Left;
4141 offset = metrics.horizontalAdvance(text) / 2;
4144 offset = metrics.horizontalAdvance(text);
4155 m_grabbedImage = grab;
4159QQmlRefPointer<QQuickCanvasPixmap>
QQuickContext2D::createPixmap(
const QUrl& url, QSizeF sourceSize)
4161 return m_canvas->loadedPixmap(url, sourceSize);
4166 const QFontMetrics metrics(state.font);
4167 int yoffset = baseLineOffset(
static_cast<QQuickContext2D::TextBaseLineType>(state.textBaseline), metrics);
4168 int xoffset = textAlignOffset(
static_cast<QQuickContext2D::TextAlignType>(state.textAlign), metrics, text);
4170 QPainterPath textPath;
4172 textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
4177static inline bool areCollinear(
const QPointF& a,
const QPointF& b,
const QPointF& c)
4180 return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x()));
4185 return (p >= a && p <= b) || (p >= b && p <= a);
4190 if (!state.invertibleCTM)
4193 if (!m_path.elementCount())
4196 if (!qt_is_finite(x) || !qt_is_finite(y))
4199 QPointF point(x, y);
4200 QTransform ctm = state.matrix;
4201 QPointF p = ctm.inverted().map(point);
4202 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y()))
4205 const_cast<
QQuickContext2D *>(
this)->m_path.setFillRule(state.fillRule);
4207 bool contains = m_path.contains(p);
4211 QPolygonF border = m_path.toFillPolygon();
4213 QPointF p1 = border.at(0);
4216 for (
int i = 1; i < border.size(); ++i) {
4218 if (areCollinear(p, p1, p2)
4221 && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
4222 withinRange(p.x(), p1.x(), p2.x()) :
4223 withinRange(p.y(), p1.y(), p2.y()))) {
4256 return m_v4value.value();
4261 return QStringList() << QStringLiteral(
"2d");
4268 m_canvas = canvasItem;
4269 m_renderTarget = canvasItem->renderTarget();
4270 m_renderStrategy = canvasItem->renderStrategy();
4273 if (m_renderTarget == QQuickCanvasItem::FramebufferObject
4274 && m_renderStrategy == QQuickCanvasItem::Threaded
4275 && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
4276 m_renderTarget = QQuickCanvasItem::Image;
4282 if (m_renderTarget == QQuickCanvasItem::FramebufferObject)
4283 m_renderTarget = QQuickCanvasItem::Image;
4285 m_texture =
new QQuickContext2DImageTexture;
4288 m_texture->setCanvasWindow(canvasItem->canvasWindow().toRect());
4289 m_texture->setTileSize(canvasItem->tileSize());
4290 m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
4291 m_texture->setSmooth(canvasItem->smooth());
4292 m_texture->setAntialiasing(canvasItem->antialiasing());
4293 m_texture->setOnCustomThread(m_renderStrategy == QQuickCanvasItem::Threaded);
4294 m_thread = QThread::currentThread();
4296 QThread *renderThread = m_thread;
4297 if (m_renderStrategy == QQuickCanvasItem::Threaded)
4299 if (renderThread && renderThread != QThread::currentThread())
4301 connect(
m_texture, SIGNAL(textureChanged()), SIGNAL(textureChanged()));
4306void QQuickContext2D::
prepare(
const QSize& canvasSize,
const QSize& tileSize,
const QRect& canvasWindow,
const QRect& dirtyRect,
bool smooth,
bool antialiasing)
4308 if (m_texture->thread() == QThread::currentThread()) {
4309 m_texture->canvasChanged(canvasSize, tileSize, canvasWindow, dirtyRect, smooth, antialiasing);
4311 QEvent *e =
new QQuickContext2DTexture::CanvasChangeEvent(canvasSize,
4317 QCoreApplication::postEvent(m_texture, e);
4324 if (m_texture->thread() == QThread::currentThread())
4327 QCoreApplication::postEvent(m_texture,
new QQuickContext2DTexture::PaintEvent(m_buffer));
4339 if (m_texture->thread() == QThread::currentThread()) {
4342 }
else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
4343 qWarning() <<
"Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode";
4347 QCoreApplication::postEvent(m_texture,
new QEvent(QEvent::Type(QEvent::User + 10)));
4348 QMetaObject::invokeMethod(m_texture,
4350 Qt::BlockingQueuedConnection,
4351 Q_ARG(QRectF, bounds));
4353 QImage img = m_grabbedImage;
4354 m_grabbedImage = QImage();
4362 QV4::Scope scope(v4);
4364 QV4::ScopedObject proto(scope, QQuickJSContext2DPrototype::create(v4));
4365 proto->defineAccessorProperty(QStringLiteral(
"strokeStyle"), QQuickJSContext2D::method_get_strokeStyle, QQuickJSContext2D::method_set_strokeStyle);
4366 proto->defineAccessorProperty(QStringLiteral(
"font"), QQuickJSContext2D::method_get_font, QQuickJSContext2D::method_set_font);
4367 proto->defineAccessorProperty(QStringLiteral(
"fillRule"), QQuickJSContext2D::method_get_fillRule, QQuickJSContext2D::method_set_fillRule);
4368 proto->defineAccessorProperty(QStringLiteral(
"globalAlpha"), QQuickJSContext2D::method_get_globalAlpha, QQuickJSContext2D::method_set_globalAlpha);
4369 proto->defineAccessorProperty(QStringLiteral(
"lineCap"), QQuickJSContext2D::method_get_lineCap, QQuickJSContext2D::method_set_lineCap);
4370 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetX"), QQuickJSContext2D::method_get_shadowOffsetX, QQuickJSContext2D::method_set_shadowOffsetX);
4371 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetY"), QQuickJSContext2D::method_get_shadowOffsetY, QQuickJSContext2D::method_set_shadowOffsetY);
4372 proto->defineAccessorProperty(QStringLiteral(
"globalCompositeOperation"), QQuickJSContext2D::method_get_globalCompositeOperation, QQuickJSContext2D::method_set_globalCompositeOperation);
4373 proto->defineAccessorProperty(QStringLiteral(
"miterLimit"), QQuickJSContext2D::method_get_miterLimit, QQuickJSContext2D::method_set_miterLimit);
4374 proto->defineAccessorProperty(QStringLiteral(
"fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle);
4375 proto->defineAccessorProperty(QStringLiteral(
"shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor);
4376 proto->defineAccessorProperty(QStringLiteral(
"textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline);
4377#if QT_CONFIG(quick_path)
4378 proto->defineAccessorProperty(QStringLiteral(
"path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path);
4380 proto->defineAccessorProperty(QStringLiteral(
"lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin);
4381 proto->defineAccessorProperty(QStringLiteral(
"lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
4382 proto->defineAccessorProperty(QStringLiteral(
"textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
4383 proto->defineAccessorProperty(QStringLiteral(
"shadowBlur"), QQuickJSContext2D::method_get_shadowBlur, QQuickJSContext2D::method_set_shadowBlur);
4384 proto->defineAccessorProperty(QStringLiteral(
"lineDashOffset"), QQuickJSContext2D::method_get_lineDashOffset, QQuickJSContext2D::method_set_lineDashOffset);
4385 contextPrototype = proto;
4387 proto = scope.engine->newObject();
4388 proto->defineDefaultProperty(QStringLiteral(
"addColorStop"), QQuickContext2DStyle::gradient_proto_addColorStop, 0);
4389 gradientProto = proto;
4391 proto = scope.engine->newObject();
4392 proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length,
nullptr);
4393 pixelArrayProto = proto;
4402 if (m_stateStack.isEmpty())
4407 if (state.matrix != newState.matrix)
4408 buffer()->updateMatrix(newState.matrix);
4410 if (newState.globalAlpha != state.globalAlpha)
4411 buffer()->setGlobalAlpha(newState.globalAlpha);
4413 if (newState.globalCompositeOperation != state.globalCompositeOperation)
4414 buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
4416 if (newState.fillStyle != state.fillStyle)
4417 buffer()->setFillStyle(newState.fillStyle);
4419 if (newState.strokeStyle != state.strokeStyle)
4420 buffer()->setStrokeStyle(newState.strokeStyle);
4422 if (newState.lineWidth != state.lineWidth)
4423 buffer()->setLineWidth(newState.lineWidth);
4425 if (newState.lineCap != state.lineCap)
4426 buffer()->setLineCap(newState.lineCap);
4428 if (newState.lineJoin != state.lineJoin)
4429 buffer()->setLineJoin(newState.lineJoin);
4431 if (newState.miterLimit != state.miterLimit)
4432 buffer()->setMiterLimit(newState.miterLimit);
4434 if (newState.clip != state.clip || newState.clipPath != state.clipPath)
4437 if (newState.shadowBlur != state.shadowBlur)
4438 buffer()->setShadowBlur(newState.shadowBlur);
4440 if (newState.shadowColor != state.shadowColor)
4441 buffer()->setShadowColor(newState.shadowColor);
4443 if (newState.shadowOffsetX != state.shadowOffsetX)
4444 buffer()->setShadowOffsetX(newState.shadowOffsetX);
4446 if (newState.shadowOffsetY != state.shadowOffsetY)
4447 buffer()->setShadowOffsetY(newState.shadowOffsetY);
4449 if (newState.lineDash != state.lineDash)
4450 buffer()->setLineDash(newState.lineDash);
4452 m_path = state.matrix.map(m_path);
4454 m_path = state.matrix.inverted().map(m_path);
4458 m_stateStack.push(state);
4465 m_path = QPainterPath();
4467 newState.clipPath.setFillRule(Qt::WindingFill);
4469 m_stateStack.clear();
4470 m_stateStack.push(newState);
4472 m_buffer->clearRect(QRectF(0, 0, m_canvas->width(), m_canvas->height()));
4489 QV4::Scope scope(engine);
4490 QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->allocate<QQuickJSContext2D>());
4491 QV4::ScopedObject p(scope, ed->contextPrototype.value());
4492 wrapper->setPrototypeOf(p);
4493 wrapper->d()->setContext(
this);
4494 m_v4value = wrapper;
4500#include "moc_qquickcontext2d_p.cpp"
QQuickContext2DCommandBuffer()
QV4::PersistentValue gradientProto
~QQuickContext2DEngineData()
QQuickContext2DEngineData(QV4::ExecutionEngine *engine)
QV4::PersistentValue contextPrototype
QV4::PersistentValue pixelArrayProto
static QQuickContext2DRenderThread * instance(QQmlEngine *engine)
QPainterPath createTextGlyphs(qreal x, qreal y, const QString &text)
bool isPointInPath(qreal x, qreal y) const
void arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius)
void translate(qreal x, qreal y)
QQuickContext2DTexture * texture() const
QV4::ExecutionEngine * v4Engine() const override
void strokeRect(qreal x, qreal y, qreal w, qreal h)
void text(const QString &str, qreal x, qreal y)
void ellipse(qreal x, qreal y, qreal w, qreal h)
QV4::ExecutionEngine * m_v4engine
QV4::ReturnedValue v4value() const override
void setTransform(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f)
QImage toImage(const QRectF &bounds) override
void arc(qreal x, qreal y, qreal radius, qreal startAngle, qreal endAngle, bool anticlockwise)
QStringList contextNames() const override
void setGrabbedImage(const QImage &grab)
void lineTo(qreal x, qreal y)
QQuickContext2D(QObject *parent=nullptr)
QQuickContext2DCommandBuffer * buffer() const
void scale(qreal x, qreal y)
void bezierCurveTo(qreal cp1x, qreal cp1y, qreal cp2x, qreal cp2y, qreal x, qreal y)
void prepare(const QSize &canvasSize, const QSize &tileSize, const QRect &canvasWindow, const QRect &dirtyRect, bool smooth, bool antialiasing) override
QQuickContext2DTexture * m_texture
void quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y)
void drawText(const QString &text, qreal x, qreal y, bool fill)
void roundedRect(qreal x, qreal y, qreal w, qreal h, qreal xr, qreal yr)
void setV4Engine(QV4::ExecutionEngine *eng) override
void shear(qreal h, qreal v)
QQuickContext2DCommandBuffer * m_buffer
void clearRect(qreal x, qreal y, qreal w, qreal h)
void addArcTo(const QPointF &p1, const QPointF &p2, qreal radius)
void transform(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f)
void rect(qreal x, qreal y, qreal w, qreal h)
void moveTo(qreal x, qreal y)
void fillRect(qreal x, qreal y, qreal w, qreal h)
static bool withinRange(qreal p, qreal a, qreal b)
#define qClamp(val, min, max)
static QPainter::CompositionMode qt_composite_mode_from_string(const QString &compositeOperator)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DPrototype)
static QFont qt_font_from_string(const QString &fontString, const QFont ¤tFont)
QImage qt_image_convolute_filter(const QImage &src, const QList< qreal > &weights, int radius=0)
DEFINE_OBJECT_VTABLE(QQuickContext2DStyle)
static int textAlignOffset(QQuickContext2D::TextAlignType value, const QFontMetrics &metrics, const QString &text)
#define CHECK_CONTEXT(r)
\qmltype Context2D \nativetype QQuickContext2D \inqmlmodule QtQuick
#define Q_TRY_SET_TOKEN(token, value, setStatement)
int baseLineOffset(QQuickContext2D::TextBaseLineType value, const QFontMetrics &metrics)
void qt_image_boxblur(QImage &image, int radius, bool quality)
static QString makeColorString(QColor color)
static bool qSetFontFamilyFromTokens(QFont &font, const QStringList &fontFamilyTokens)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData)
static bool areCollinear(const QPointF &a, const QPointF &b, const QPointF &c)
#define CHECK_CONTEXT_SETTER(r)
static bool qSetFontSizeFromToken(QFont &font, QStringView fontSizeToken)
static int qParseFontSizeFromToken(QStringView fontSizeToken, bool &ok)
static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionEngine *v4, QImage &&image)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DPixelData)
static QString qt_composite_mode_to_string(QPainter::CompositionMode op)
static QStringList qExtractFontFamiliesFromString(QStringView fontFamiliesString)
DEFINE_OBJECT_VTABLE(QQuickJSContext2D)
QDebug Q_QUICK_EXPORT operator<<(QDebug debug, const QQuickWindow *item)
static QV4::ReturnedValue method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty object QtQuick::CanvasImageData::data Holds the one-dimensional array containing the dat...
static QV4::ReturnedValue method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty int QtQuick::CanvasImageData::height Holds the actual height dimension of the data in th...
static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id, const QV4::Value &value, Value *receiver)
static QV4::ReturnedValue proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmltype CanvasPixelArray \inqmlmodule QtQuick
static QV4::ReturnedValue method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::isPointInPath(real x, real y)
static QV4::ReturnedValue method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::measureText(text)
static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::moveTo(real x, real y)
static QV4::ReturnedValue method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::bezierCurveTo(real cp1x, real cp1y, real cp2x,...
static QV4::ReturnedValue method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real x, real y, real w,...
static QV4::ReturnedValue method_setLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod void QtQuick::Context2D::setLineDash(array pattern)
static QV4::ReturnedValue method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::quadraticCurveTo(real cpx, real cpy, real x,...
static QV4::ReturnedValue method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod void QtQuick::Context2D::drawImage(variant image, real dx, real dy) Draws the given image ...
static QV4::ReturnedValue method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::scale(real x, real y)
static QV4::ReturnedValue method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::stroke()
static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::closePath() Closes the current subpath by drawing a line to the...
static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::strokeRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::transform(real a, real b, real c, real d, real e,...
static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::translate(real x, real y)
static QV4::ReturnedValue method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::ellipse(real x, real y, real w, real h)
static QV4::ReturnedValue method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::resetTransform()
static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createRadialGradient(real x0, real y0, real r0,...
static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::clip()
static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createLinearGradient(real x0, real y0, real x1,...
static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::reset() Resets the context state and properties to the default ...
static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fillText(text, x, y)
static QV4::ReturnedValue method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::arc(real x, real y, real radius, real startAngle,...
static QV4::ReturnedValue method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::save() Pushes the current state onto the state stack.
static QV4::ReturnedValue method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::shear(real sh, real sv)
static QV4::ReturnedValue method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::lineTo(real x, real y)
static QV4::ReturnedValue method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::setTransform(real a, real b, real c, real d,...
static QV4::ReturnedValue method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createConicalGradient(real x, real y, real angle)
static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::strokeText(text, x, y)
static QV4::ReturnedValue method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::restore() Pops the top state on the stack, restoring the contex...
static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::rect(real x, real y, real w, real h)
static QV4::ReturnedValue method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::beginPath()
static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::rotate(real angle) Rotate the canvas around the current origin ...
static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fillRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_getLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod array QtQuick::Context2D::getLineDash()
static QV4::ReturnedValue method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::arcTo(real x1, real y1, real x2, real y2,...
static QV4::ReturnedValue method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fill()
static QV4::ReturnedValue method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasImageData QtQuick::Context2D::createImageData(real sw, real sh)
static QV4::ReturnedValue method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode) This is an...
static QV4::ReturnedValue method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::roundedRect(real x, real y, real w, real h, real xRadius,...
static QV4::ReturnedValue method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx,...
static QV4::ReturnedValue method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::text(string text, real x, real y)
static QV4::ReturnedValue method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::lineJoin Holds the current line join style.
static QV4::ReturnedValue method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::globalCompositeOperation Holds the current the current compos...
static QV4::ReturnedValue method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty enumeration QtQuick::Context2D::fillRule Holds the current fill rule used for filling sh...
static QV4::ReturnedValue method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::lineCap Holds the current line cap style.
static QV4::ReturnedValue method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::lineDashOffset
static QV4::ReturnedValue method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::textAlign
static QV4::ReturnedValue method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::lineWidth Holds the current line width.
static QV4::ReturnedValue method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::font Holds the current font settings.
static QV4::ReturnedValue method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty variant QtQuick::Context2D::fillStyle Holds the current style used for filling shapes.
static QV4::ReturnedValue method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowBlur Holds the current level of blur applied to shadows
static QV4::ReturnedValue method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowOffsetY Holds the current shadow offset in the positive v...
static QV4::ReturnedValue method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::miterLimit Holds the current miter limit ratio.
static QV4::ReturnedValue method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::shadowColor Holds the current shadow color.
static QV4::ReturnedValue method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty variant QtQuick::Context2D::strokeStyle Holds the current color or style to use for the ...
static QV4::ReturnedValue method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::textBaseline
static QV4::ReturnedValue method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowOffsetX Holds the current shadow offset in the positive h...
static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack)
QQuickContext2D * context()
void setContext(QQuickContext2D *context)