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
92
96#define CHECK_CONTEXT(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
97 THROW_GENERIC_ERROR("Not a Context2D object");
99#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
100 THROW_GENERIC_ERROR("Not a Context2D object");
101#define qClamp(val, min, max) qMin(qMax(val, min), max)
102#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0
&& c <= 9
))
105 QByteArray str = name.toQString().toUtf8();
107 char *p = str.data();
108 int len = str.size();
110 if (!p || len > 255 || len <= 7)
111 return QColor::fromString(p);
113 bool isRgb(
false), isHsl(
false), hasAlpha(
false);
116 while (isspace(*p)) p++;
117 if (strncmp(p,
"rgb", 3) == 0)
119 else if (strncmp(p,
"hsl", 3) == 0)
122 return QColor::fromString(p);
125 hasAlpha = (*p ==
'a') ?
true :
false;
131 int rh, gs, bl, alpha = 255;
134 while (isspace(*p)) p++;
135 rh = strtol(p, &p, 10);
137 rh = qRound(rh/100.0 * 255);
140 if (*p++ !=
',')
return QColor();
143 while (isspace(*p)) p++;
144 gs = strtol(p, &p, 10);
146 gs = qRound(gs/100.0 * 255);
149 if (*p++ !=
',')
return QColor();
152 while (isspace(*p)) p++;
153 bl = strtol(p, &p, 10);
155 bl = qRound(bl/100.0 * 255);
160 if (*p++!=
',')
return QColor();
161 while (isspace(*p)) p++;
163 alpha = qRound(qstrtod(p,
const_cast<
const char **>(&p), &ok) * 255);
166 if (*p !=
')')
return QColor();
168 return QColor::fromRgba(qRgba(
qClamp(rh, 0, 255),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255)));
170 return QColor::fromHsl(
qClamp(rh, 0, 359),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255));
178 float size = fontSizeToken.trimmed().toFloat(&ok);
182 qWarning().nospace() <<
"Context2D: A font size of " << fontSizeToken <<
" is invalid.";
187
188
189
190
193 const QStringView trimmedToken = fontSizeToken.trimmed();
194 const QStringView unitStr = trimmedToken.right(2);
195 const QStringView value = trimmedToken.left(trimmedToken.size() - 2);
198 if (unitStr == QLatin1String(
"px")) {
199 size = qParseFontSizeFromToken(value, ok);
201 font.setPixelSize(size);
204 }
else if (unitStr == QLatin1String(
"pt")) {
205 size = qParseFontSizeFromToken(value, ok);
207 font.setPointSize(size);
211 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
217
218
219
220
223 QStringList extractedFamilies;
225 QString currentFamily;
226 for (
int index = 0; index < fontFamiliesString.size(); ++index) {
227 const QChar ch = fontFamiliesString.at(index);
228 if (ch == u'"' || ch == u'\'') {
229 if (quoteIndex == -1) {
232 if (ch == fontFamiliesString.at(quoteIndex)) {
234 const QString family = fontFamiliesString.mid(quoteIndex + 1, index - quoteIndex - 1).toString();
235 extractedFamilies.push_back(family);
236 currentFamily.clear();
239 qWarning().nospace() <<
"Context2D: Mismatched quote in font string.";
240 return QStringList();
243 }
else if (ch == u' ' && quoteIndex == -1) {
245 if (!currentFamily.isEmpty()) {
247 extractedFamilies.push_back(currentFamily);
248 currentFamily.clear();
251 currentFamily.push_back(ch);
254 if (!currentFamily.isEmpty()) {
255 if (quoteIndex == -1) {
257 extractedFamilies.push_back(currentFamily);
259 qWarning().nospace() <<
"Context2D: Unclosed quote in font string.";
260 return QStringList();
263 if (extractedFamilies.isEmpty()) {
264 qWarning().nospace() <<
"Context2D: Missing or misplaced font family in font string"
265 <<
" (it must come after the font size).";
267 return extractedFamilies;
271
272
273
274
275
276
277
278
281 for (
const QString &fontFamilyToken : fontFamilyTokens) {
282 if (QFontDatabase::hasFamily(fontFamilyToken)) {
283 font.setFamily(fontFamilyToken);
289 if (fontFamilyToken.compare(QLatin1String(
"serif")) == 0) {
290 styleHint = QFont::Serif;
291 }
else if (fontFamilyToken.compare(QLatin1String(
"sans-serif")) == 0) {
292 styleHint = QFont::SansSerif;
293 }
else if (fontFamilyToken.compare(QLatin1String(
"cursive")) == 0) {
294 styleHint = QFont::Cursive;
295 }
else if (fontFamilyToken.compare(QLatin1String(
"monospace")) == 0) {
296 styleHint = QFont::Monospace;
297 }
else if (fontFamilyToken.compare(QLatin1String(
"fantasy")) == 0) {
298 styleHint = QFont::Fantasy;
300 if (styleHint != -1) {
302 tmp.setStyleHint(
static_cast<QFont::StyleHint>(styleHint));
303 font.setFamily(tmp.defaultFamily());
308 qWarning(
"Context2D: The font families specified are invalid: %s", qPrintable(fontFamilyTokens.join(QString()).trimmed()));
320#define Q_TRY_SET_TOKEN(token, value, setStatement) if
321 (!(usedTokens & token)) {
324}else {
325 qWarning().nospace() << "Context2D: Duplicate token " << QLatin1String(value) << " found in font string.";
326 return currentFont; \
327}
330
331
332
333
335 if (fontString.isEmpty()) {
336 qWarning().nospace() <<
"Context2D: Font string is empty.";
342 int fontSizeEnd = fontString.indexOf(QLatin1String(
"px"));
343 if (fontSizeEnd == -1)
344 fontSizeEnd = fontString.indexOf(QLatin1String(
"pt"));
345 if (fontSizeEnd == -1) {
346 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
350 int fontSizeStart = fontString.lastIndexOf(u' ', fontSizeEnd);
351 if (fontSizeStart == -1) {
364 if (!qSetFontSizeFromToken(newFont, QStringView{fontString}.mid(fontSizeStart, fontSizeEnd - fontSizeStart)))
368 QString remainingFontString = fontString;
369 remainingFontString.remove(fontSizeStart, fontSizeEnd - fontSizeStart);
370 QStringView remainingFontStringRef(remainingFontString);
373 const QStringView fontFamiliesString = remainingFontStringRef.mid(fontSizeStart);
374 remainingFontStringRef.truncate(fontSizeStart);
375 QStringList fontFamilies = qExtractFontFamiliesFromString(fontFamiliesString);
376 if (fontFamilies.isEmpty()) {
379 if (!qSetFontFamilyFromTokens(newFont, fontFamilies))
383 const QStringView trimmedTokensStr = remainingFontStringRef.trimmed();
384 if (trimmedTokensStr.isEmpty()) {
388 const auto tokens = trimmedTokensStr.split(QLatin1Char(
' '));
392 for (
const QStringView &token : tokens) {
393 if (token.compare(QLatin1String(
"normal")) == 0) {
394 if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
396 if (!(usedTokens & FontStyle)) {
398 usedTokens = usedTokens | FontStyle;
399 }
else if (!(usedTokens & FontVariant)) {
401 usedTokens |= FontVariant;
402 }
else if (!(usedTokens & FontWeight)) {
404 usedTokens |= FontWeight;
407 qWarning().nospace() <<
"Context2D: Duplicate token \"normal\" found in font string.";
410 }
else if (token.compare(QLatin1String(
"bold")) == 0) {
412 }
else if (token.compare(QLatin1String(
"italic")) == 0) {
413 Q_TRY_SET_TOKEN(FontStyle,
"italic", newFont.setStyle(QFont::StyleItalic))
414 }
else if (token.compare(QLatin1String(
"oblique")) == 0) {
415 Q_TRY_SET_TOKEN(FontStyle,
"oblique", newFont.setStyle(QFont::StyleOblique))
416 }
else if (token.compare(QLatin1String(
"small-caps")) == 0) {
417 Q_TRY_SET_TOKEN(FontVariant,
"small-caps", newFont.setCapitalization(QFont::SmallCaps))
419 bool conversionOk =
false;
420 int weight = token.toInt(&conversionOk);
423 newFont.setWeight(QFont::Weight(weight)))
426 qWarning().nospace() <<
"Context2D: Invalid or misplaced token " << token
427 <<
" found in font string.";
468 *m_context = context;
470 m_context =
new QPointer<QQuickContext2D>(context);
474 QPointer<QQuickContext2D>* m_context;
478 void init() { Object::init(); }
502 auto *mm = internalClass->engine->memoryManager;
503 mm->changeUnmanagedHeapSizeUsage(-image->sizeInBytes());
515 static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
517 Object::markObjects(that, markStack);
563#if QT_CONFIG(quick_path)
704 int delta = radius ? radius : qFloor(qSqrt(weights.size()) / qreal(2));
705 int filterDim = 2 * delta + 1;
707 QImage dst = QImage(src.size(), src.format());
710 int h = src.height();
712 const QRgb *sr = (
const QRgb *)(src.constBits());
713 int srcStride = src.bytesPerLine() / 4;
715 QRgb *dr = (QRgb*)dst.bits();
716 int dstStride = dst.bytesPerLine() / 4;
718 for (
int y = 0; y < h; ++y) {
719 for (
int x = 0; x < w; ++x) {
733 for (
int cy = 0; cy < filterDim; ++cy) {
734 int scy = sy + cy - delta;
736 if (scy < 0 || scy >= h)
739 const QRgb *sry = sr + scy * srcStride;
741 for (
int cx = 0; cx < filterDim; ++cx) {
742 int scx = sx + cx - delta;
744 if (scx < 0 || scx >= w)
747 const QRgb col = sry[scx];
751 green += qGreen(col);
753 alpha += qAlpha(col);
755 qreal wt = weights[cy * filterDim + cx];
757 redF += qRed(col) * wt;
758 greenF += qGreen(col) * wt;
759 blueF += qBlue(col) * wt;
760 alphaF += qAlpha(col) * wt;
766 dr[x] = qRgba(qRound(red * weights[0]), qRound(green * weights[0]), qRound(blue * weights[0]), qRound(alpha * weights[0]));
768 dr[x] = qRgba(qRound(redF), qRound(greenF), qRound(blueF), qRound(alphaF));
779 int passes = quality? 3: 1;
780 int filterSize = 2 * radius + 1;
781 for (
int i = 0; i < passes; ++i)
782 image = qt_image_convolute_filter(image, QList<qreal>() << 1.0 / (filterSize * filterSize), radius);
787 if (compositeOperator == QLatin1String(
"source-over")) {
788 return QPainter::CompositionMode_SourceOver;
789 }
else if (compositeOperator == QLatin1String(
"source-out")) {
790 return QPainter::CompositionMode_SourceOut;
791 }
else if (compositeOperator == QLatin1String(
"source-in")) {
792 return QPainter::CompositionMode_SourceIn;
793 }
else if (compositeOperator == QLatin1String(
"source-atop")) {
794 return QPainter::CompositionMode_SourceAtop;
795 }
else if (compositeOperator == QLatin1String(
"destination-atop")) {
796 return QPainter::CompositionMode_DestinationAtop;
797 }
else if (compositeOperator == QLatin1String(
"destination-in")) {
798 return QPainter::CompositionMode_DestinationIn;
799 }
else if (compositeOperator == QLatin1String(
"destination-out")) {
800 return QPainter::CompositionMode_DestinationOut;
801 }
else if (compositeOperator == QLatin1String(
"destination-over")) {
802 return QPainter::CompositionMode_DestinationOver;
803 }
else if (compositeOperator == QLatin1String(
"lighter")) {
804 return QPainter::CompositionMode_Plus;
805 }
else if (compositeOperator == QLatin1String(
"copy")) {
806 return QPainter::CompositionMode_Source;
807 }
else if (compositeOperator == QLatin1String(
"xor")) {
808 return QPainter::CompositionMode_Xor;
809 }
else if (compositeOperator == QLatin1String(
"qt-clear")) {
810 return QPainter::CompositionMode_Clear;
811 }
else if (compositeOperator == QLatin1String(
"qt-destination")) {
812 return QPainter::CompositionMode_Destination;
813 }
else if (compositeOperator == QLatin1String(
"qt-multiply")) {
814 return QPainter::CompositionMode_Multiply;
815 }
else if (compositeOperator == QLatin1String(
"qt-screen")) {
816 return QPainter::CompositionMode_Screen;
817 }
else if (compositeOperator == QLatin1String(
"qt-overlay")) {
818 return QPainter::CompositionMode_Overlay;
819 }
else if (compositeOperator == QLatin1String(
"qt-darken")) {
820 return QPainter::CompositionMode_Darken;
821 }
else if (compositeOperator == QLatin1String(
"qt-lighten")) {
822 return QPainter::CompositionMode_Lighten;
823 }
else if (compositeOperator == QLatin1String(
"qt-color-dodge")) {
824 return QPainter::CompositionMode_ColorDodge;
825 }
else if (compositeOperator == QLatin1String(
"qt-color-burn")) {
826 return QPainter::CompositionMode_ColorBurn;
827 }
else if (compositeOperator == QLatin1String(
"qt-hard-light")) {
828 return QPainter::CompositionMode_HardLight;
829 }
else if (compositeOperator == QLatin1String(
"qt-soft-light")) {
830 return QPainter::CompositionMode_SoftLight;
831 }
else if (compositeOperator == QLatin1String(
"qt-difference")) {
832 return QPainter::CompositionMode_Difference;
833 }
else if (compositeOperator == QLatin1String(
"qt-exclusion")) {
834 return QPainter::CompositionMode_Exclusion;
836 return QPainter::CompositionMode_SourceOver;
842 case QPainter::CompositionMode_SourceOver:
843 return QStringLiteral(
"source-over");
844 case QPainter::CompositionMode_DestinationOver:
845 return QStringLiteral(
"destination-over");
846 case QPainter::CompositionMode_Clear:
847 return QStringLiteral(
"qt-clear");
848 case QPainter::CompositionMode_Source:
849 return QStringLiteral(
"copy");
850 case QPainter::CompositionMode_Destination:
851 return QStringLiteral(
"qt-destination");
852 case QPainter::CompositionMode_SourceIn:
853 return QStringLiteral(
"source-in");
854 case QPainter::CompositionMode_DestinationIn:
855 return QStringLiteral(
"destination-in");
856 case QPainter::CompositionMode_SourceOut:
857 return QStringLiteral(
"source-out");
858 case QPainter::CompositionMode_DestinationOut:
859 return QStringLiteral(
"destination-out");
860 case QPainter::CompositionMode_SourceAtop:
861 return QStringLiteral(
"source-atop");
862 case QPainter::CompositionMode_DestinationAtop:
863 return QStringLiteral(
"destination-atop");
864 case QPainter::CompositionMode_Xor:
865 return QStringLiteral(
"xor");
866 case QPainter::CompositionMode_Plus:
867 return QStringLiteral(
"lighter");
868 case QPainter::CompositionMode_Multiply:
869 return QStringLiteral(
"qt-multiply");
870 case QPainter::CompositionMode_Screen:
871 return QStringLiteral(
"qt-screen");
872 case QPainter::CompositionMode_Overlay:
873 return QStringLiteral(
"qt-overlay");
874 case QPainter::CompositionMode_Darken:
875 return QStringLiteral(
"qt-darken");
876 case QPainter::CompositionMode_Lighten:
877 return QStringLiteral(
"lighter");
878 case QPainter::CompositionMode_ColorDodge:
879 return QStringLiteral(
"qt-color-dodge");
880 case QPainter::CompositionMode_ColorBurn:
881 return QStringLiteral(
"qt-color-burn");
882 case QPainter::CompositionMode_HardLight:
883 return QStringLiteral(
"qt-hard-light");
884 case QPainter::CompositionMode_SoftLight:
885 return QStringLiteral(
"qt-soft-light");
886 case QPainter::CompositionMode_Difference:
887 return QStringLiteral(
"qt-difference");
888 case QPainter::CompositionMode_Exclusion:
889 return QStringLiteral(
"qt-exclusion");
902 static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, Value *receiver);
911 QV4::Scope scope(internalClass->engine);
912 QV4::ScopedObject o(scope,
this);
913 o->setArrayType(QV4::Heap::ArrayData::Custom);
931 pixelData = QV4::Value::undefinedValue();
933 QV4::Scope scope(internalClass->engine);
934 QV4::ScopedObject o(scope,
this);
936 o->defineAccessorProperty(QStringLiteral(
"width"), ::QQuickJSContext2DImageData::method_get_width,
nullptr);
937 o->defineAccessorProperty(QStringLiteral(
"height"), ::QQuickJSContext2DImageData::method_get_height,
nullptr);
938 o->defineAccessorProperty(QStringLiteral(
"data"), ::QQuickJSContext2DImageData::method_get_data,
nullptr);
945 QV4::Scope scope(v4);
947 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DPixelData>());
948 v4->memoryManager->changeUnmanagedHeapSizeUsage(image.sizeInBytes());
949 QV4::ScopedObject p(scope, ed->pixelArrayProto.value());
950 pixelData->setPrototypeOf(p);
952 if (image.isNull()) {
953 *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32);
954 pixelData->d()->image->fill(0x00000000);
957 Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatio())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatio())) <= 1);
958 *pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? std::move(image) : std::move(image).convertToFormat(QImage::Format_ARGB32);
961 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DImageData>());
962 imageData->d()->pixelData = pixelData.asReturnedValue();
963 return imageData.asReturnedValue();
969
970
971
972
973
974QV4::ReturnedValue
QQuickJSContext2DPrototype::method_get_canvas(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
977 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
980 RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context()->canvas()));
984
985
986
987
988
989QV4::ReturnedValue
QQuickJSContext2DPrototype::method_restore(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
992 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
995 r->d()->context()->popState();
996 RETURN_RESULT(thisObject->asReturnedValue());
1000
1001
1002
1005 QV4::Scope scope(b);
1006 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1009 r->d()->context()->reset();
1011 RETURN_RESULT(thisObject->asReturnedValue());
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
1043
1046 QV4::Scope scope(b);
1047 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1050 r->d()->context()->pushState();
1052 RETURN_RESULT(*thisObject);
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rotate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1077 QV4::Scope scope(b);
1078 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1082 r->d()->context()->rotate(argv[0].toNumber());
1083 RETURN_RESULT(*thisObject);
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104QV4::ReturnedValue
QQuickJSContext2DPrototype::method_scale(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1106 QV4::Scope scope(b);
1107 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1112 r->d()->context()->scale(argv[0].toNumber(), argv[1].toNumber());
1113 RETURN_RESULT(*thisObject);
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
1149
1150
1151
1152
1153
1154QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1156 QV4::Scope scope(b);
1157 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1162 r->d()->context()->setTransform( argv[0].toNumber()
1163 , argv[1].toNumber()
1164 , argv[2].toNumber()
1165 , argv[3].toNumber()
1166 , argv[4].toNumber()
1167 , argv[5].toNumber());
1169 RETURN_RESULT(*thisObject);
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187QV4::ReturnedValue
QQuickJSContext2DPrototype::method_transform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1189 QV4::Scope scope(b);
1190 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1194 r->d()->context()->transform( argv[0].toNumber()
1195 , argv[1].toNumber()
1196 , argv[2].toNumber()
1197 , argv[3].toNumber()
1198 , argv[4].toNumber()
1199 , argv[5].toNumber());
1201 RETURN_RESULT(*thisObject);
1206
1207
1208
1209
1210
1211
1212
1213
1214QV4::ReturnedValue
QQuickJSContext2DPrototype::method_translate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1216 QV4::Scope scope(b);
1217 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1221 r->d()->context()->translate(argv[0].toNumber(), argv[1].toNumber());
1222 RETURN_RESULT(*thisObject);
1228
1229
1230
1231
1232
1233
1234
1235QV4::ReturnedValue
QQuickJSContext2DPrototype::method_resetTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1237 QV4::Scope scope(b);
1238 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1241 r->d()->context()->setTransform(1, 0, 0, 1, 0, 0);
1243 RETURN_RESULT(*thisObject);
1249
1250
1251
1252
1253
1254QV4::ReturnedValue
QQuickJSContext2DPrototype::method_shear(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1256 QV4::Scope scope(b);
1257 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1261 r->d()->context()->shear(argv[0].toNumber(), argv[1].toNumber());
1263 RETURN_RESULT(*thisObject);
1269
1270
1271
1272
1273
1274
1275QV4::ReturnedValue
QQuickJSContext2D::method_get_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1277 QV4::Scope scope(b);
1278 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1281 RETURN_RESULT(QV4::Encode(r->d()->context()->state.globalAlpha));
1284QV4::ReturnedValue
QQuickJSContext2D::method_set_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1286 QV4::Scope scope(b);
1287 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1290 double globalAlpha = argc ? argv[0].toNumber() : qt_qnan();
1293 if (!qt_is_finite(globalAlpha))
1296 if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context()->state.globalAlpha != globalAlpha) {
1297 r->d()->context()->state.globalAlpha = globalAlpha;
1298 r->d()->context()->buffer()->setGlobalAlpha(r->d()->context()->state.globalAlpha);
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
1376
1377
1378
1379
1380
1381QV4::ReturnedValue
QQuickJSContext2D::method_get_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1383 QV4::Scope scope(b);
1384 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1387 RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context()->state.globalCompositeOperation)));
1390QV4::ReturnedValue
QQuickJSContext2D::method_set_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1392 QV4::Scope scope(b);
1393 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1399 QString mode = argv[0].toQString();
1400 QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
1401 if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String(
"source-over"))
1404 if (cm != r->d()->context()->state.globalCompositeOperation) {
1405 r->d()->context()->state.globalCompositeOperation = cm;
1406 r->d()->context()->buffer()->setGlobalCompositeOperation(cm);
1414 if (color.isValid()) {
1415 if (color.alpha() == 255)
1416 return color.name();
1417 QString alphaString = QString::number(color.alphaF(),
'f');
1418 while (alphaString.endsWith(QLatin1Char(
'0')))
1419 alphaString.chop(1);
1420 if (alphaString.endsWith(QLatin1Char(
'.')))
1421 alphaString += QLatin1Char(
'0');
1422 return QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450QV4::ReturnedValue
QQuickJSContext2D::method_get_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1452 QV4::Scope scope(b);
1453 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1456 if (
auto str = makeColorString(r->d()->context()->state.fillStyle.color().toRgb()); !str.isEmpty())
1457 RETURN_RESULT(scope.engine->newString(std::move(str)));
1458 RETURN_RESULT(r->d()->context()->m_fillStyle.value());
1461QV4::ReturnedValue
QQuickJSContext2D::method_set_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1463 QV4::Scope scope(b);
1464 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1467 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1469 if (value->as<Object>()) {
1470 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1471 if (color.isValid()) {
1472 r->d()->context()->state.fillStyle = color;
1473 r->d()->context()->buffer()->setFillStyle(color);
1474 r->d()->context()->m_fillStyle.set(scope.engine, value);
1476 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1477 if (style && *style->d()->brush != r->d()->context()->state.fillStyle) {
1478 r->d()->context()->state.fillStyle = *style->d()->brush;
1479 r->d()->context()->buffer()->setFillStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1480 r->d()->context()->m_fillStyle.set(scope.engine, value);
1481 r->d()->context()->state.fillPatternRepeatX = style->d()->patternRepeatX;
1482 r->d()->context()->state.fillPatternRepeatY = style->d()->patternRepeatY;
1485 }
else if (value->isString()) {
1486 QColor color = qt_color_from_string(value);
1487 if (color.isValid() && r->d()->context()->state.fillStyle != QBrush(color)) {
1488 r->d()->context()->state.fillStyle = QBrush(color);
1489 r->d()->context()->buffer()->setFillStyle(r->d()->context()->state.fillStyle);
1490 r->d()->context()->m_fillStyle.set(scope.engine, value);
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508QV4::ReturnedValue
QQuickJSContext2D::method_get_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1510 QV4::Scope scope(b);
1511 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1514 RETURN_RESULT(scope.engine->fromVariant(r->d()->context()->state.fillRule));
1517QV4::ReturnedValue
QQuickJSContext2D::method_set_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1519 QV4::Scope scope(b);
1520 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1523 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1525 if ((value->isString() && value->toQString() == QLatin1String(
"WindingFill"))
1526 || (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
1527 r->d()->context()->state.fillRule = Qt::WindingFill;
1528 }
else if ((value->isString() && value->toQStringNoThrow() == QLatin1String(
"OddEvenFill"))
1529 || (value->isInt32() && value->integerValue() == Qt::OddEvenFill)) {
1530 r->d()->context()->state.fillRule = Qt::OddEvenFill;
1534 r->d()->context()->m_path.setFillRule(r->d()->context()->state.fillRule);
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550QV4::ReturnedValue
QQuickJSContext2D::method_get_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1552 QV4::Scope scope(b);
1553 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1556 if (
auto str = makeColorString(r->d()->context()->state.strokeStyle.color().toRgb()); !str.isEmpty())
1557 RETURN_RESULT(scope.engine->newString(std::move(str)));
1558 RETURN_RESULT(r->d()->context()->m_strokeStyle.value());
1561QV4::ReturnedValue
QQuickJSContext2D::method_set_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1563 QV4::Scope scope(b);
1564 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1567 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1569 if (value->as<Object>()) {
1570 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1571 if (color.isValid()) {
1572 r->d()->context()->state.strokeStyle = color;
1573 r->d()->context()->buffer()->setStrokeStyle(color);
1574 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1576 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1577 if (style && *style->d()->brush != r->d()->context()->state.strokeStyle) {
1578 r->d()->context()->state.strokeStyle = *style->d()->brush;
1579 r->d()->context()->buffer()->setStrokeStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1580 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1581 r->d()->context()->state.strokePatternRepeatX = style->d()->patternRepeatX;
1582 r->d()->context()->state.strokePatternRepeatY = style->d()->patternRepeatY;
1583 }
else if (!style && r->d()->context()->state.strokeStyle != QBrush(QColor())) {
1586 r->d()->context()->state.strokeStyle = QBrush(QColor());
1587 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1588 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1591 }
else if (value->isString()) {
1592 QColor color = qt_color_from_string(value);
1593 if (color.isValid() && r->d()->context()->state.strokeStyle != QBrush(color)) {
1594 r->d()->context()->state.strokeStyle = QBrush(color);
1595 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1596 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1619QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createLinearGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1621 QV4::Scope scope(b);
1622 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1626 qreal x0 = argv[0].toNumber();
1627 qreal y0 = argv[1].toNumber();
1628 qreal x1 = argv[2].toNumber();
1629 qreal y1 = argv[3].toNumber();
1631 if (!qt_is_finite(x0)
1632 || !qt_is_finite(y0)
1633 || !qt_is_finite(x1)
1634 || !qt_is_finite(y1)) {
1635 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createLinearGradient(): Incorrect arguments")
1639 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1640 QV4::ScopedObject p(scope, ed->gradientProto.value());
1641 gradient->setPrototypeOf(p);
1642 *gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
1643 RETURN_RESULT(*gradient);
1646 RETURN_RESULT(*thisObject);
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1666QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createRadialGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1668 QV4::Scope scope(b);
1669 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1673 qreal x0 = argv[0].toNumber();
1674 qreal y0 = argv[1].toNumber();
1675 qreal r0 = argv[2].toNumber();
1676 qreal x1 = argv[3].toNumber();
1677 qreal y1 = argv[4].toNumber();
1678 qreal r1 = argv[5].toNumber();
1680 if (!qt_is_finite(x0)
1681 || !qt_is_finite(y0)
1682 || !qt_is_finite(x1)
1683 || !qt_is_finite(r0)
1684 || !qt_is_finite(r1)
1685 || !qt_is_finite(y1)) {
1686 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createRadialGradient(): Incorrect arguments")
1689 if (r0 < 0 || r1 < 0)
1690 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createRadialGradient(): Incorrect arguments")
1694 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1695 QV4::ScopedObject p(scope, ed->gradientProto.value());
1696 gradient->setPrototypeOf(p);
1697 *gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r1, QPointF(x0, y0), r0);
1698 RETURN_RESULT(*gradient);
1701 RETURN_RESULT(*thisObject);
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1720QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createConicalGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1722 QV4::Scope scope(b);
1723 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1727 qreal x = argv[0].toNumber();
1728 qreal y = argv[1].toNumber();
1729 qreal angle = qRadiansToDegrees(argv[2].toNumber());
1730 if (!qt_is_finite(x) || !qt_is_finite(y)) {
1731 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createConicalGradient(): Incorrect arguments");
1734 if (!qt_is_finite(angle)) {
1735 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createConicalGradient(): Incorrect arguments");
1740 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1741 QV4::ScopedObject p(scope, ed->gradientProto.value());
1742 gradient->setPrototypeOf(p);
1743 *gradient->d()->brush = QConicalGradient(x, y, angle);
1744 RETURN_RESULT(*gradient);
1747 RETURN_RESULT(*thisObject);
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createPattern(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1796 QV4::Scope scope(b);
1797 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1801 QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1803 QColor color = QV4::ExecutionEngine::toVariant(
1804 argv[0], QMetaType::fromType<QColor>()).value<QColor>();
1805 if (color.isValid()) {
1806 int patternMode = argv[1].toInt32();
1807 Qt::BrushStyle style = Qt::SolidPattern;
1808 if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
1809 style =
static_cast<Qt::BrushStyle>(patternMode);
1811 *pattern->d()->brush = QBrush(color, style);
1813 QImage patternTexture;
1815 if (
const QV4::Object *o = argv[0].as<Object>()) {
1816 QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral(
"data")));
1817 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
1819 patternTexture = *pixelData->d()->image;
1822 patternTexture = r->d()->context()->createPixmap(QUrl(argv[0].toQStringNoThrow()))->image();
1825 if (!patternTexture.isNull()) {
1826 pattern->d()->brush->setTextureImage(patternTexture);
1828 QString repetition = argv[1].toQStringNoThrow();
1829 if (repetition == QLatin1String(
"repeat") || repetition.isEmpty()) {
1830 pattern->d()->patternRepeatX =
true;
1831 pattern->d()->patternRepeatY =
true;
1832 }
else if (repetition == QLatin1String(
"repeat-x")) {
1833 pattern->d()->patternRepeatX =
true;
1834 pattern->d()->patternRepeatY =
false;
1835 }
else if (repetition == QLatin1String(
"repeat-y")) {
1836 pattern->d()->patternRepeatX =
false;
1837 pattern->d()->patternRepeatY =
true;
1838 }
else if (repetition == QLatin1String(
"no-repeat")) {
1839 pattern->d()->patternRepeatX =
false;
1840 pattern->d()->patternRepeatY =
false;
1848 RETURN_RESULT(*pattern);
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873QV4::ReturnedValue
QQuickJSContext2D::method_get_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1875 QV4::Scope scope(b);
1876 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1879 switch (r->d()->context()->state.lineCap) {
1881 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1883 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"square")));
1888 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"butt")));
1891QV4::ReturnedValue
QQuickJSContext2D::method_set_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1894 return QV4::Encode::undefined();
1896 QV4::Scope scope(b);
1897 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1900 QString lineCap = argv[0].toQString();
1901 Qt::PenCapStyle cap;
1902 if (lineCap == QLatin1String(
"round"))
1904 else if (lineCap == QLatin1String(
"butt"))
1906 else if (lineCap == QLatin1String(
"square"))
1907 cap = Qt::SquareCap;
1911 if (cap != r->d()->context()->state.lineCap) {
1912 r->d()->context()->state.lineCap = cap;
1913 r->d()->context()->buffer()->setLineCap(cap);
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934QV4::ReturnedValue
QQuickJSContext2D::method_get_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1936 QV4::Scope scope(b);
1937 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1940 switch (r->d()->context()->state.lineJoin) {
1942 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1944 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bevel")));
1949 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"miter")));
1952QV4::ReturnedValue
QQuickJSContext2D::method_set_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1954 QV4::Scope scope(b);
1955 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1961 QString lineJoin = argv[0].toQString();
1962 Qt::PenJoinStyle join;
1963 if (lineJoin == QLatin1String(
"round"))
1964 join = Qt::RoundJoin;
1965 else if (lineJoin == QLatin1String(
"bevel"))
1966 join = Qt::BevelJoin;
1967 else if (lineJoin == QLatin1String(
"miter"))
1968 join = Qt::SvgMiterJoin;
1972 if (join != r->d()->context()->state.lineJoin) {
1973 r->d()->context()->state.lineJoin = join;
1974 r->d()->context()->buffer()->setLineJoin(join);
1980
1981
1982
1983QV4::ReturnedValue
QQuickJSContext2D::method_get_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1985 QV4::Scope scope(b);
1986 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1989 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineWidth));
1992QV4::ReturnedValue
QQuickJSContext2D::method_set_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1994 QV4::Scope scope(b);
1995 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1998 qreal w = argc ? argv[0].toNumber() : -1;
2000 if (w > 0 && qt_is_finite(w) && w != r->d()->context()->state.lineWidth) {
2001 r->d()->context()->state.lineWidth = w;
2002 r->d()->context()->buffer()->setLineWidth(w);
2008
2009
2010
2011
2012QV4::ReturnedValue
QQuickJSContext2D::method_get_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2014 QV4::Scope scope(b);
2015 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2018 RETURN_RESULT(QV4::Encode(r->d()->context()->state.miterLimit));
2021QV4::ReturnedValue
QQuickJSContext2D::method_set_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2023 QV4::Scope scope(b);
2024 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2027 qreal ml = argc ? argv[0].toNumber() : -1;
2029 if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context()->state.miterLimit) {
2030 r->d()->context()->state.miterLimit = ml;
2031 r->d()->context()->buffer()->setMiterLimit(ml);
2037
2038
2039
2040
2041
2042
2043QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2045 QV4::Scope scope(b);
2046 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2049 const QList<qreal> pattern = r->d()->context()->state.lineDash;
2050 QV4::ScopedArrayObject array(scope, scope.engine->newArrayObject(pattern.size()));
2051 array->arrayReserve(pattern.size());
2052 for (
int i = 0; i < pattern.size(); i++)
2053 array->put(i, QV4::Value::fromDouble(pattern[i]));
2055 array->setArrayLengthUnchecked(pattern.size());
2057 RETURN_RESULT(*array);
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2087 QV4::Scope scope(b);
2088 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2094 QV4::ScopedArrayObject array(scope, argv[0]);
2098 QV4::ScopedValue v(scope);
2099 const uint arrayLength = array->getLength();
2100 QList<qreal> dashes;
2101 dashes.reserve(arrayLength);
2102 for (uint i = 0; i < arrayLength; ++i) {
2104 const double number = v->toNumber();
2106 if (!qt_is_finite(number) || (number < 0))
2109 dashes.append(v->toNumber());
2111 if (dashes.size() % 2 != 0) {
2115 r->d()->context()->state.lineDash = dashes;
2116 r->d()->context()->buffer()->setLineDash(dashes);
2122
2123
2124
2125
2126
2127
2128
2129
2130QV4::ReturnedValue
QQuickJSContext2D::method_get_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2132 QV4::Scope scope(b);
2133 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2136 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineDashOffset));
2139QV4::ReturnedValue
QQuickJSContext2D::method_set_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2141 QV4::Scope scope(b);
2142 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2145 const qreal offset = argc ? argv[0].toNumber() : -1;
2147 if (qt_is_finite(offset) && offset != r->d()->context()->state.lineDashOffset) {
2148 r->d()->context()->state.lineDashOffset = offset;
2149 r->d()->context()->buffer()->setLineDashOffset(offset);
2157
2158
2159
2160QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2162 QV4::Scope scope(b);
2163 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2166 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowBlur));
2169QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2171 QV4::Scope scope(b);
2172 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2175 qreal blur = argc ? argv[0].toNumber() : -1;
2177 if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context()->state.shadowBlur) {
2178 r->d()->context()->state.shadowBlur = blur;
2179 r->d()->context()->buffer()->setShadowBlur(blur);
2185
2186
2187
2188QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2190 QV4::Scope scope(b);
2191 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2194 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.shadowColor.name()));
2197QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2199 QV4::Scope scope(b);
2200 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2205 color = qt_color_from_string(argv[0]);
2207 if (color.isValid() && color != r->d()->context()->state.shadowColor) {
2208 r->d()->context()->state.shadowColor = color;
2209 r->d()->context()->buffer()->setShadowColor(color);
2216
2217
2218
2219
2220
2221QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2223 QV4::Scope scope(b);
2224 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2227 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetX));
2230QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2232 QV4::Scope scope(b);
2233 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2236 qreal offsetX = argc ? argv[0].toNumber() : qt_qnan();
2237 if (qt_is_finite(offsetX) && offsetX != r->d()->context()->state.shadowOffsetX) {
2238 r->d()->context()->state.shadowOffsetX = offsetX;
2239 r->d()->context()->buffer()->setShadowOffsetX(offsetX);
2244
2245
2246
2247
2248
2249QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2251 QV4::Scope scope(b);
2252 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2255 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetY));
2258QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2260 QV4::Scope scope(b);
2261 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2264 qreal offsetY = argc ? argv[0].toNumber() : qt_qnan();
2265 if (qt_is_finite(offsetY) && offsetY != r->d()->context()->state.shadowOffsetY) {
2266 r->d()->context()->state.shadowOffsetY = offsetY;
2267 r->d()->context()->buffer()->setShadowOffsetY(offsetY);
2272#if QT_CONFIG(quick_path)
2273QV4::ReturnedValue QQuickJSContext2D::method_get_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2275 QV4::Scope scope(b);
2276 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2279 RETURN_RESULT(r->d()->context()->m_v4path.value());
2282QV4::ReturnedValue QQuickJSContext2D::method_set_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2284 QV4::Scope scope(b);
2285 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2286 CHECK_CONTEXT_SETTER(r)
2288 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
2289 r->d()->context()->beginPath();
2290 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
2291 if (!!qobjectWrapper) {
2292 if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
2293 r->d()->context()->m_path = path->path();
2295 QString path =value->toQStringNoThrow();
2296 QQuickSvgParser::parsePathDataFast(path, r->d()->context()->m_path);
2298 r->d()->context()->m_v4path.set(scope.engine, value);
2305
2306
2307
2308
2309
2310QV4::ReturnedValue
QQuickJSContext2DPrototype::method_clearRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2312 QV4::Scope scope(b);
2313 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2318 r->d()->context()->clearRect(argv[0].toNumber(),
2321 argv[3].toNumber());
2323 RETURN_RESULT(*thisObject);
2327
2328
2329
2330
2331
2332
2333QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2335 QV4::Scope scope(b);
2336 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2340 r->d()->context()->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2341 RETURN_RESULT(*thisObject);
2346
2347
2348
2349
2350
2351
2352
2353QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2355 QV4::Scope scope(b);
2356 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2360 r->d()->context()->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2362 RETURN_RESULT(*thisObject);
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arc(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2391 QV4::Scope scope(b);
2392 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2396 bool antiClockwise =
false;
2399 antiClockwise = argv[5].toBoolean();
2401 qreal radius = argv[2].toNumber();
2403 if (qt_is_finite(radius) && radius < 0)
2404 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2406 r->d()->context()->arc(argv[0].toNumber(),
2414 RETURN_RESULT(*thisObject);
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arcTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2444 QV4::Scope scope(b);
2445 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2449 qreal radius = argv[4].toNumber();
2451 if (qt_is_finite(radius) && radius < 0)
2452 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2454 r->d()->context()->arcTo(argv[0].toNumber(),
2461 RETURN_RESULT(*thisObject);
2466
2467
2468
2469
2470QV4::ReturnedValue
QQuickJSContext2DPrototype::method_beginPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2472 QV4::Scope scope(b);
2473 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2476 r->d()->context()->beginPath();
2478 RETURN_RESULT(*thisObject);
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505QV4::ReturnedValue
QQuickJSContext2DPrototype::method_bezierCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2507 QV4::Scope scope(b);
2508 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2512 qreal cp1x = argv[0].toNumber();
2513 qreal cp1y = argv[1].toNumber();
2514 qreal cp2x = argv[2].toNumber();
2515 qreal cp2y = argv[3].toNumber();
2516 qreal x = argv[4].toNumber();
2517 qreal y = argv[5].toNumber();
2519 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))
2522 r->d()->context()->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
2524 RETURN_RESULT(*thisObject);
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2554 QV4::Scope scope(b);
2555 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2558 r->d()->context()->clip();
2559 RETURN_RESULT(*thisObject);
2563
2564
2565
2566
2567
2568
2569QV4::ReturnedValue
QQuickJSContext2DPrototype::method_closePath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2571 QV4::Scope scope(b);
2572 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2575 r->d()->context()->closePath();
2577 RETURN_RESULT(*thisObject);
2581
2582
2583
2584
2585
2586
2587
2588
2591 QV4::Scope scope(b);
2592 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2594 r->d()->context()->fill();
2595 RETURN_RESULT(*thisObject);
2599
2600
2601
2602
2603QV4::ReturnedValue
QQuickJSContext2DPrototype::method_lineTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2605 QV4::Scope scope(b);
2606 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2610 qreal x = argv[0].toNumber();
2611 qreal y = argv[1].toNumber();
2613 if (!qt_is_finite(x) || !qt_is_finite(y))
2616 r->d()->context()->lineTo(x, y);
2619 RETURN_RESULT(*thisObject);
2623
2624
2625
2626
2627QV4::ReturnedValue
QQuickJSContext2DPrototype::method_moveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2629 QV4::Scope scope(b);
2630 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2634 qreal x = argv[0].toNumber();
2635 qreal y = argv[1].toNumber();
2637 if (!qt_is_finite(x) || !qt_is_finite(y))
2639 r->d()->context()->moveTo(x, y);
2642 RETURN_RESULT(*thisObject);
2646
2647
2648
2649
2650
2651
2652
2653QV4::ReturnedValue
QQuickJSContext2DPrototype::method_quadraticCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2655 QV4::Scope scope(b);
2656 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2660 qreal cpx = argv[0].toNumber();
2661 qreal cpy = argv[1].toNumber();
2662 qreal x = argv[2].toNumber();
2663 qreal y = argv[3].toNumber();
2665 if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
2668 r->d()->context()->quadraticCurveTo(cpx, cpy, x, y);
2671 RETURN_RESULT(*thisObject);
2675
2676
2677
2678
2679
2680QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2682 QV4::Scope scope(b);
2683 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2687 r->d()->context()->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2688 RETURN_RESULT(*thisObject);
2693
2694
2695
2696
2697
2698
2699QV4::ReturnedValue
QQuickJSContext2DPrototype::method_roundedRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2701 QV4::Scope scope(b);
2702 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2706 r->d()->context()->roundedRect(argv[0].toNumber()
2707 , argv[1].toNumber()
2708 , argv[2].toNumber()
2709 , argv[3].toNumber()
2710 , argv[4].toNumber()
2711 , argv[5].toNumber());
2712 RETURN_RESULT(*thisObject);
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726QV4::ReturnedValue
QQuickJSContext2DPrototype::method_ellipse(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2728 QV4::Scope scope(b);
2729 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2733 r->d()->context()->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2735 RETURN_RESULT(*thisObject);
2740
2741
2742
2743
2744
2745
2746
2747
2748QV4::ReturnedValue
QQuickJSContext2DPrototype::method_text(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2750 QV4::Scope scope(b);
2751 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2755 qreal x = argv[1].toNumber();
2756 qreal y = argv[2].toNumber();
2758 if (!qt_is_finite(x) || !qt_is_finite(y))
2760 r->d()->context()->text(argv[0].toQStringNoThrow(), x, y);
2763 RETURN_RESULT(*thisObject);
2767
2768
2769
2770
2771
2772
2775 QV4::Scope scope(b);
2776 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2779 r->d()->context()->stroke();
2780 RETURN_RESULT(*thisObject);
2785
2786
2787
2788
2789
2790
2791QV4::ReturnedValue
QQuickJSContext2DPrototype::method_isPointInPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2793 QV4::Scope scope(b);
2794 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2797 bool pointInPath =
false;
2799 pointInPath = r->d()->context()->isPointInPath(argv[0].toNumber(), argv[1].toNumber());
2800 RETURN_RESULT(QV4::Value::fromBoolean(pointInPath).asReturnedValue());
2805 QV4::Scope scope(b);
2806 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::drawFocusRing is not supported");
2809QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setCaretSelectionRect(
const QV4::FunctionObject *b,
const QV4::Value *,
const QV4::Value *,
int)
2811 QV4::Scope scope(b);
2812 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::setCaretSelectionRect is not supported");
2817 QV4::Scope scope(b);
2818 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::caretBlinkRate is not supported");
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844QV4::ReturnedValue
QQuickJSContext2D::method_get_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2846 QV4::Scope scope(b);
2847 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2850 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.font.toString()));
2853QV4::ReturnedValue
QQuickJSContext2D::method_set_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2855 QV4::Scope scope(b);
2856 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2859 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2860 if (scope.hasException())
2862 QFont font = qt_font_from_string(s->toQString(), r->d()->context()->state.font);
2863 if (font != r->d()->context()->state.font) {
2864 r->d()->context()->state.font = font;
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884QV4::ReturnedValue
QQuickJSContext2D::method_get_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2886 QV4::Scope scope(b);
2887 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2890 switch (r->d()->context()->state.textAlign) {
2892 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"end")));
2894 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"left")));
2896 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"right")));
2898 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"center")));
2903 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"start")));
2906QV4::ReturnedValue
QQuickJSContext2D::method_set_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2908 QV4::Scope scope(b);
2909 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2912 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2913 if (scope.hasException())
2915 QString textAlign = s->toQString();
2918 if (textAlign == QLatin1String(
"start"))
2920 else if (textAlign == QLatin1String(
"end"))
2922 else if (textAlign == QLatin1String(
"left"))
2924 else if (textAlign == QLatin1String(
"right"))
2926 else if (textAlign == QLatin1String(
"center"))
2931 if (ta != r->d()->context()->state.textAlign)
2932 r->d()->context()->state.textAlign = ta;
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951QV4::ReturnedValue
QQuickJSContext2D::method_get_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2953 QV4::Scope scope(b);
2954 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2957 switch (r->d()->context()->state.textBaseline) {
2958 case QQuickContext2D::Hanging:
2959 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"hanging")));
2960 case QQuickContext2D::Top:
2961 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"top")));
2962 case QQuickContext2D::Bottom:
2963 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bottom")));
2964 case QQuickContext2D::Middle:
2965 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"middle")));
2966 case QQuickContext2D::Alphabetic:
2970 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"alphabetic")));
2973QV4::ReturnedValue
QQuickJSContext2D::method_set_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2975 QV4::Scope scope(b);
2976 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2978 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2979 if (scope.hasException())
2981 QString textBaseline = s->toQString();
2983 QQuickContext2D::TextBaseLineType tb;
2984 if (textBaseline == QLatin1String(
"alphabetic"))
2985 tb = QQuickContext2D::Alphabetic;
2986 else if (textBaseline == QLatin1String(
"hanging"))
2987 tb = QQuickContext2D::Hanging;
2988 else if (textBaseline == QLatin1String(
"top"))
2989 tb = QQuickContext2D::Top;
2990 else if (textBaseline == QLatin1String(
"bottom"))
2991 tb = QQuickContext2D::Bottom;
2992 else if (textBaseline == QLatin1String(
"middle"))
2993 tb = QQuickContext2D::Middle;
2997 if (tb != r->d()->context()->state.textBaseline)
2998 r->d()->context()->state.textBaseline = tb;
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3015 QV4::Scope scope(b);
3016 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3020 qreal x = argv[1].toNumber();
3021 qreal y = argv[2].toNumber();
3022 if (!qt_is_finite(x) || !qt_is_finite(y))
3024 QPainterPath textPath = r->d()->context()->createTextGlyphs(x, y, argv[0].toQStringNoThrow());
3025 r->d()->context()->buffer()->fill(textPath);
3028 RETURN_RESULT(*thisObject);
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3042 QV4::Scope scope(b);
3043 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3047 r->d()->context()->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(),
false);
3049 RETURN_RESULT(*thisObject);
3053
3054
3055
3056
3057
3058
3059QV4::ReturnedValue
QQuickJSContext2DPrototype::method_measureText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3061 QV4::Scope scope(b);
3062 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3066 QFontMetrics fm(r->d()->context()->state.font);
3067 uint width = fm.horizontalAdvance(argv[0].toQStringNoThrow());
3068 QV4::ScopedObject tm(scope, scope.engine->newObject());
3069 tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral(
"width"))).getPointer(),
3070 QV4::ScopedValue(scope, QV4::Value::fromDouble(width)));
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135QV4::ReturnedValue
QQuickJSContext2DPrototype::method_drawImage(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3137 QV4::Scope scope(b);
3138 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3141 qreal sx, sy, sw, sh, dx, dy, dw, dh;
3147 if (!r->d()->context()->state.invertibleCTM)
3150 QQmlRefPointer<QQuickCanvasPixmap> pixmap;
3152 QV4::ScopedValue arg(scope, argv[0]);
3153 if (arg->isString()) {
3154 QUrl url(arg->toQString());
3156 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3158 pixmap = r->d()->context()->createPixmap(url);
3159 }
else if (arg->isObject()) {
3160 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, arg);
3161 if (!!qobjectWrapper) {
3162 if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
3163 pixmap = r->d()->context()->createPixmap(imageItem->source());
3165 QImage img = canvas->toImage();
3167 pixmap.adopt(
new QQuickCanvasPixmap(img));
3169 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3172 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
3174 QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3175 if (pix && !pix->d()->image->isNull()) {
3176 pixmap.adopt(
new QQuickCanvasPixmap(*pix->d()->image));
3178 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3181 QUrl url(arg->toQStringNoThrow());
3183 pixmap = r->d()->context()->createPixmap(url);
3185 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3189 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3192 if (pixmap.isNull() || !pixmap->isValid())
3196 sx = argv[1].toNumber();
3197 sy = argv[2].toNumber();
3198 sw = argv[3].toNumber();
3199 sh = argv[4].toNumber();
3200 dx = argv[5].toNumber();
3201 dy = argv[6].toNumber();
3202 dw = argv[7].toNumber();
3203 dh = argv[8].toNumber();
3204 }
else if (argc >= 5) {
3207 sw = pixmap->width();
3208 sh = pixmap->height();
3209 dx = argv[1].toNumber();
3210 dy = argv[2].toNumber();
3211 dw = argv[3].toNumber();
3212 dh = argv[4].toNumber();
3213 }
else if (argc >= 3) {
3214 dx = argv[1].toNumber();
3215 dy = argv[2].toNumber();
3218 sw = pixmap->width();
3219 sh = pixmap->height();
3226 if (!qt_is_finite(sx)
3227 || !qt_is_finite(sy)
3228 || !qt_is_finite(sw)
3229 || !qt_is_finite(sh)
3230 || !qt_is_finite(dx)
3231 || !qt_is_finite(dy)
3232 || !qt_is_finite(dw)
3233 || !qt_is_finite(dh))
3240 || sx + sw > pixmap->width()
3241 || sy + sh > pixmap->height()
3242 || sx + sw < 0 || sy + sh < 0) {
3243 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"drawImage(), index size error");
3246 r->d()->context()->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
3248 RETURN_RESULT(*thisObject);
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3272
3273
3274
3275QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_width(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3277 QV4::Scope scope(b);
3278 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3281 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3282 int width = r ? r->d()->image->width() : 0;
3283 RETURN_RESULT(QV4::Encode(width));
3287
3288
3289
3290QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_height(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3292 QV4::Scope scope(b);
3293 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3296 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3297 int height = r ? r->d()->image->height() : 0;
3298 RETURN_RESULT(QV4::Encode(height));
3302
3303
3304
3305QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_data(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3307 QV4::Scope scope(b);
3308 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3311 RETURN_RESULT(imageData->d()->pixelData);
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3327
3328
3329
3330
3331
3332QV4::ReturnedValue
QQuickJSContext2DPixelData::proto_get_length(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3334 QV4::Scope scope(b);
3335 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>());
3336 if (!r || r->d()->image->isNull())
3339 RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4));
3342QV4::ReturnedValue
QQuickJSContext2DPixelData::virtualGet(
const QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value *receiver,
bool *hasProperty)
3344 if (!id.isArrayIndex())
3345 return QV4::Object::virtualGet(m, id, receiver, hasProperty);
3347 uint index = id.asArrayIndex();
3350 QV4::Scope scope(v4);
3351 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<
const QQuickJSContext2DPixelData *>(m));
3353 if (index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4)) {
3355 *hasProperty =
true;
3356 const quint32 w = r->d()->image->width();
3357 const quint32 row = (index / 4) / w;
3358 const quint32 col = (index / 4) % w;
3359 const QRgb* pixel =
reinterpret_cast<
const QRgb*>(r->d()->image->constScanLine(row));
3361 switch (index % 4) {
3363 return QV4::Encode(qRed(*pixel));
3365 return QV4::Encode(qGreen(*pixel));
3367 return QV4::Encode(qBlue(*pixel));
3369 return QV4::Encode(qAlpha(*pixel));
3374 *hasProperty =
false;
3375 return QV4::Encode::undefined();
3378bool QQuickJSContext2DPixelData::virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, QV4::Value *receiver)
3380 if (!id.isArrayIndex())
3381 return Object::virtualPut(m, id, value, receiver);
3385 QV4::Scope scope(v4);
3386 if (scope.hasException())
3389 uint index = id.asArrayIndex();
3390 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<QQuickJSContext2DPixelData *>(m));
3392 const int v = value.toInt32();
3393 if (r && index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4) && v >= 0 && v <= 255) {
3394 const quint32 w = r->d()->image->width();
3395 const quint32 row = (index / 4) / w;
3396 const quint32 col = (index / 4) % w;
3398 QRgb* pixel =
reinterpret_cast<QRgb*>(r->d()->image->scanLine(row));
3400 switch (index % 4) {
3402 *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
3405 *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
3408 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
3411 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
3420
3421
3422
3423
3425
3426
3427
3428
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3442 QV4::Scope scope(b);
3443 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3447 QV4::ScopedValue arg0(scope, argv[0]);
3448 QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
3450 QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3452 qreal w = pa->d()->image->width();
3453 qreal h = pa->d()->image->height();
3454 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3456 }
else if (arg0->isString()) {
3457 QImage image = r->d()->context()->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
3458 RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, std::move(image)));
3460 }
else if (argc == 2) {
3461 qreal w = argv[0].toNumber();
3462 qreal h = argv[1].toNumber();
3464 if (!qt_is_finite(w) || !qt_is_finite(h))
3465 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createImageData(): invalid arguments");
3468 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3470 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createImageData(): invalid arguments");
3476
3477
3478
3479
3480
3481QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3483 QV4::Scope scope(b);
3484 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3488 qreal x = argv[0].toNumber();
3489 qreal y = argv[1].toNumber();
3490 qreal w = argv[2].toNumber();
3491 qreal h = argv[3].toNumber();
3492 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3493 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"getImageData(): Invalid arguments");
3495 if (w <= 0 || h <= 0)
3496 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"getImageData(): Invalid arguments");
3498 QImage image = r->d()->context()->canvas()->toImage(QRectF(x, y, w, h));
3499 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, std::move(image)));
3501 RETURN_RESULT(QV4::Encode::null());
3505
3506
3507
3508
3509
3510
3511
3512
3513QV4::ReturnedValue
QQuickJSContext2DPrototype::method_putImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3515 QV4::Scope scope(b);
3516 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3521 QV4::ScopedValue arg0(scope, argv[0]);
3522 if (!arg0->isObject())
3523 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"Context2D::putImageData, the image data type mismatch");
3525 qreal dx = argv[1].toNumber();
3526 qreal dy = argv[2].toNumber();
3527 qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
3529 if (!qt_is_finite(dx) || !qt_is_finite(dy))
3530 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3532 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
3536 QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3538 w = pixelArray->d()->image->width();
3539 h = pixelArray->d()->image->height();
3542 dirtyX = argv[3].toNumber();
3543 dirtyY = argv[4].toNumber();
3544 dirtyWidth = argv[5].toNumber();
3545 dirtyHeight = argv[6].toNumber();
3547 if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
3548 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3551 if (dirtyWidth < 0) {
3552 dirtyX = dirtyX+dirtyWidth;
3553 dirtyWidth = -dirtyWidth;
3556 if (dirtyHeight < 0) {
3557 dirtyY = dirtyY+dirtyHeight;
3558 dirtyHeight = -dirtyHeight;
3562 dirtyWidth = dirtyWidth+dirtyX;
3567 dirtyHeight = dirtyHeight+dirtyY;
3571 if (dirtyX+dirtyWidth > w) {
3572 dirtyWidth = w - dirtyX;
3575 if (dirtyY+dirtyHeight > h) {
3576 dirtyHeight = h - dirtyY;
3579 if (dirtyWidth <=0 || dirtyHeight <= 0)
3588 QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
3589 r->d()->context()->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
3592 RETURN_RESULT(*thisObject);
3596
3597
3598
3599
3600
3601
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617QV4::ReturnedValue
QQuickContext2DStyle::gradient_proto_addColorStop(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3619 QV4::Scope scope(b);
3620 QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>());
3622 THROW_GENERIC_ERROR(
"Not a CanvasGradient object");
3626 if (!style->d()->brush->gradient())
3627 THROW_GENERIC_ERROR(
"Not a valid CanvasGradient object, can't get the gradient information");
3628 QGradient gradient = *(style->d()->brush->gradient());
3629 qreal pos = argv[0].toNumber();
3632 if (argv[1].as<Object>()) {
3633 color = QV4::ExecutionEngine::toVariant(
3634 argv[1], QMetaType::fromType<QColor>()).value<QColor>();
3636 color = qt_color_from_string(argv[1]);
3638 if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
3639 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"CanvasGradient: parameter offset out of range");
3642 if (color.isValid()) {
3643 gradient.setColorAt(pos, color);
3645 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"CanvasGradient: parameter color is not a valid color string");
3647 *style->d()->brush = gradient;
3650 return thisObject->asReturnedValue();
3655 if (!state.invertibleCTM)
3658 if (!qt_is_finite(x) || !qt_is_finite(y))
3661 QTransform newTransform = state.matrix;
3662 newTransform.scale(x, y);
3664 if (!newTransform.isInvertible()) {
3665 state.invertibleCTM =
false;
3669 state.matrix = newTransform;
3670 buffer()->updateMatrix(state.matrix);
3671 m_path = QTransform().scale(1.0 / x, 1.0 / y).map(m_path);
3676 if (!state.invertibleCTM)
3679 if (!qt_is_finite(angle))
3682 QTransform newTransform =state.matrix;
3683 newTransform.rotate(qRadiansToDegrees(angle));
3685 if (!newTransform.isInvertible()) {
3686 state.invertibleCTM =
false;
3690 state.matrix = newTransform;
3691 buffer()->updateMatrix(state.matrix);
3692 m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
3697 if (!state.invertibleCTM)
3700 if (!qt_is_finite(h) || !qt_is_finite(v))
3703 QTransform newTransform = state.matrix;
3704 newTransform.shear(h, v);
3706 if (!newTransform.isInvertible()) {
3707 state.invertibleCTM =
false;
3711 state.matrix = newTransform;
3712 buffer()->updateMatrix(state.matrix);
3713 m_path = QTransform().shear(-h, -v).map(m_path);
3718 if (!state.invertibleCTM)
3721 if (!qt_is_finite(x) || !qt_is_finite(y))
3724 QTransform newTransform = state.matrix;
3725 newTransform.translate(x, y);
3727 if (!newTransform.isInvertible()) {
3728 state.invertibleCTM =
false;
3732 state.matrix = newTransform;
3733 buffer()->updateMatrix(state.matrix);
3734 m_path = QTransform().translate(-x, -y).map(m_path);
3739 if (!state.invertibleCTM)
3742 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))
3745 QTransform transform(a, b, c, d, e, f);
3746 QTransform newTransform = state.matrix * transform;
3748 if (!newTransform.isInvertible()) {
3749 state.invertibleCTM =
false;
3752 state.matrix = newTransform;
3753 buffer()->updateMatrix(state.matrix);
3754 m_path = transform.inverted().map(m_path);
3759 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))
3762 QTransform ctm = state.matrix;
3763 if (!ctm.isInvertible())
3766 state.matrix = ctm.inverted() * state.matrix;
3767 m_path = ctm.map(m_path);
3768 state.invertibleCTM =
true;
3769 transform(a, b, c, d, e, f);
3774 if (!state.invertibleCTM)
3777 if (!m_path.elementCount())
3780 m_path.setFillRule(state.fillRule);
3786 if (!state.invertibleCTM)
3789 QPainterPath clipPath = m_path;
3790 clipPath.closeSubpath();
3792 state.clipPath = clipPath.intersected(state.clipPath);
3795 state.clipPath = clipPath;
3797 buffer()->clip(state.clip, state.clipPath);
3802 if (!state.invertibleCTM)
3805 if (!m_path.elementCount())
3813 if (!state.invertibleCTM)
3816 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3819 buffer()->fillRect(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()->strokeRect(QRectF(x, y, w, h));
3835 if (!state.invertibleCTM)
3838 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3841 buffer()->clearRect(QRectF(x, y, w, h));
3846 if (!state.invertibleCTM)
3849 if (!qt_is_finite(x) || !qt_is_finite(y))
3852 QPainterPath textPath = createTextGlyphs(x, y, text);
3862 if (!m_path.elementCount())
3864 m_path = QPainterPath();
3869 if (!m_path.elementCount())
3872 QRectF boundRect = m_path.boundingRect();
3873 if (boundRect.width() || boundRect.height())
3874 m_path.closeSubpath();
3881 if (!state.invertibleCTM)
3885 m_path.moveTo(QPointF(x, y));
3890 if (!state.invertibleCTM)
3895 if (!m_path.elementCount())
3897 else if (m_path.currentPosition() != pt)
3904 if (!state.invertibleCTM)
3907 if (!m_path.elementCount())
3908 m_path.moveTo(QPointF(cpx, cpy));
3911 if (m_path.currentPosition() != pt)
3912 m_path.quadTo(QPointF(cpx, cpy), pt);
3916 qreal cp2x, qreal cp2y,
3919 if (!state.invertibleCTM)
3922 if (!m_path.elementCount())
3923 m_path.moveTo(QPointF(cp1x, cp1y));
3926 if (m_path.currentPosition() != pt)
3927 m_path.cubicTo(QPointF(cp1x, cp1y), QPointF(cp2x, cp2y), pt);
3932 QPointF p0(m_path.currentPosition());
3934 QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
3935 QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
3936 qreal p1p0_length =
std::hypot(p1p0.x(), p1p0.y());
3937 qreal p1p2_length =
std::hypot(p1p2.x(), p1p2.y());
3939 qreal cos_phi = QPointF::dotProduct(p1p0, p1p2) / (p1p0_length * p1p2_length);
3944 if (qFuzzyCompare(
std::abs(cos_phi), qreal(1.0))) {
3949 qreal tangent = radius /
std::tan(
std::acos(cos_phi) / 2);
3950 qreal factor_p1p0 = tangent / p1p0_length;
3951 QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
3953 QPointF orth_p1p0(p1p0.y(), -p1p0.x());
3954 qreal orth_p1p0_length =
std::hypot(orth_p1p0.x(), orth_p1p0.y());
3955 qreal factor_ra = radius / orth_p1p0_length;
3958 qreal cos_alpha = QPointF::dotProduct(orth_p1p0, p1p2) / (orth_p1p0_length * p1p2_length);
3959 if (cos_alpha < 0.f)
3960 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3962 QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
3965 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3966 qreal sa =
std::atan2(orth_p1p0.y(), orth_p1p0.x());
3969 bool anticlockwise =
false;
3971 qreal factor_p1p2 = tangent / p1p2_length;
3972 QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
3973 QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
3974 qreal ea =
std::atan2(orth_p1p2.y(), orth_p1p2.x());
3975 if ((sa > ea) && ((sa - ea) <
M_PI))
3976 anticlockwise =
true;
3977 if ((sa < ea) && ((ea - sa) >
M_PI))
3978 anticlockwise =
true;
3980 arc(p.x(), p.y(), radius, sa, ea, anticlockwise);
3987 if (!state.invertibleCTM)
3990 if (!qt_is_finite(x1) || !qt_is_finite(y1) || !qt_is_finite(x2) || !qt_is_finite(y2) || !qt_is_finite(radius))
3994 QPointF end(x2, y2);
3996 if (!m_path.elementCount())
3998 else if (st == m_path.currentPosition() || st == end || !radius)
4001 addArcTo(st, end, radius);
4006 if (!state.invertibleCTM)
4008 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4012 m_path.moveTo(x, y);
4015 m_path.addRect(x, y, w, h);
4022 if (!state.invertibleCTM)
4025 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))
4029 m_path.moveTo(x, y);
4032 m_path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
4038 if (!state.invertibleCTM)
4041 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4045 m_path.moveTo(x, y);
4049 m_path.addEllipse(x, y, w, h);
4054 if (!state.invertibleCTM)
4058 path.addText(x, y, state.font, str);
4059 m_path.addPath(path);
4064 if (!state.invertibleCTM)
4067 if (!qt_is_finite(xc) || !qt_is_finite(yc) || !qt_is_finite(sar) || !qt_is_finite(ear) || !qt_is_finite(radius))
4081 antiClockWise = !antiClockWise;
4084 float sa = qRadiansToDegrees(sar);
4085 float ea = qRadiansToDegrees(ear);
4089 double xs = xc - radius;
4090 double ys = yc - radius;
4091 double width = radius*2;
4092 double height = radius*2;
4093 if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
4099 if (!antiClockWise && (ea < sa)) {
4101 }
else if (antiClockWise && (sa < ea)) {
4106 if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
4107 qFuzzyCompare(qAbs(span), 360))) {
4113 if (!m_path.elementCount())
4114 m_path.arcMoveTo(xs, ys, width, height, sa);
4116 m_path.lineTo(xc, yc);
4120 m_path.arcTo(xs, ys, width, height, sa, span);
4123int baseLineOffset(QQuickContext2D::TextBaseLineType value,
const QFontMetrics &metrics)
4127 case QQuickContext2D::Top:
4128 case QQuickContext2D::Hanging:
4130 case QQuickContext2D::Middle:
4131 offset = (metrics.ascent() >> 1) + metrics.height() - metrics.ascent();
4133 case QQuickContext2D::Alphabetic:
4134 offset = metrics.ascent();
4136 case QQuickContext2D::Bottom:
4137 offset = metrics.height();
4146 if (value == QQuickContext2D::Start)
4147 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Left : QQuickContext2D::Right;
4148 else if (value == QQuickContext2D::End)
4149 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Right: QQuickContext2D::Left;
4152 offset = metrics.horizontalAdvance(text) / 2;
4155 offset = metrics.horizontalAdvance(text);
4166 m_grabbedImage = grab;
4170QQmlRefPointer<QQuickCanvasPixmap>
QQuickContext2D::createPixmap(
const QUrl& url, QSizeF sourceSize)
4172 return m_canvas->loadedPixmap(url, sourceSize);
4177 const QFontMetrics metrics(state.font);
4178 int yoffset = baseLineOffset(
static_cast<QQuickContext2D::TextBaseLineType>(state.textBaseline), metrics);
4179 int xoffset = textAlignOffset(
static_cast<QQuickContext2D::TextAlignType>(state.textAlign), metrics, text);
4181 QPainterPath textPath;
4183 textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
4188static inline bool areCollinear(
const QPointF& a,
const QPointF& b,
const QPointF& c)
4191 return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x()));
4196 return (p >= a && p <= b) || (p >= b && p <= a);
4201 if (!state.invertibleCTM)
4204 if (!m_path.elementCount())
4207 if (!qt_is_finite(x) || !qt_is_finite(y))
4210 QPointF point(x, y);
4211 QTransform ctm = state.matrix;
4212 QPointF p = ctm.inverted().map(point);
4213 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y()))
4216 const_cast<
QQuickContext2D *>(
this)->m_path.setFillRule(state.fillRule);
4218 bool contains = m_path.contains(p);
4222 QPolygonF border = m_path.toFillPolygon();
4224 QPointF p1 = border.at(0);
4227 for (
int i = 1; i < border.size(); ++i) {
4229 if (areCollinear(p, p1, p2)
4232 && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
4233 withinRange(p.x(), p1.x(), p2.x()) :
4234 withinRange(p.y(), p1.y(), p2.y()))) {
4267 return m_v4value.value();
4272 return QStringList() << QStringLiteral(
"2d");
4279 m_canvas = canvasItem;
4280 m_renderTarget = canvasItem->renderTarget();
4281 m_renderStrategy = canvasItem->renderStrategy();
4284 if (m_renderTarget == QQuickCanvasItem::FramebufferObject
4285 && m_renderStrategy == QQuickCanvasItem::Threaded
4286 && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
4287 m_renderTarget = QQuickCanvasItem::Image;
4293 if (m_renderTarget == QQuickCanvasItem::FramebufferObject)
4294 m_renderTarget = QQuickCanvasItem::Image;
4296 m_texture =
new QQuickContext2DImageTexture;
4299 m_texture->setCanvasWindow(canvasItem->canvasWindow().toRect());
4300 m_texture->setTileSize(canvasItem->tileSize());
4301 m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
4302 m_texture->setSmooth(canvasItem->smooth());
4303 m_texture->setAntialiasing(canvasItem->antialiasing());
4304 m_texture->setOnCustomThread(m_renderStrategy == QQuickCanvasItem::Threaded);
4305 m_thread = QThread::currentThread();
4307 QThread *renderThread = m_thread;
4308 if (m_renderStrategy == QQuickCanvasItem::Threaded)
4310 if (renderThread && renderThread != QThread::currentThread())
4312 connect(
m_texture, SIGNAL(textureChanged()), SIGNAL(textureChanged()));
4317void QQuickContext2D::
prepare(
const QSize& canvasSize,
const QSize& tileSize,
const QRect& canvasWindow,
const QRect& dirtyRect,
bool smooth,
bool antialiasing)
4319 if (m_texture->thread() == QThread::currentThread()) {
4320 m_texture->canvasChanged(canvasSize, tileSize, canvasWindow, dirtyRect, smooth, antialiasing);
4322 QEvent *e =
new QQuickContext2DTexture::CanvasChangeEvent(canvasSize,
4328 QCoreApplication::postEvent(m_texture, e);
4335 if (m_texture->thread() == QThread::currentThread())
4338 QCoreApplication::postEvent(m_texture,
new QQuickContext2DTexture::PaintEvent(m_buffer));
4350 if (m_texture->thread() == QThread::currentThread()) {
4353 }
else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
4354 qWarning() <<
"Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode";
4358 QCoreApplication::postEvent(m_texture,
new QEvent(QEvent::Type(QEvent::User + 10)));
4359 QMetaObject::invokeMethod(m_texture,
4361 Qt::BlockingQueuedConnection,
4362 Q_ARG(QRectF, bounds));
4364 QImage img = m_grabbedImage;
4365 m_grabbedImage = QImage();
4373 QV4::Scope scope(v4);
4375 QV4::ScopedObject proto(scope, QQuickJSContext2DPrototype::create(v4));
4376 proto->defineAccessorProperty(QStringLiteral(
"strokeStyle"), QQuickJSContext2D::method_get_strokeStyle, QQuickJSContext2D::method_set_strokeStyle);
4377 proto->defineAccessorProperty(QStringLiteral(
"font"), QQuickJSContext2D::method_get_font, QQuickJSContext2D::method_set_font);
4378 proto->defineAccessorProperty(QStringLiteral(
"fillRule"), QQuickJSContext2D::method_get_fillRule, QQuickJSContext2D::method_set_fillRule);
4379 proto->defineAccessorProperty(QStringLiteral(
"globalAlpha"), QQuickJSContext2D::method_get_globalAlpha, QQuickJSContext2D::method_set_globalAlpha);
4380 proto->defineAccessorProperty(QStringLiteral(
"lineCap"), QQuickJSContext2D::method_get_lineCap, QQuickJSContext2D::method_set_lineCap);
4381 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetX"), QQuickJSContext2D::method_get_shadowOffsetX, QQuickJSContext2D::method_set_shadowOffsetX);
4382 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetY"), QQuickJSContext2D::method_get_shadowOffsetY, QQuickJSContext2D::method_set_shadowOffsetY);
4383 proto->defineAccessorProperty(QStringLiteral(
"globalCompositeOperation"), QQuickJSContext2D::method_get_globalCompositeOperation, QQuickJSContext2D::method_set_globalCompositeOperation);
4384 proto->defineAccessorProperty(QStringLiteral(
"miterLimit"), QQuickJSContext2D::method_get_miterLimit, QQuickJSContext2D::method_set_miterLimit);
4385 proto->defineAccessorProperty(QStringLiteral(
"fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle);
4386 proto->defineAccessorProperty(QStringLiteral(
"shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor);
4387 proto->defineAccessorProperty(QStringLiteral(
"textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline);
4388#if QT_CONFIG(quick_path)
4389 proto->defineAccessorProperty(QStringLiteral(
"path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path);
4391 proto->defineAccessorProperty(QStringLiteral(
"lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin);
4392 proto->defineAccessorProperty(QStringLiteral(
"lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
4393 proto->defineAccessorProperty(QStringLiteral(
"textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
4394 proto->defineAccessorProperty(QStringLiteral(
"shadowBlur"), QQuickJSContext2D::method_get_shadowBlur, QQuickJSContext2D::method_set_shadowBlur);
4395 proto->defineAccessorProperty(QStringLiteral(
"lineDashOffset"), QQuickJSContext2D::method_get_lineDashOffset, QQuickJSContext2D::method_set_lineDashOffset);
4396 contextPrototype = proto;
4398 proto = scope.engine->newObject();
4399 proto->defineDefaultProperty(QStringLiteral(
"addColorStop"), QQuickContext2DStyle::gradient_proto_addColorStop, 0);
4400 gradientProto = proto;
4402 proto = scope.engine->newObject();
4403 proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length,
nullptr);
4404 pixelArrayProto = proto;
4413 if (m_stateStack.isEmpty())
4418 if (state.matrix != newState.matrix)
4419 buffer()->updateMatrix(newState.matrix);
4421 if (newState.globalAlpha != state.globalAlpha)
4422 buffer()->setGlobalAlpha(newState.globalAlpha);
4424 if (newState.globalCompositeOperation != state.globalCompositeOperation)
4425 buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
4427 if (newState.fillStyle != state.fillStyle)
4428 buffer()->setFillStyle(newState.fillStyle);
4430 if (newState.strokeStyle != state.strokeStyle)
4431 buffer()->setStrokeStyle(newState.strokeStyle);
4433 if (newState.lineWidth != state.lineWidth)
4434 buffer()->setLineWidth(newState.lineWidth);
4436 if (newState.lineCap != state.lineCap)
4437 buffer()->setLineCap(newState.lineCap);
4439 if (newState.lineJoin != state.lineJoin)
4440 buffer()->setLineJoin(newState.lineJoin);
4442 if (newState.miterLimit != state.miterLimit)
4443 buffer()->setMiterLimit(newState.miterLimit);
4445 if (newState.clip != state.clip || newState.clipPath != state.clipPath)
4448 if (newState.shadowBlur != state.shadowBlur)
4449 buffer()->setShadowBlur(newState.shadowBlur);
4451 if (newState.shadowColor != state.shadowColor)
4452 buffer()->setShadowColor(newState.shadowColor);
4454 if (newState.shadowOffsetX != state.shadowOffsetX)
4455 buffer()->setShadowOffsetX(newState.shadowOffsetX);
4457 if (newState.shadowOffsetY != state.shadowOffsetY)
4458 buffer()->setShadowOffsetY(newState.shadowOffsetY);
4460 if (newState.lineDash != state.lineDash)
4461 buffer()->setLineDash(newState.lineDash);
4463 m_path = state.matrix.map(m_path);
4465 m_path = state.matrix.inverted().map(m_path);
4469 m_stateStack.push(state);
4476 m_path = QPainterPath();
4478 newState.clipPath.setFillRule(Qt::WindingFill);
4480 m_stateStack.clear();
4481 m_stateStack.push(newState);
4483 m_buffer->clearRect(QRectF(0, 0, m_canvas->width(), m_canvas->height()));
4500 QV4::Scope scope(engine);
4501 QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->allocate<QQuickJSContext2D>());
4502 QV4::ScopedObject p(scope, ed->contextPrototype.value());
4503 wrapper->setPrototypeOf(p);
4504 wrapper->d()->setContext(
this);
4505 m_v4value = wrapper;
4511#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 CanvasPixelArray QtQuick::CanvasImageData::data Holds the one-dimensional array containi...
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 bool 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 var QtQuick::Context2D::measureText(text)
static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D 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 Context2D 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 Context2D QtQuick::Context2D::stroke()
static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::closePath() Closes the current subpath by drawing a line to ...
static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::transform(real a, real b, real c, real d,...
static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D QtQuick::Context2D::resetTransform()
static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasGradient QtQuick::Context2D::createRadialGradient(real x0, real y0,...
static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::clip()
static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasGradient QtQuick::Context2D::createLinearGradient(real x0, real y0,...
static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::reset() Resets the context state and properties to the defau...
static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D 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 Context2D 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 Context2D 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 Context2D 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 CanvasGradient QtQuick::Context2D::createConicalGradient(real x, real y,...
static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::restore() Pops the top state on the stack,...
static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D QtQuick::Context2D::beginPath()
static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D QtQuick::Context2D::rotate(real angle) Rotate the canvas around the current orig...
static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod Context2D 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 Context2D 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 Context2D 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 Context2D QtQuick::Context2D::roundedRect(real x, real y, real w, real h,...
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 void 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 Context2D 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 Context2D 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)