7#include <private/qtquickglobal_p.h>
8#include <private/qquickcontext2dtexture_p.h>
9#include <private/qquickitem_p.h>
10#if QT_CONFIG(quick_shadereffect)
11#include <QtQuick/private/qquickshadereffectsource_p.h>
13#include <qsgrendererinterface.h>
15#include <QtQuick/private/qsgcontext_p.h>
16#include <private/qquicksvgparser_p.h>
17#if QT_CONFIG(quick_path)
18#include <private/qquickpath_p.h>
20#include <private/qquickimage_p_p.h>
24#include <qqmlengine.h>
25#include <private/qv4domerrors_p.h>
26#include <private/qv4engine_p.h>
27#include <private/qv4object_p.h>
28#include <private/qv4qobjectwrapper_p.h>
29#include <private/qquickwindow_p.h>
31#include <private/qv4value_p.h>
32#include <private/qv4functionobject_p.h>
33#include <private/qv4objectproto_p.h>
34#include <private/qv4scopedvalue_p.h>
35#include <private/qlocale_tools_p.h>
37#include <QtCore/qmath.h>
38#include <QtCore/qvector.h>
39#include <QtCore/private/qnumeric_p.h>
40#include <QtCore/QRunnable>
41#include <QtGui/qguiapplication.h>
42#include <private/qguiapplication_p.h>
43#include <qpa/qplatformintegration.h>
45#include <private/qsgdefaultrendercontext_p.h>
47#include <QtCore/qpointer.h>
50#if defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
56
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
94#define CHECK_CONTEXT(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
95 THROW_GENERIC_ERROR("Not a Context2D object");
97#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context() || !r->d()->context()->bufferValid())
98 THROW_GENERIC_ERROR("Not a Context2D object");
99#define qClamp(val, min, max) qMin(qMax(val, min), max)
100#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0
&& c <= 9
))
103 QByteArray str = name.toQString().toUtf8();
105 char *p = str.data();
106 int len = str.size();
108 if (!p || len > 255 || len <= 7)
109 return QColor::fromString(p);
111 bool isRgb(
false), isHsl(
false), hasAlpha(
false);
114 while (isspace(*p)) p++;
115 if (strncmp(p,
"rgb", 3) == 0)
117 else if (strncmp(p,
"hsl", 3) == 0)
120 return QColor::fromString(p);
123 hasAlpha = (*p ==
'a') ?
true :
false;
129 int rh, gs, bl, alpha = 255;
132 while (isspace(*p)) p++;
133 rh = strtol(p, &p, 10);
135 rh = qRound(rh/100.0 * 255);
138 if (*p++ !=
',')
return QColor();
141 while (isspace(*p)) p++;
142 gs = strtol(p, &p, 10);
144 gs = qRound(gs/100.0 * 255);
147 if (*p++ !=
',')
return QColor();
150 while (isspace(*p)) p++;
151 bl = strtol(p, &p, 10);
153 bl = qRound(bl/100.0 * 255);
158 if (*p++!=
',')
return QColor();
159 while (isspace(*p)) p++;
161 alpha = qRound(qstrtod(p,
const_cast<
const char **>(&p), &ok) * 255);
164 if (*p !=
')')
return QColor();
166 return QColor::fromRgba(qRgba(
qClamp(rh, 0, 255),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255)));
168 return QColor::fromHsl(
qClamp(rh, 0, 359),
qClamp(gs, 0, 255),
qClamp(bl, 0, 255),
qClamp(alpha, 0, 255));
176 float size = fontSizeToken.trimmed().toFloat(&ok);
180 qWarning().nospace() <<
"Context2D: A font size of " << fontSizeToken <<
" is invalid.";
185
186
187
188
191 const QStringView trimmedToken = fontSizeToken.trimmed();
192 const QStringView unitStr = trimmedToken.right(2);
193 const QStringView value = trimmedToken.left(trimmedToken.size() - 2);
196 if (unitStr == QLatin1String(
"px")) {
197 size = qParseFontSizeFromToken(value, ok);
199 font.setPixelSize(size);
202 }
else if (unitStr == QLatin1String(
"pt")) {
203 size = qParseFontSizeFromToken(value, ok);
205 font.setPointSize(size);
209 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
215
216
217
218
221 QStringList extractedFamilies;
223 QString currentFamily;
224 for (
int index = 0; index < fontFamiliesString.size(); ++index) {
225 const QChar ch = fontFamiliesString.at(index);
226 if (ch == u'"' || ch == u'\'') {
227 if (quoteIndex == -1) {
230 if (ch == fontFamiliesString.at(quoteIndex)) {
232 const QString family = fontFamiliesString.mid(quoteIndex + 1, index - quoteIndex - 1).toString();
233 extractedFamilies.push_back(family);
234 currentFamily.clear();
237 qWarning().nospace() <<
"Context2D: Mismatched quote in font string.";
238 return QStringList();
241 }
else if (ch == u' ' && quoteIndex == -1) {
243 if (!currentFamily.isEmpty()) {
245 extractedFamilies.push_back(currentFamily);
246 currentFamily.clear();
249 currentFamily.push_back(ch);
252 if (!currentFamily.isEmpty()) {
253 if (quoteIndex == -1) {
255 extractedFamilies.push_back(currentFamily);
257 qWarning().nospace() <<
"Context2D: Unclosed quote in font string.";
258 return QStringList();
261 if (extractedFamilies.isEmpty()) {
262 qWarning().nospace() <<
"Context2D: Missing or misplaced font family in font string"
263 <<
" (it must come after the font size).";
265 return extractedFamilies;
269
270
271
272
273
274
275
276
279 for (
const QString &fontFamilyToken : fontFamilyTokens) {
280 if (QFontDatabase::hasFamily(fontFamilyToken)) {
281 font.setFamily(fontFamilyToken);
287 if (fontFamilyToken.compare(QLatin1String(
"serif")) == 0) {
288 styleHint = QFont::Serif;
289 }
else if (fontFamilyToken.compare(QLatin1String(
"sans-serif")) == 0) {
290 styleHint = QFont::SansSerif;
291 }
else if (fontFamilyToken.compare(QLatin1String(
"cursive")) == 0) {
292 styleHint = QFont::Cursive;
293 }
else if (fontFamilyToken.compare(QLatin1String(
"monospace")) == 0) {
294 styleHint = QFont::Monospace;
295 }
else if (fontFamilyToken.compare(QLatin1String(
"fantasy")) == 0) {
296 styleHint = QFont::Fantasy;
298 if (styleHint != -1) {
300 tmp.setStyleHint(
static_cast<QFont::StyleHint>(styleHint));
301 font.setFamily(tmp.defaultFamily());
306 qWarning(
"Context2D: The font families specified are invalid: %s", qPrintable(fontFamilyTokens.join(QString()).trimmed()));
318#define Q_TRY_SET_TOKEN(token, value, setStatement) if
319 (!(usedTokens & token)) {
322}else {
323 qWarning().nospace() << "Context2D: Duplicate token " << QLatin1String(value) << " found in font string.";
324 return currentFont; \
325}
328
329
330
331
333 if (fontString.isEmpty()) {
334 qWarning().nospace() <<
"Context2D: Font string is empty.";
340 int fontSizeEnd = fontString.indexOf(QLatin1String(
"px"));
341 if (fontSizeEnd == -1)
342 fontSizeEnd = fontString.indexOf(QLatin1String(
"pt"));
343 if (fontSizeEnd == -1) {
344 qWarning().nospace() <<
"Context2D: Invalid font size unit in font string.";
348 int fontSizeStart = fontString.lastIndexOf(u' ', fontSizeEnd);
349 if (fontSizeStart == -1) {
362 if (!qSetFontSizeFromToken(newFont, QStringView{fontString}.mid(fontSizeStart, fontSizeEnd - fontSizeStart)))
366 QString remainingFontString = fontString;
367 remainingFontString.remove(fontSizeStart, fontSizeEnd - fontSizeStart);
368 QStringView remainingFontStringRef(remainingFontString);
371 const QStringView fontFamiliesString = remainingFontStringRef.mid(fontSizeStart);
372 remainingFontStringRef.truncate(fontSizeStart);
373 QStringList fontFamilies = qExtractFontFamiliesFromString(fontFamiliesString);
374 if (fontFamilies.isEmpty()) {
377 if (!qSetFontFamilyFromTokens(newFont, fontFamilies))
381 const QStringView trimmedTokensStr = remainingFontStringRef.trimmed();
382 if (trimmedTokensStr.isEmpty()) {
386 const auto tokens = trimmedTokensStr.split(QLatin1Char(
' '));
390 for (
const QStringView &token : tokens) {
391 if (token.compare(QLatin1String(
"normal")) == 0) {
392 if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
394 if (!(usedTokens & FontStyle)) {
396 usedTokens = usedTokens | FontStyle;
397 }
else if (!(usedTokens & FontVariant)) {
399 usedTokens |= FontVariant;
400 }
else if (!(usedTokens & FontWeight)) {
402 usedTokens |= FontWeight;
405 qWarning().nospace() <<
"Context2D: Duplicate token \"normal\" found in font string.";
408 }
else if (token.compare(QLatin1String(
"bold")) == 0) {
410 }
else if (token.compare(QLatin1String(
"italic")) == 0) {
411 Q_TRY_SET_TOKEN(FontStyle,
"italic", newFont.setStyle(QFont::StyleItalic))
412 }
else if (token.compare(QLatin1String(
"oblique")) == 0) {
413 Q_TRY_SET_TOKEN(FontStyle,
"oblique", newFont.setStyle(QFont::StyleOblique))
414 }
else if (token.compare(QLatin1String(
"small-caps")) == 0) {
415 Q_TRY_SET_TOKEN(FontVariant,
"small-caps", newFont.setCapitalization(QFont::SmallCaps))
417 bool conversionOk =
false;
418 int weight = token.toInt(&conversionOk);
421 newFont.setWeight(QFont::Weight(weight)))
424 qWarning().nospace() <<
"Context2D: Invalid or misplaced token " << token
425 <<
" found in font string.";
466 *m_context = context;
468 m_context =
new QPointer<QQuickContext2D>(context);
472 QPointer<QQuickContext2D>* m_context;
476 void init() { Object::init(); }
509 static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
511 Object::markObjects(that, markStack);
557#if QT_CONFIG(quick_path)
698 int delta = radius ? radius : qFloor(qSqrt(weights.size()) / qreal(2));
699 int filterDim = 2 * delta + 1;
701 QImage dst = QImage(src.size(), src.format());
704 int h = src.height();
706 const QRgb *sr = (
const QRgb *)(src.constBits());
707 int srcStride = src.bytesPerLine() / 4;
709 QRgb *dr = (QRgb*)dst.bits();
710 int dstStride = dst.bytesPerLine() / 4;
712 for (
int y = 0; y < h; ++y) {
713 for (
int x = 0; x < w; ++x) {
727 for (
int cy = 0; cy < filterDim; ++cy) {
728 int scy = sy + cy - delta;
730 if (scy < 0 || scy >= h)
733 const QRgb *sry = sr + scy * srcStride;
735 for (
int cx = 0; cx < filterDim; ++cx) {
736 int scx = sx + cx - delta;
738 if (scx < 0 || scx >= w)
741 const QRgb col = sry[scx];
745 green += qGreen(col);
747 alpha += qAlpha(col);
749 qreal wt = weights[cy * filterDim + cx];
751 redF += qRed(col) * wt;
752 greenF += qGreen(col) * wt;
753 blueF += qBlue(col) * wt;
754 alphaF += qAlpha(col) * wt;
760 dr[x] = qRgba(qRound(red * weights[0]), qRound(green * weights[0]), qRound(blue * weights[0]), qRound(alpha * weights[0]));
762 dr[x] = qRgba(qRound(redF), qRound(greenF), qRound(blueF), qRound(alphaF));
773 int passes = quality? 3: 1;
774 int filterSize = 2 * radius + 1;
775 for (
int i = 0; i < passes; ++i)
776 image = qt_image_convolute_filter(image, QVector<qreal>() << 1.0 / (filterSize * filterSize), radius);
781 if (compositeOperator == QLatin1String(
"source-over")) {
782 return QPainter::CompositionMode_SourceOver;
783 }
else if (compositeOperator == QLatin1String(
"source-out")) {
784 return QPainter::CompositionMode_SourceOut;
785 }
else if (compositeOperator == QLatin1String(
"source-in")) {
786 return QPainter::CompositionMode_SourceIn;
787 }
else if (compositeOperator == QLatin1String(
"source-atop")) {
788 return QPainter::CompositionMode_SourceAtop;
789 }
else if (compositeOperator == QLatin1String(
"destination-atop")) {
790 return QPainter::CompositionMode_DestinationAtop;
791 }
else if (compositeOperator == QLatin1String(
"destination-in")) {
792 return QPainter::CompositionMode_DestinationIn;
793 }
else if (compositeOperator == QLatin1String(
"destination-out")) {
794 return QPainter::CompositionMode_DestinationOut;
795 }
else if (compositeOperator == QLatin1String(
"destination-over")) {
796 return QPainter::CompositionMode_DestinationOver;
797 }
else if (compositeOperator == QLatin1String(
"lighter")) {
798 return QPainter::CompositionMode_Plus;
799 }
else if (compositeOperator == QLatin1String(
"copy")) {
800 return QPainter::CompositionMode_Source;
801 }
else if (compositeOperator == QLatin1String(
"xor")) {
802 return QPainter::CompositionMode_Xor;
803 }
else if (compositeOperator == QLatin1String(
"qt-clear")) {
804 return QPainter::CompositionMode_Clear;
805 }
else if (compositeOperator == QLatin1String(
"qt-destination")) {
806 return QPainter::CompositionMode_Destination;
807 }
else if (compositeOperator == QLatin1String(
"qt-multiply")) {
808 return QPainter::CompositionMode_Multiply;
809 }
else if (compositeOperator == QLatin1String(
"qt-screen")) {
810 return QPainter::CompositionMode_Screen;
811 }
else if (compositeOperator == QLatin1String(
"qt-overlay")) {
812 return QPainter::CompositionMode_Overlay;
813 }
else if (compositeOperator == QLatin1String(
"qt-darken")) {
814 return QPainter::CompositionMode_Darken;
815 }
else if (compositeOperator == QLatin1String(
"qt-lighten")) {
816 return QPainter::CompositionMode_Lighten;
817 }
else if (compositeOperator == QLatin1String(
"qt-color-dodge")) {
818 return QPainter::CompositionMode_ColorDodge;
819 }
else if (compositeOperator == QLatin1String(
"qt-color-burn")) {
820 return QPainter::CompositionMode_ColorBurn;
821 }
else if (compositeOperator == QLatin1String(
"qt-hard-light")) {
822 return QPainter::CompositionMode_HardLight;
823 }
else if (compositeOperator == QLatin1String(
"qt-soft-light")) {
824 return QPainter::CompositionMode_SoftLight;
825 }
else if (compositeOperator == QLatin1String(
"qt-difference")) {
826 return QPainter::CompositionMode_Difference;
827 }
else if (compositeOperator == QLatin1String(
"qt-exclusion")) {
828 return QPainter::CompositionMode_Exclusion;
830 return QPainter::CompositionMode_SourceOver;
836 case QPainter::CompositionMode_SourceOver:
837 return QStringLiteral(
"source-over");
838 case QPainter::CompositionMode_DestinationOver:
839 return QStringLiteral(
"destination-over");
840 case QPainter::CompositionMode_Clear:
841 return QStringLiteral(
"qt-clear");
842 case QPainter::CompositionMode_Source:
843 return QStringLiteral(
"copy");
844 case QPainter::CompositionMode_Destination:
845 return QStringLiteral(
"qt-destination");
846 case QPainter::CompositionMode_SourceIn:
847 return QStringLiteral(
"source-in");
848 case QPainter::CompositionMode_DestinationIn:
849 return QStringLiteral(
"destination-in");
850 case QPainter::CompositionMode_SourceOut:
851 return QStringLiteral(
"source-out");
852 case QPainter::CompositionMode_DestinationOut:
853 return QStringLiteral(
"destination-out");
854 case QPainter::CompositionMode_SourceAtop:
855 return QStringLiteral(
"source-atop");
856 case QPainter::CompositionMode_DestinationAtop:
857 return QStringLiteral(
"destination-atop");
858 case QPainter::CompositionMode_Xor:
859 return QStringLiteral(
"xor");
860 case QPainter::CompositionMode_Plus:
861 return QStringLiteral(
"lighter");
862 case QPainter::CompositionMode_Multiply:
863 return QStringLiteral(
"qt-multiply");
864 case QPainter::CompositionMode_Screen:
865 return QStringLiteral(
"qt-screen");
866 case QPainter::CompositionMode_Overlay:
867 return QStringLiteral(
"qt-overlay");
868 case QPainter::CompositionMode_Darken:
869 return QStringLiteral(
"qt-darken");
870 case QPainter::CompositionMode_Lighten:
871 return QStringLiteral(
"lighter");
872 case QPainter::CompositionMode_ColorDodge:
873 return QStringLiteral(
"qt-color-dodge");
874 case QPainter::CompositionMode_ColorBurn:
875 return QStringLiteral(
"qt-color-burn");
876 case QPainter::CompositionMode_HardLight:
877 return QStringLiteral(
"qt-hard-light");
878 case QPainter::CompositionMode_SoftLight:
879 return QStringLiteral(
"qt-soft-light");
880 case QPainter::CompositionMode_Difference:
881 return QStringLiteral(
"qt-difference");
882 case QPainter::CompositionMode_Exclusion:
883 return QStringLiteral(
"qt-exclusion");
896 static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, Value *receiver);
905 QV4::Scope scope(internalClass->engine);
906 QV4::ScopedObject o(scope,
this);
907 o->setArrayType(QV4::Heap::ArrayData::Custom);
925 pixelData = QV4::Value::undefinedValue();
927 QV4::Scope scope(internalClass->engine);
928 QV4::ScopedObject o(scope,
this);
930 o->defineAccessorProperty(QStringLiteral(
"width"), ::QQuickJSContext2DImageData::method_get_width,
nullptr);
931 o->defineAccessorProperty(QStringLiteral(
"height"), ::QQuickJSContext2DImageData::method_get_height,
nullptr);
932 o->defineAccessorProperty(QStringLiteral(
"data"), ::QQuickJSContext2DImageData::method_get_data,
nullptr);
939 QV4::Scope scope(v4);
941 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DPixelData>());
942 QV4::ScopedObject p(scope, ed->pixelArrayProto.value());
943 pixelData->setPrototypeOf(p);
945 if (image.isNull()) {
946 *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32);
947 pixelData->d()->image->fill(0x00000000);
950 Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatio())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatio())) <= 1);
951 *pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? std::move(image) : std::move(image).convertToFormat(QImage::Format_ARGB32);
954 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocate<QQuickJSContext2DImageData>());
955 imageData->d()->pixelData = pixelData.asReturnedValue();
956 return imageData.asReturnedValue();
962
963
964
965
966
967QV4::ReturnedValue
QQuickJSContext2DPrototype::method_get_canvas(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
970 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
973 RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context()->canvas()));
977
978
979
980
981
982QV4::ReturnedValue
QQuickJSContext2DPrototype::method_restore(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
985 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
988 r->d()->context()->popState();
989 RETURN_RESULT(thisObject->asReturnedValue());
993
994
995
996QV4::ReturnedValue
QQuickJSContext2DPrototype::method_reset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
999 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1002 r->d()->context()->reset();
1004 RETURN_RESULT(thisObject->asReturnedValue());
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1039 QV4::Scope scope(b);
1040 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1043 r->d()->context()->pushState();
1045 RETURN_RESULT(*thisObject);
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rotate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1068 QV4::Scope scope(b);
1069 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1073 r->d()->context()->rotate(argv[0].toNumber());
1074 RETURN_RESULT(*thisObject);
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094QV4::ReturnedValue
QQuickJSContext2DPrototype::method_scale(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1096 QV4::Scope scope(b);
1097 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1102 r->d()->context()->scale(argv[0].toNumber(), argv[1].toNumber());
1103 RETURN_RESULT(*thisObject);
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1145 QV4::Scope scope(b);
1146 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1151 r->d()->context()->setTransform( argv[0].toNumber()
1152 , argv[1].toNumber()
1153 , argv[2].toNumber()
1154 , argv[3].toNumber()
1155 , argv[4].toNumber()
1156 , argv[5].toNumber());
1158 RETURN_RESULT(*thisObject);
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176QV4::ReturnedValue
QQuickJSContext2DPrototype::method_transform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1178 QV4::Scope scope(b);
1179 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1183 r->d()->context()->transform( argv[0].toNumber()
1184 , argv[1].toNumber()
1185 , argv[2].toNumber()
1186 , argv[3].toNumber()
1187 , argv[4].toNumber()
1188 , argv[5].toNumber());
1190 RETURN_RESULT(*thisObject);
1195
1196
1197
1198
1199
1200
1201
1202
1203QV4::ReturnedValue
QQuickJSContext2DPrototype::method_translate(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1205 QV4::Scope scope(b);
1206 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1210 r->d()->context()->translate(argv[0].toNumber(), argv[1].toNumber());
1211 RETURN_RESULT(*thisObject);
1217
1218
1219
1220
1221
1222
1223
1224QV4::ReturnedValue
QQuickJSContext2DPrototype::method_resetTransform(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1226 QV4::Scope scope(b);
1227 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1230 r->d()->context()->setTransform(1, 0, 0, 1, 0, 0);
1232 RETURN_RESULT(*thisObject);
1238
1239
1240
1241
1242
1243QV4::ReturnedValue
QQuickJSContext2DPrototype::method_shear(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1245 QV4::Scope scope(b);
1246 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1250 r->d()->context()->shear(argv[0].toNumber(), argv[1].toNumber());
1252 RETURN_RESULT(*thisObject);
1258
1259
1260
1261
1262
1263
1264QV4::ReturnedValue
QQuickJSContext2D::method_get_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1266 QV4::Scope scope(b);
1267 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1270 RETURN_RESULT(QV4::Encode(r->d()->context()->state.globalAlpha));
1273QV4::ReturnedValue
QQuickJSContext2D::method_set_globalAlpha(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1275 QV4::Scope scope(b);
1276 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1279 double globalAlpha = argc ? argv[0].toNumber() : qt_qnan();
1282 if (!qt_is_finite(globalAlpha))
1285 if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context()->state.globalAlpha != globalAlpha) {
1286 r->d()->context()->state.globalAlpha = globalAlpha;
1287 r->d()->context()->buffer()->setGlobalAlpha(r->d()->context()->state.globalAlpha);
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370QV4::ReturnedValue
QQuickJSContext2D::method_get_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1372 QV4::Scope scope(b);
1373 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1376 RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context()->state.globalCompositeOperation)));
1379QV4::ReturnedValue
QQuickJSContext2D::method_set_globalCompositeOperation(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1381 QV4::Scope scope(b);
1382 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1388 QString mode = argv[0].toQString();
1389 QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
1390 if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String(
"source-over"))
1393 if (cm != r->d()->context()->state.globalCompositeOperation) {
1394 r->d()->context()->state.globalCompositeOperation = cm;
1395 r->d()->context()->buffer()->setGlobalCompositeOperation(cm);
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424QV4::ReturnedValue
QQuickJSContext2D::method_get_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1426 QV4::Scope scope(b);
1427 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1430 const QColor color = r->d()->context()->state.fillStyle.color().toRgb();
1431 if (color.isValid()) {
1432 if (color.alpha() == 255)
1433 RETURN_RESULT(scope.engine->newString(color.name()));
1434 QString alphaString = QString::number(color.alphaF(),
'f');
1435 while (alphaString.endsWith(QLatin1Char(
'0')))
1436 alphaString.chop(1);
1437 if (alphaString.endsWith(QLatin1Char(
'.')))
1438 alphaString += QLatin1Char(
'0');
1439 QString str = QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1440 RETURN_RESULT(scope.engine->newString(str));
1442 RETURN_RESULT(r->d()->context()->m_fillStyle.value());
1445QV4::ReturnedValue
QQuickJSContext2D::method_set_fillStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1447 QV4::Scope scope(b);
1448 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1451 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1453 if (value->as<Object>()) {
1454 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1455 if (color.isValid()) {
1456 r->d()->context()->state.fillStyle = color;
1457 r->d()->context()->buffer()->setFillStyle(color);
1458 r->d()->context()->m_fillStyle.set(scope.engine, value);
1460 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1461 if (style && *style->d()->brush != r->d()->context()->state.fillStyle) {
1462 r->d()->context()->state.fillStyle = *style->d()->brush;
1463 r->d()->context()->buffer()->setFillStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1464 r->d()->context()->m_fillStyle.set(scope.engine, value);
1465 r->d()->context()->state.fillPatternRepeatX = style->d()->patternRepeatX;
1466 r->d()->context()->state.fillPatternRepeatY = style->d()->patternRepeatY;
1469 }
else if (value->isString()) {
1470 QColor color = qt_color_from_string(value);
1471 if (color.isValid() && r->d()->context()->state.fillStyle != QBrush(color)) {
1472 r->d()->context()->state.fillStyle = QBrush(color);
1473 r->d()->context()->buffer()->setFillStyle(r->d()->context()->state.fillStyle);
1474 r->d()->context()->m_fillStyle.set(scope.engine, value);
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492QV4::ReturnedValue
QQuickJSContext2D::method_get_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1494 QV4::Scope scope(b);
1495 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1498 RETURN_RESULT(scope.engine->fromVariant(r->d()->context()->state.fillRule));
1501QV4::ReturnedValue
QQuickJSContext2D::method_set_fillRule(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1503 QV4::Scope scope(b);
1504 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1507 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1509 if ((value->isString() && value->toQString() == QLatin1String(
"WindingFill"))
1510 || (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
1511 r->d()->context()->state.fillRule = Qt::WindingFill;
1512 }
else if ((value->isString() && value->toQStringNoThrow() == QLatin1String(
"OddEvenFill"))
1513 || (value->isInt32() && value->integerValue() == Qt::OddEvenFill)) {
1514 r->d()->context()->state.fillRule = Qt::OddEvenFill;
1518 r->d()->context()->m_path.setFillRule(r->d()->context()->state.fillRule);
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534QV4::ReturnedValue
QQuickJSContext2D::method_get_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1536 QV4::Scope scope(b);
1537 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1540 const QColor color = r->d()->context()->state.strokeStyle.color().toRgb();
1541 if (color.isValid()) {
1542 if (color.alpha() == 255)
1543 RETURN_RESULT(scope.engine->newString(color.name()));
1544 QString alphaString = QString::number(color.alphaF(),
'f');
1545 while (alphaString.endsWith(QLatin1Char(
'0')))
1546 alphaString.chop(1);
1547 if (alphaString.endsWith(QLatin1Char(
'.')))
1548 alphaString += QLatin1Char(
'0');
1549 QString str = QString::fromLatin1(
"rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
1550 RETURN_RESULT(scope.engine->newString(str));
1552 RETURN_RESULT(r->d()->context()->m_strokeStyle.value());
1555QV4::ReturnedValue
QQuickJSContext2D::method_set_strokeStyle(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1557 QV4::Scope scope(b);
1558 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1561 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
1563 if (value->as<Object>()) {
1564 QColor color = QV4::ExecutionEngine::toVariant(value, QMetaType::fromType<QColor>()).value<QColor>();
1565 if (color.isValid()) {
1566 r->d()->context()->state.strokeStyle = color;
1567 r->d()->context()->buffer()->setStrokeStyle(color);
1568 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1570 QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
1571 if (style && *style->d()->brush != r->d()->context()->state.strokeStyle) {
1572 r->d()->context()->state.strokeStyle = *style->d()->brush;
1573 r->d()->context()->buffer()->setStrokeStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
1574 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1575 r->d()->context()->state.strokePatternRepeatX = style->d()->patternRepeatX;
1576 r->d()->context()->state.strokePatternRepeatY = style->d()->patternRepeatY;
1577 }
else if (!style && r->d()->context()->state.strokeStyle != QBrush(QColor())) {
1580 r->d()->context()->state.strokeStyle = QBrush(QColor());
1581 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1582 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1585 }
else if (value->isString()) {
1586 QColor color = qt_color_from_string(value);
1587 if (color.isValid() && r->d()->context()->state.strokeStyle != QBrush(color)) {
1588 r->d()->context()->state.strokeStyle = QBrush(color);
1589 r->d()->context()->buffer()->setStrokeStyle(r->d()->context()->state.strokeStyle);
1590 r->d()->context()->m_strokeStyle.set(scope.engine, value);
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1613QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createLinearGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1615 QV4::Scope scope(b);
1616 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1620 qreal x0 = argv[0].toNumber();
1621 qreal y0 = argv[1].toNumber();
1622 qreal x1 = argv[2].toNumber();
1623 qreal y1 = argv[3].toNumber();
1625 if (!qt_is_finite(x0)
1626 || !qt_is_finite(y0)
1627 || !qt_is_finite(x1)
1628 || !qt_is_finite(y1)) {
1629 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createLinearGradient(): Incorrect arguments")
1633 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1634 QV4::ScopedObject p(scope, ed->gradientProto.value());
1635 gradient->setPrototypeOf(p);
1636 *gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
1637 RETURN_RESULT(*gradient);
1640 RETURN_RESULT(*thisObject);
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1660QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createRadialGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1662 QV4::Scope scope(b);
1663 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1667 qreal x0 = argv[0].toNumber();
1668 qreal y0 = argv[1].toNumber();
1669 qreal r0 = argv[2].toNumber();
1670 qreal x1 = argv[3].toNumber();
1671 qreal y1 = argv[4].toNumber();
1672 qreal r1 = argv[5].toNumber();
1674 if (!qt_is_finite(x0)
1675 || !qt_is_finite(y0)
1676 || !qt_is_finite(x1)
1677 || !qt_is_finite(r0)
1678 || !qt_is_finite(r1)
1679 || !qt_is_finite(y1)) {
1680 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createRadialGradient(): Incorrect arguments")
1683 if (r0 < 0 || r1 < 0)
1684 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createRadialGradient(): Incorrect arguments")
1686 QQuickContext2DEngineData *ed = engineData(scope.engine);
1688 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1689 QV4::ScopedObject p(scope, ed->gradientProto.value());
1690 gradient->setPrototypeOf(p);
1691 *gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r1, QPointF(x0, y0), r0);
1692 RETURN_RESULT(*gradient);
1695 RETURN_RESULT(*thisObject);
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1714QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createConicalGradient(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1716 QV4::Scope scope(b);
1717 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
1721 qreal x = argv[0].toNumber();
1722 qreal y = argv[1].toNumber();
1723 qreal angle = qRadiansToDegrees(argv[2].toNumber());
1724 if (!qt_is_finite(x) || !qt_is_finite(y)) {
1725 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createConicalGradient(): Incorrect arguments");
1728 if (!qt_is_finite(angle)) {
1729 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createConicalGradient(): Incorrect arguments");
1734 QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1735 QV4::ScopedObject p(scope, ed->gradientProto.value());
1736 gradient->setPrototypeOf(p);
1737 *gradient->d()->brush = QConicalGradient(x, y, angle);
1738 RETURN_RESULT(*gradient);
1741 RETURN_RESULT(*thisObject);
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createPattern(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1790 QV4::Scope scope(b);
1791 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1795 QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocate<QQuickContext2DStyle>());
1797 QColor color = QV4::ExecutionEngine::toVariant(
1798 argv[0], QMetaType::fromType<QColor>()).value<QColor>();
1799 if (color.isValid()) {
1800 int patternMode = argv[1].toInt32();
1801 Qt::BrushStyle style = Qt::SolidPattern;
1802 if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
1803 style =
static_cast<Qt::BrushStyle>(patternMode);
1805 *pattern->d()->brush = QBrush(color, style);
1807 QImage patternTexture;
1809 if (
const QV4::Object *o = argv[0].as<Object>()) {
1810 QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral(
"data")));
1811 QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
1813 patternTexture = *pixelData->d()->image;
1816 patternTexture = r->d()->context()->createPixmap(QUrl(argv[0].toQStringNoThrow()))->image();
1819 if (!patternTexture.isNull()) {
1820 pattern->d()->brush->setTextureImage(patternTexture);
1822 QString repetition = argv[1].toQStringNoThrow();
1823 if (repetition == QLatin1String(
"repeat") || repetition.isEmpty()) {
1824 pattern->d()->patternRepeatX =
true;
1825 pattern->d()->patternRepeatY =
true;
1826 }
else if (repetition == QLatin1String(
"repeat-x")) {
1827 pattern->d()->patternRepeatX =
true;
1828 pattern->d()->patternRepeatY =
false;
1829 }
else if (repetition == QLatin1String(
"repeat-y")) {
1830 pattern->d()->patternRepeatX =
false;
1831 pattern->d()->patternRepeatY =
true;
1832 }
else if (repetition == QLatin1String(
"no-repeat")) {
1833 pattern->d()->patternRepeatX =
false;
1834 pattern->d()->patternRepeatY =
false;
1842 RETURN_RESULT(*pattern);
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867QV4::ReturnedValue
QQuickJSContext2D::method_get_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1869 QV4::Scope scope(b);
1870 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1873 switch (r->d()->context()->state.lineCap) {
1875 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1877 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"square")));
1882 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"butt")));
1885QV4::ReturnedValue
QQuickJSContext2D::method_set_lineCap(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1888 return QV4::Encode::undefined();
1890 QV4::Scope scope(b);
1891 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1894 QString lineCap = argv[0].toQString();
1895 Qt::PenCapStyle cap;
1896 if (lineCap == QLatin1String(
"round"))
1898 else if (lineCap == QLatin1String(
"butt"))
1900 else if (lineCap == QLatin1String(
"square"))
1901 cap = Qt::SquareCap;
1905 if (cap != r->d()->context()->state.lineCap) {
1906 r->d()->context()->state.lineCap = cap;
1907 r->d()->context()->buffer()->setLineCap(cap);
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928QV4::ReturnedValue
QQuickJSContext2D::method_get_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1930 QV4::Scope scope(b);
1931 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1934 switch (r->d()->context()->state.lineJoin) {
1936 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"round")));
1938 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bevel")));
1943 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"miter")));
1946QV4::ReturnedValue
QQuickJSContext2D::method_set_lineJoin(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1948 QV4::Scope scope(b);
1949 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1955 QString lineJoin = argv[0].toQString();
1956 Qt::PenJoinStyle join;
1957 if (lineJoin == QLatin1String(
"round"))
1958 join = Qt::RoundJoin;
1959 else if (lineJoin == QLatin1String(
"bevel"))
1960 join = Qt::BevelJoin;
1961 else if (lineJoin == QLatin1String(
"miter"))
1962 join = Qt::SvgMiterJoin;
1966 if (join != r->d()->context()->state.lineJoin) {
1967 r->d()->context()->state.lineJoin = join;
1968 r->d()->context()->buffer()->setLineJoin(join);
1974
1975
1976
1977QV4::ReturnedValue
QQuickJSContext2D::method_get_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
1979 QV4::Scope scope(b);
1980 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1983 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineWidth));
1986QV4::ReturnedValue
QQuickJSContext2D::method_set_lineWidth(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
1988 QV4::Scope scope(b);
1989 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
1992 qreal w = argc ? argv[0].toNumber() : -1;
1994 if (w > 0 && qt_is_finite(w) && w != r->d()->context()->state.lineWidth) {
1995 r->d()->context()->state.lineWidth = w;
1996 r->d()->context()->buffer()->setLineWidth(w);
2002
2003
2004
2005
2006QV4::ReturnedValue
QQuickJSContext2D::method_get_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2008 QV4::Scope scope(b);
2009 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2012 RETURN_RESULT(QV4::Encode(r->d()->context()->state.miterLimit));
2015QV4::ReturnedValue
QQuickJSContext2D::method_set_miterLimit(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2017 QV4::Scope scope(b);
2018 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2021 qreal ml = argc ? argv[0].toNumber() : -1;
2023 if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context()->state.miterLimit) {
2024 r->d()->context()->state.miterLimit = ml;
2025 r->d()->context()->buffer()->setMiterLimit(ml);
2031
2032
2033
2034
2035
2036
2037QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2039 QV4::Scope scope(b);
2040 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2043 const QVector<qreal> pattern = r->d()->context()->state.lineDash;
2044 QV4::ScopedArrayObject array(scope, scope.engine->newArrayObject(pattern.size()));
2045 array->arrayReserve(pattern.size());
2046 for (
int i = 0; i < pattern.size(); i++)
2047 array->put(i, QV4::Value::fromDouble(pattern[i]));
2049 array->setArrayLengthUnchecked(pattern.size());
2051 RETURN_RESULT(*array);
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setLineDash(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2080 QV4::Scope scope(b);
2081 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2087 QV4::ScopedArrayObject array(scope, argv[0]);
2091 QV4::ScopedValue v(scope);
2092 const uint arrayLength = array->getLength();
2093 QVector<qreal> dashes;
2094 dashes.reserve(arrayLength);
2095 for (uint i = 0; i < arrayLength; ++i) {
2097 const double number = v->toNumber();
2099 if (!qt_is_finite(number) || (number < 0))
2102 dashes.append(v->toNumber());
2104 if (dashes.size() % 2 != 0) {
2108 r->d()->context()->state.lineDash = dashes;
2109 r->d()->context()->buffer()->setLineDash(dashes);
2115
2116
2117
2118
2119
2120
2121
2122
2123QV4::ReturnedValue
QQuickJSContext2D::method_get_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2125 QV4::Scope scope(b);
2126 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2129 RETURN_RESULT(QV4::Encode(r->d()->context()->state.lineDashOffset));
2132QV4::ReturnedValue
QQuickJSContext2D::method_set_lineDashOffset(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2134 QV4::Scope scope(b);
2135 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2138 const qreal offset = argc ? argv[0].toNumber() : -1;
2140 if (qt_is_finite(offset) && offset != r->d()->context()->state.lineDashOffset) {
2141 r->d()->context()->state.lineDashOffset = offset;
2142 r->d()->context()->buffer()->setLineDashOffset(offset);
2150
2151
2152
2153QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2155 QV4::Scope scope(b);
2156 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2159 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowBlur));
2162QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowBlur(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2164 QV4::Scope scope(b);
2165 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2168 qreal blur = argc ? argv[0].toNumber() : -1;
2170 if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context()->state.shadowBlur) {
2171 r->d()->context()->state.shadowBlur = blur;
2172 r->d()->context()->buffer()->setShadowBlur(blur);
2178
2179
2180
2181QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2183 QV4::Scope scope(b);
2184 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2187 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.shadowColor.name()));
2190QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowColor(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2192 QV4::Scope scope(b);
2193 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2198 color = qt_color_from_string(argv[0]);
2200 if (color.isValid() && color != r->d()->context()->state.shadowColor) {
2201 r->d()->context()->state.shadowColor = color;
2202 r->d()->context()->buffer()->setShadowColor(color);
2209
2210
2211
2212
2213
2214QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2216 QV4::Scope scope(b);
2217 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2220 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetX));
2223QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetX(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2225 QV4::Scope scope(b);
2226 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2229 qreal offsetX = argc ? argv[0].toNumber() : qt_qnan();
2230 if (qt_is_finite(offsetX) && offsetX != r->d()->context()->state.shadowOffsetX) {
2231 r->d()->context()->state.shadowOffsetX = offsetX;
2232 r->d()->context()->buffer()->setShadowOffsetX(offsetX);
2237
2238
2239
2240
2241
2242QV4::ReturnedValue
QQuickJSContext2D::method_get_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2244 QV4::Scope scope(b);
2245 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2248 RETURN_RESULT(QV4::Encode(r->d()->context()->state.shadowOffsetY));
2251QV4::ReturnedValue
QQuickJSContext2D::method_set_shadowOffsetY(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2253 QV4::Scope scope(b);
2254 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2257 qreal offsetY = argc ? argv[0].toNumber() : qt_qnan();
2258 if (qt_is_finite(offsetY) && offsetY != r->d()->context()->state.shadowOffsetY) {
2259 r->d()->context()->state.shadowOffsetY = offsetY;
2260 r->d()->context()->buffer()->setShadowOffsetY(offsetY);
2265#if QT_CONFIG(quick_path)
2266QV4::ReturnedValue QQuickJSContext2D::method_get_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2268 QV4::Scope scope(b);
2269 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2272 RETURN_RESULT(r->d()->context()->m_v4path.value());
2275QV4::ReturnedValue QQuickJSContext2D::method_set_path(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2277 QV4::Scope scope(b);
2278 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2279 CHECK_CONTEXT_SETTER(r)
2281 QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Value::undefinedValue());
2282 r->d()->context()->beginPath();
2283 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
2284 if (!!qobjectWrapper) {
2285 if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
2286 r->d()->context()->m_path = path->path();
2288 QString path =value->toQStringNoThrow();
2289 QQuickSvgParser::parsePathDataFast(path, r->d()->context()->m_path);
2291 r->d()->context()->m_v4path.set(scope.engine, value);
2298
2299
2300
2301
2302
2303QV4::ReturnedValue
QQuickJSContext2DPrototype::method_clearRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2305 QV4::Scope scope(b);
2306 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2311 r->d()->context()->clearRect(argv[0].toNumber(),
2314 argv[3].toNumber());
2316 RETURN_RESULT(*thisObject);
2320
2321
2322
2323
2324
2325
2326QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2328 QV4::Scope scope(b);
2329 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2333 r->d()->context()->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2334 RETURN_RESULT(*thisObject);
2339
2340
2341
2342
2343
2344
2345
2346QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2348 QV4::Scope scope(b);
2349 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2353 r->d()->context()->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2355 RETURN_RESULT(*thisObject);
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arc(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2382 QV4::Scope scope(b);
2383 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2387 bool antiClockwise =
false;
2390 antiClockwise = argv[5].toBoolean();
2392 qreal radius = argv[2].toNumber();
2394 if (qt_is_finite(radius) && radius < 0)
2395 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2397 r->d()->context()->arc(argv[0].toNumber(),
2405 RETURN_RESULT(*thisObject);
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432QV4::ReturnedValue
QQuickJSContext2DPrototype::method_arcTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2434 QV4::Scope scope(b);
2435 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2439 qreal radius = argv[4].toNumber();
2441 if (qt_is_finite(radius) && radius < 0)
2442 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"Incorrect argument radius");
2444 r->d()->context()->arcTo(argv[0].toNumber(),
2451 RETURN_RESULT(*thisObject);
2456
2457
2458
2459
2460QV4::ReturnedValue
QQuickJSContext2DPrototype::method_beginPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2462 QV4::Scope scope(b);
2463 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2466 r->d()->context()->beginPath();
2468 RETURN_RESULT(*thisObject);
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494QV4::ReturnedValue
QQuickJSContext2DPrototype::method_bezierCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2496 QV4::Scope scope(b);
2497 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2501 qreal cp1x = argv[0].toNumber();
2502 qreal cp1y = argv[1].toNumber();
2503 qreal cp2x = argv[2].toNumber();
2504 qreal cp2y = argv[3].toNumber();
2505 qreal x = argv[4].toNumber();
2506 qreal y = argv[5].toNumber();
2508 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))
2511 r->d()->context()->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
2513 RETURN_RESULT(*thisObject);
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2542 QV4::Scope scope(b);
2543 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2546 r->d()->context()->clip();
2547 RETURN_RESULT(*thisObject);
2551
2552
2553
2554
2555
2556
2557QV4::ReturnedValue
QQuickJSContext2DPrototype::method_closePath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2559 QV4::Scope scope(b);
2560 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2563 r->d()->context()->closePath();
2565 RETURN_RESULT(*thisObject);
2569
2570
2571
2572
2573
2574
2575
2576
2579 QV4::Scope scope(b);
2580 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2582 r->d()->context()->fill();
2583 RETURN_RESULT(*thisObject);
2587
2588
2589
2590
2591QV4::ReturnedValue
QQuickJSContext2DPrototype::method_lineTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2593 QV4::Scope scope(b);
2594 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2598 qreal x = argv[0].toNumber();
2599 qreal y = argv[1].toNumber();
2601 if (!qt_is_finite(x) || !qt_is_finite(y))
2604 r->d()->context()->lineTo(x, y);
2607 RETURN_RESULT(*thisObject);
2611
2612
2613
2614
2615QV4::ReturnedValue
QQuickJSContext2DPrototype::method_moveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2617 QV4::Scope scope(b);
2618 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2622 qreal x = argv[0].toNumber();
2623 qreal y = argv[1].toNumber();
2625 if (!qt_is_finite(x) || !qt_is_finite(y))
2627 r->d()->context()->moveTo(x, y);
2630 RETURN_RESULT(*thisObject);
2634
2635
2636
2637
2638
2639
2640
2641QV4::ReturnedValue
QQuickJSContext2DPrototype::method_quadraticCurveTo(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2643 QV4::Scope scope(b);
2644 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2648 qreal cpx = argv[0].toNumber();
2649 qreal cpy = argv[1].toNumber();
2650 qreal x = argv[2].toNumber();
2651 qreal y = argv[3].toNumber();
2653 if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
2656 r->d()->context()->quadraticCurveTo(cpx, cpy, x, y);
2659 RETURN_RESULT(*thisObject);
2663
2664
2665
2666
2667
2668QV4::ReturnedValue
QQuickJSContext2DPrototype::method_rect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2670 QV4::Scope scope(b);
2671 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2675 r->d()->context()->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2676 RETURN_RESULT(*thisObject);
2681
2682
2683
2684
2685
2686
2687QV4::ReturnedValue
QQuickJSContext2DPrototype::method_roundedRect(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2689 QV4::Scope scope(b);
2690 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2694 r->d()->context()->roundedRect(argv[0].toNumber()
2695 , argv[1].toNumber()
2696 , argv[2].toNumber()
2697 , argv[3].toNumber()
2698 , argv[4].toNumber()
2699 , argv[5].toNumber());
2700 RETURN_RESULT(*thisObject);
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714QV4::ReturnedValue
QQuickJSContext2DPrototype::method_ellipse(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2716 QV4::Scope scope(b);
2717 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2721 r->d()->context()->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
2723 RETURN_RESULT(*thisObject);
2728
2729
2730
2731
2732
2733
2734
2735
2736QV4::ReturnedValue
QQuickJSContext2DPrototype::method_text(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2738 QV4::Scope scope(b);
2739 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2743 qreal x = argv[1].toNumber();
2744 qreal y = argv[2].toNumber();
2746 if (!qt_is_finite(x) || !qt_is_finite(y))
2748 r->d()->context()->text(argv[0].toQStringNoThrow(), x, y);
2751 RETURN_RESULT(*thisObject);
2755
2756
2757
2758
2759
2760
2763 QV4::Scope scope(b);
2764 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2767 r->d()->context()->stroke();
2768 RETURN_RESULT(*thisObject);
2773
2774
2775
2776
2777
2778
2779QV4::ReturnedValue
QQuickJSContext2DPrototype::method_isPointInPath(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2781 QV4::Scope scope(b);
2782 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2785 bool pointInPath =
false;
2787 pointInPath = r->d()->context()->isPointInPath(argv[0].toNumber(), argv[1].toNumber());
2788 RETURN_RESULT(QV4::Value::fromBoolean(pointInPath).asReturnedValue());
2793 QV4::Scope scope(b);
2794 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::drawFocusRing is not supported");
2797QV4::ReturnedValue
QQuickJSContext2DPrototype::method_setCaretSelectionRect(
const QV4::FunctionObject *b,
const QV4::Value *,
const QV4::Value *,
int)
2799 QV4::Scope scope(b);
2800 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::setCaretSelectionRect is not supported");
2805 QV4::Scope scope(b);
2806 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"Context2D::caretBlinkRate is not supported");
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832QV4::ReturnedValue
QQuickJSContext2D::method_get_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2834 QV4::Scope scope(b);
2835 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2838 RETURN_RESULT(scope.engine->newString(r->d()->context()->state.font.toString()));
2841QV4::ReturnedValue
QQuickJSContext2D::method_set_font(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2843 QV4::Scope scope(b);
2844 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2847 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2848 if (scope.hasException())
2850 QFont font = qt_font_from_string(s->toQString(), r->d()->context()->state.font);
2851 if (font != r->d()->context()->state.font) {
2852 r->d()->context()->state.font = font;
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872QV4::ReturnedValue
QQuickJSContext2D::method_get_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2874 QV4::Scope scope(b);
2875 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2878 switch (r->d()->context()->state.textAlign) {
2879 case QQuickContext2D::End:
2880 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"end")));
2881 case QQuickContext2D::Left:
2882 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"left")));
2883 case QQuickContext2D::Right:
2884 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"right")));
2885 case QQuickContext2D::Center:
2886 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"center")));
2891 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"start")));
2894QV4::ReturnedValue
QQuickJSContext2D::method_set_textAlign(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2896 QV4::Scope scope(b);
2897 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2900 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2901 if (scope.hasException())
2903 QString textAlign = s->toQString();
2906 if (textAlign == QLatin1String(
"start"))
2908 else if (textAlign == QLatin1String(
"end"))
2910 else if (textAlign == QLatin1String(
"left"))
2912 else if (textAlign == QLatin1String(
"right"))
2914 else if (textAlign == QLatin1String(
"center"))
2919 if (ta != r->d()->context()->state.textAlign)
2920 r->d()->context()->state.textAlign = ta;
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939QV4::ReturnedValue
QQuickJSContext2D::method_get_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
2941 QV4::Scope scope(b);
2942 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2945 switch (r->d()->context()->state.textBaseline) {
2946 case QQuickContext2D::Hanging:
2947 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"hanging")));
2948 case QQuickContext2D::Top:
2949 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"top")));
2950 case QQuickContext2D::Bottom:
2951 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"bottom")));
2952 case QQuickContext2D::Middle:
2953 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"middle")));
2954 case QQuickContext2D::Alphabetic:
2958 RETURN_RESULT(scope.engine->newString(QStringLiteral(
"alphabetic")));
2961QV4::ReturnedValue
QQuickJSContext2D::method_set_textBaseline(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
2963 QV4::Scope scope(b);
2964 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
2966 QV4::ScopedString s(scope, argc ? argv[0] : QV4::Value::undefinedValue(), QV4::ScopedString::Convert);
2967 if (scope.hasException())
2969 QString textBaseline = s->toQString();
2971 QQuickContext2D::TextBaseLineType tb;
2972 if (textBaseline == QLatin1String(
"alphabetic"))
2973 tb = QQuickContext2D::Alphabetic;
2974 else if (textBaseline == QLatin1String(
"hanging"))
2975 tb = QQuickContext2D::Hanging;
2976 else if (textBaseline == QLatin1String(
"top"))
2977 tb = QQuickContext2D::Top;
2978 else if (textBaseline == QLatin1String(
"bottom"))
2979 tb = QQuickContext2D::Bottom;
2980 else if (textBaseline == QLatin1String(
"middle"))
2981 tb = QQuickContext2D::Middle;
2985 if (tb != r->d()->context()->state.textBaseline)
2986 r->d()->context()->state.textBaseline = tb;
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001QV4::ReturnedValue
QQuickJSContext2DPrototype::method_fillText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3003 QV4::Scope scope(b);
3004 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3008 qreal x = argv[1].toNumber();
3009 qreal y = argv[2].toNumber();
3010 if (!qt_is_finite(x) || !qt_is_finite(y))
3012 QPainterPath textPath = r->d()->context()->createTextGlyphs(x, y, argv[0].toQStringNoThrow());
3013 r->d()->context()->buffer()->fill(textPath);
3016 RETURN_RESULT(*thisObject);
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028QV4::ReturnedValue
QQuickJSContext2DPrototype::method_strokeText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3030 QV4::Scope scope(b);
3031 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3035 r->d()->context()->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(),
false);
3037 RETURN_RESULT(*thisObject);
3041
3042
3043
3044
3045
3046
3047QV4::ReturnedValue
QQuickJSContext2DPrototype::method_measureText(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3049 QV4::Scope scope(b);
3050 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3054 QFontMetrics fm(r->d()->context()->state.font);
3055 uint width = fm.horizontalAdvance(argv[0].toQStringNoThrow());
3056 QV4::ScopedObject tm(scope, scope.engine->newObject());
3057 tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral(
"width"))).getPointer(),
3058 QV4::ScopedValue(scope, QV4::Value::fromDouble(width)));
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123QV4::ReturnedValue
QQuickJSContext2DPrototype::method_drawImage(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3125 QV4::Scope scope(b);
3126 QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
3129 qreal sx, sy, sw, sh, dx, dy, dw, dh;
3135 if (!r->d()->context()->state.invertibleCTM)
3138 QQmlRefPointer<QQuickCanvasPixmap> pixmap;
3140 QV4::ScopedValue arg(scope, argv[0]);
3141 if (arg->isString()) {
3142 QUrl url(arg->toQString());
3144 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3146 pixmap = r->d()->context()->createPixmap(url);
3147 }
else if (arg->isObject()) {
3148 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, arg);
3149 if (!!qobjectWrapper) {
3150 if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
3151 pixmap = r->d()->context()->createPixmap(imageItem->source());
3152 }
else if (
QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(qobjectWrapper->object())) {
3153 QImage img = canvas->toImage();
3155 pixmap.adopt(
new QQuickCanvasPixmap(img));
3157 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3160 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
3162 QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3163 if (pix && !pix->d()->image->isNull()) {
3164 pixmap.adopt(
new QQuickCanvasPixmap(*pix->d()->image));
3166 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3169 QUrl url(arg->toQStringNoThrow());
3171 pixmap = r->d()->context()->createPixmap(url);
3173 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3177 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"drawImage(), type mismatch");
3180 if (pixmap.isNull() || !pixmap->isValid())
3184 sx = argv[1].toNumber();
3185 sy = argv[2].toNumber();
3186 sw = argv[3].toNumber();
3187 sh = argv[4].toNumber();
3188 dx = argv[5].toNumber();
3189 dy = argv[6].toNumber();
3190 dw = argv[7].toNumber();
3191 dh = argv[8].toNumber();
3192 }
else if (argc >= 5) {
3195 sw = pixmap->width();
3196 sh = pixmap->height();
3197 dx = argv[1].toNumber();
3198 dy = argv[2].toNumber();
3199 dw = argv[3].toNumber();
3200 dh = argv[4].toNumber();
3201 }
else if (argc >= 3) {
3202 dx = argv[1].toNumber();
3203 dy = argv[2].toNumber();
3206 sw = pixmap->width();
3207 sh = pixmap->height();
3214 if (!qt_is_finite(sx)
3215 || !qt_is_finite(sy)
3216 || !qt_is_finite(sw)
3217 || !qt_is_finite(sh)
3218 || !qt_is_finite(dx)
3219 || !qt_is_finite(dy)
3220 || !qt_is_finite(dw)
3221 || !qt_is_finite(dh))
3228 || sx + sw > pixmap->width()
3229 || sy + sh > pixmap->height()
3230 || sx + sw < 0 || sy + sh < 0) {
3231 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"drawImage(), index size error");
3234 r->d()->context()->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
3236 RETURN_RESULT(*thisObject);
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3260
3261
3262
3263QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_width(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3265 QV4::Scope scope(b);
3266 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3269 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3270 int width = r ? r->d()->image->width() : 0;
3271 RETURN_RESULT(QV4::Encode(width));
3275
3276
3277
3278QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_height(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3280 QV4::Scope scope(b);
3281 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3284 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3285 int height = r ? r->d()->image->height() : 0;
3286 RETURN_RESULT(QV4::Encode(height));
3290
3291
3292
3293QV4::ReturnedValue
QQuickJSContext2DImageData::method_get_data(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3295 QV4::Scope scope(b);
3296 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
3299 RETURN_RESULT(imageData->d()->pixelData);
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3315
3316
3317
3318
3319
3320QV4::ReturnedValue
QQuickJSContext2DPixelData::proto_get_length(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *,
int)
3322 QV4::Scope scope(b);
3323 QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>());
3324 if (!r || r->d()->image->isNull())
3327 RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4));
3330QV4::ReturnedValue
QQuickJSContext2DPixelData::virtualGet(
const QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value *receiver,
bool *hasProperty)
3332 if (!id.isArrayIndex())
3333 return QV4::Object::virtualGet(m, id, receiver, hasProperty);
3335 uint index = id.asArrayIndex();
3338 QV4::Scope scope(v4);
3339 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<
const QQuickJSContext2DPixelData *>(m));
3341 if (index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4)) {
3343 *hasProperty =
true;
3344 const quint32 w = r->d()->image->width();
3345 const quint32 row = (index / 4) / w;
3346 const quint32 col = (index / 4) % w;
3347 const QRgb* pixel =
reinterpret_cast<
const QRgb*>(r->d()->image->constScanLine(row));
3349 switch (index % 4) {
3351 return QV4::Encode(qRed(*pixel));
3353 return QV4::Encode(qGreen(*pixel));
3355 return QV4::Encode(qBlue(*pixel));
3357 return QV4::Encode(qAlpha(*pixel));
3362 *hasProperty =
false;
3363 return QV4::Encode::undefined();
3366bool QQuickJSContext2DPixelData::virtualPut(QV4::Managed *m, QV4::PropertyKey id,
const QV4::Value &value, QV4::Value *receiver)
3368 if (!id.isArrayIndex())
3369 return Object::virtualPut(m, id, value, receiver);
3373 QV4::Scope scope(v4);
3374 if (scope.hasException())
3377 uint index = id.asArrayIndex();
3378 QV4::Scoped<QQuickJSContext2DPixelData> r(scope,
static_cast<QQuickJSContext2DPixelData *>(m));
3380 const int v = value.toInt32();
3381 if (r && index <
static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4) && v >= 0 && v <= 255) {
3382 const quint32 w = r->d()->image->width();
3383 const quint32 row = (index / 4) / w;
3384 const quint32 col = (index / 4) % w;
3386 QRgb* pixel =
reinterpret_cast<QRgb*>(r->d()->image->scanLine(row));
3388 switch (index % 4) {
3390 *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
3393 *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
3396 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
3399 *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
3408
3409
3410
3411
3413
3414
3415
3416
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3430 QV4::Scope scope(b);
3431 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3435 QV4::ScopedValue arg0(scope, argv[0]);
3436 QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
3438 QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3440 qreal w = pa->d()->image->width();
3441 qreal h = pa->d()->image->height();
3442 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3444 }
else if (arg0->isString()) {
3445 QImage image = r->d()->context()->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
3446 RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, std::move(image)));
3448 }
else if (argc == 2) {
3449 qreal w = argv[0].toNumber();
3450 qreal h = argv[1].toNumber();
3452 if (!qt_is_finite(w) || !qt_is_finite(h))
3453 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"createImageData(): invalid arguments");
3456 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
3458 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"createImageData(): invalid arguments");
3464
3465
3466
3467
3468
3469QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3471 QV4::Scope scope(b);
3472 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3476 qreal x = argv[0].toNumber();
3477 qreal y = argv[1].toNumber();
3478 qreal w = argv[2].toNumber();
3479 qreal h = argv[3].toNumber();
3480 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3481 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"getImageData(): Invalid arguments");
3483 if (w <= 0 || h <= 0)
3484 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"getImageData(): Invalid arguments");
3486 QImage image = r->d()->context()->canvas()->toImage(QRectF(x, y, w, h));
3487 RETURN_RESULT(qt_create_image_data(w, h, scope.engine, std::move(image)));
3489 RETURN_RESULT(QV4::Encode::null());
3493
3494
3495
3496
3497
3498
3499
3500
3501QV4::ReturnedValue
QQuickJSContext2DPrototype::method_putImageData(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3503 QV4::Scope scope(b);
3504 QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
3509 QV4::ScopedValue arg0(scope, argv[0]);
3510 if (!arg0->isObject())
3511 THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR,
"Context2D::putImageData, the image data type mismatch");
3513 qreal dx = argv[1].toNumber();
3514 qreal dy = argv[2].toNumber();
3515 qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
3517 if (!qt_is_finite(dx) || !qt_is_finite(dy))
3518 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3520 QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
3524 QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
3526 w = pixelArray->d()->image->width();
3527 h = pixelArray->d()->image->height();
3530 dirtyX = argv[3].toNumber();
3531 dirtyY = argv[4].toNumber();
3532 dirtyWidth = argv[5].toNumber();
3533 dirtyHeight = argv[6].toNumber();
3535 if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
3536 THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR,
"putImageData() : Invalid arguments");
3539 if (dirtyWidth < 0) {
3540 dirtyX = dirtyX+dirtyWidth;
3541 dirtyWidth = -dirtyWidth;
3544 if (dirtyHeight < 0) {
3545 dirtyY = dirtyY+dirtyHeight;
3546 dirtyHeight = -dirtyHeight;
3550 dirtyWidth = dirtyWidth+dirtyX;
3555 dirtyHeight = dirtyHeight+dirtyY;
3559 if (dirtyX+dirtyWidth > w) {
3560 dirtyWidth = w - dirtyX;
3563 if (dirtyY+dirtyHeight > h) {
3564 dirtyHeight = h - dirtyY;
3567 if (dirtyWidth <=0 || dirtyHeight <= 0)
3576 QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
3577 r->d()->context()->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
3580 RETURN_RESULT(*thisObject);
3584
3585
3586
3587
3588
3589
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605QV4::ReturnedValue
QQuickContext2DStyle::gradient_proto_addColorStop(
const QV4::FunctionObject *b,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc)
3607 QV4::Scope scope(b);
3608 QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>());
3610 THROW_GENERIC_ERROR(
"Not a CanvasGradient object");
3614 if (!style->d()->brush->gradient())
3615 THROW_GENERIC_ERROR(
"Not a valid CanvasGradient object, can't get the gradient information");
3616 QGradient gradient = *(style->d()->brush->gradient());
3617 qreal pos = argv[0].toNumber();
3620 if (argv[1].as<Object>()) {
3621 color = QV4::ExecutionEngine::toVariant(
3622 argv[1], QMetaType::fromType<QColor>()).value<QColor>();
3624 color = qt_color_from_string(argv[1]);
3626 if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
3627 THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR,
"CanvasGradient: parameter offset out of range");
3630 if (color.isValid()) {
3631 gradient.setColorAt(pos, color);
3633 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"CanvasGradient: parameter color is not a valid color string");
3635 *style->d()->brush = gradient;
3638 return thisObject->asReturnedValue();
3643 if (!state.invertibleCTM)
3646 if (!qt_is_finite(x) || !qt_is_finite(y))
3649 QTransform newTransform = state.matrix;
3650 newTransform.scale(x, y);
3652 if (!newTransform.isInvertible()) {
3653 state.invertibleCTM =
false;
3657 state.matrix = newTransform;
3658 buffer()->updateMatrix(state.matrix);
3659 m_path = QTransform().scale(1.0 / x, 1.0 / y).map(m_path);
3664 if (!state.invertibleCTM)
3667 if (!qt_is_finite(angle))
3670 QTransform newTransform =state.matrix;
3671 newTransform.rotate(qRadiansToDegrees(angle));
3673 if (!newTransform.isInvertible()) {
3674 state.invertibleCTM =
false;
3678 state.matrix = newTransform;
3679 buffer()->updateMatrix(state.matrix);
3680 m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
3685 if (!state.invertibleCTM)
3688 if (!qt_is_finite(h) || !qt_is_finite(v))
3691 QTransform newTransform = state.matrix;
3692 newTransform.shear(h, v);
3694 if (!newTransform.isInvertible()) {
3695 state.invertibleCTM =
false;
3699 state.matrix = newTransform;
3700 buffer()->updateMatrix(state.matrix);
3701 m_path = QTransform().shear(-h, -v).map(m_path);
3706 if (!state.invertibleCTM)
3709 if (!qt_is_finite(x) || !qt_is_finite(y))
3712 QTransform newTransform = state.matrix;
3713 newTransform.translate(x, y);
3715 if (!newTransform.isInvertible()) {
3716 state.invertibleCTM =
false;
3720 state.matrix = newTransform;
3721 buffer()->updateMatrix(state.matrix);
3722 m_path = QTransform().translate(-x, -y).map(m_path);
3727 if (!state.invertibleCTM)
3730 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))
3733 QTransform transform(a, b, c, d, e, f);
3734 QTransform newTransform = state.matrix * transform;
3736 if (!newTransform.isInvertible()) {
3737 state.invertibleCTM =
false;
3740 state.matrix = newTransform;
3741 buffer()->updateMatrix(state.matrix);
3742 m_path = transform.inverted().map(m_path);
3747 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))
3750 QTransform ctm = state.matrix;
3751 if (!ctm.isInvertible())
3754 state.matrix = ctm.inverted() * state.matrix;
3755 m_path = ctm.map(m_path);
3756 state.invertibleCTM =
true;
3757 transform(a, b, c, d, e, f);
3762 if (!state.invertibleCTM)
3765 if (!m_path.elementCount())
3768 m_path.setFillRule(state.fillRule);
3769 buffer()->fill(m_path);
3774 if (!state.invertibleCTM)
3777 QPainterPath clipPath = m_path;
3778 clipPath.closeSubpath();
3780 state.clipPath = clipPath.intersected(state.clipPath);
3783 state.clipPath = clipPath;
3785 buffer()->clip(state.clip, state.clipPath);
3790 if (!state.invertibleCTM)
3793 if (!m_path.elementCount())
3796 buffer()->stroke(m_path);
3801 if (!state.invertibleCTM)
3804 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3807 buffer()->fillRect(QRectF(x, y, w, h));
3812 if (!state.invertibleCTM)
3815 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3818 buffer()->strokeRect(QRectF(x, y, w, h));
3823 if (!state.invertibleCTM)
3826 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
3829 buffer()->clearRect(QRectF(x, y, w, h));
3834 if (!state.invertibleCTM)
3837 if (!qt_is_finite(x) || !qt_is_finite(y))
3840 QPainterPath textPath = createTextGlyphs(x, y, text);
3850 if (!m_path.elementCount())
3852 m_path = QPainterPath();
3857 if (!m_path.elementCount())
3860 QRectF boundRect = m_path.boundingRect();
3861 if (boundRect.width() || boundRect.height())
3862 m_path.closeSubpath();
3869 if (!state.invertibleCTM)
3873 m_path.moveTo(QPointF(x, y));
3878 if (!state.invertibleCTM)
3883 if (!m_path.elementCount())
3885 else if (m_path.currentPosition() != pt)
3892 if (!state.invertibleCTM)
3895 if (!m_path.elementCount())
3896 m_path.moveTo(QPointF(cpx, cpy));
3899 if (m_path.currentPosition() != pt)
3900 m_path.quadTo(QPointF(cpx, cpy), pt);
3904 qreal cp2x, qreal cp2y,
3907 if (!state.invertibleCTM)
3910 if (!m_path.elementCount())
3911 m_path.moveTo(QPointF(cp1x, cp1y));
3914 if (m_path.currentPosition() != pt)
3915 m_path.cubicTo(QPointF(cp1x, cp1y), QPointF(cp2x, cp2y), pt);
3920 QPointF p0(m_path.currentPosition());
3922 QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
3923 QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
3924 qreal p1p0_length =
std::hypot(p1p0.x(), p1p0.y());
3925 qreal p1p2_length =
std::hypot(p1p2.x(), p1p2.y());
3927 qreal cos_phi = QPointF::dotProduct(p1p0, p1p2) / (p1p0_length * p1p2_length);
3932 if (qFuzzyCompare(
std::abs(cos_phi), 1.0)) {
3937 qreal tangent = radius /
std::tan(
std::acos(cos_phi) / 2);
3938 qreal factor_p1p0 = tangent / p1p0_length;
3939 QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
3941 QPointF orth_p1p0(p1p0.y(), -p1p0.x());
3942 qreal orth_p1p0_length =
std::hypot(orth_p1p0.x(), orth_p1p0.y());
3943 qreal factor_ra = radius / orth_p1p0_length;
3946 qreal cos_alpha = QPointF::dotProduct(orth_p1p0, p1p2) / (orth_p1p0_length * p1p2_length);
3947 if (cos_alpha < 0.f)
3948 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3950 QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
3953 orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
3954 qreal sa =
std::atan2(orth_p1p0.y(), orth_p1p0.x());
3957 bool anticlockwise =
false;
3959 qreal factor_p1p2 = tangent / p1p2_length;
3960 QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
3961 QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
3962 qreal ea =
std::atan2(orth_p1p2.y(), orth_p1p2.x());
3963 if ((sa > ea) && ((sa - ea) <
M_PI))
3964 anticlockwise =
true;
3965 if ((sa < ea) && ((ea - sa) >
M_PI))
3966 anticlockwise =
true;
3968 arc(p.x(), p.y(), radius, sa, ea, anticlockwise);
3975 if (!state.invertibleCTM)
3978 if (!qt_is_finite(x1) || !qt_is_finite(y1) || !qt_is_finite(x2) || !qt_is_finite(y2) || !qt_is_finite(radius))
3982 QPointF end(x2, y2);
3984 if (!m_path.elementCount())
3986 else if (st == m_path.currentPosition() || st == end || !radius)
3989 addArcTo(st, end, radius);
3994 if (!state.invertibleCTM)
3996 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4000 m_path.moveTo(x, y);
4003 m_path.addRect(x, y, w, h);
4010 if (!state.invertibleCTM)
4013 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))
4017 m_path.moveTo(x, y);
4020 m_path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
4026 if (!state.invertibleCTM)
4029 if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
4033 m_path.moveTo(x, y);
4037 m_path.addEllipse(x, y, w, h);
4042 if (!state.invertibleCTM)
4046 path.addText(x, y, state.font, str);
4047 m_path.addPath(path);
4052 if (!state.invertibleCTM)
4055 if (!qt_is_finite(xc) || !qt_is_finite(yc) || !qt_is_finite(sar) || !qt_is_finite(ear) || !qt_is_finite(radius))
4069 antiClockWise = !antiClockWise;
4072 float sa = qRadiansToDegrees(sar);
4073 float ea = qRadiansToDegrees(ear);
4077 double xs = xc - radius;
4078 double ys = yc - radius;
4079 double width = radius*2;
4080 double height = radius*2;
4081 if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
4087 if (!antiClockWise && (ea < sa)) {
4089 }
else if (antiClockWise && (sa < ea)) {
4094 if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
4095 qFuzzyCompare(qAbs(span), 360))) {
4101 if (!m_path.elementCount())
4102 m_path.arcMoveTo(xs, ys, width, height, sa);
4104 m_path.lineTo(xc, yc);
4108 m_path.arcTo(xs, ys, width, height, sa, span);
4111int baseLineOffset(QQuickContext2D::TextBaseLineType value,
const QFontMetrics &metrics)
4115 case QQuickContext2D::Top:
4116 case QQuickContext2D::Hanging:
4118 case QQuickContext2D::Middle:
4119 offset = (metrics.ascent() >> 1) + metrics.height() - metrics.ascent();
4121 case QQuickContext2D::Alphabetic:
4122 offset = metrics.ascent();
4124 case QQuickContext2D::Bottom:
4125 offset = metrics.height();
4134 if (value == QQuickContext2D::Start)
4135 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Left : QQuickContext2D::Right;
4136 else if (value == QQuickContext2D::End)
4137 value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Right: QQuickContext2D::Left;
4140 offset = metrics.horizontalAdvance(text) / 2;
4143 offset = metrics.horizontalAdvance(text);
4154 m_grabbedImage = grab;
4158QQmlRefPointer<QQuickCanvasPixmap>
QQuickContext2D::createPixmap(
const QUrl& url, QSizeF sourceSize)
4160 return m_canvas->loadedPixmap(url, sourceSize);
4165 const QFontMetrics metrics(state.font);
4166 int yoffset = baseLineOffset(
static_cast<QQuickContext2D::TextBaseLineType>(state.textBaseline), metrics);
4167 int xoffset = textAlignOffset(
static_cast<QQuickContext2D::TextAlignType>(state.textAlign), metrics, text);
4169 QPainterPath textPath;
4171 textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
4176static inline bool areCollinear(
const QPointF& a,
const QPointF& b,
const QPointF& c)
4179 return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x()));
4184 return (p >= a && p <= b) || (p >= b && p <= a);
4189 if (!state.invertibleCTM)
4192 if (!m_path.elementCount())
4195 if (!qt_is_finite(x) || !qt_is_finite(y))
4198 QPointF point(x, y);
4199 QTransform ctm = state.matrix;
4200 QPointF p = ctm.inverted().map(point);
4201 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y()))
4204 const_cast<QQuickContext2D *>(
this)->m_path.setFillRule(state.fillRule);
4206 bool contains = m_path.contains(p);
4210 QPolygonF border = m_path.toFillPolygon();
4212 QPointF p1 = border.at(0);
4215 for (
int i = 1; i < border.size(); ++i) {
4217 if (areCollinear(p, p1, p2)
4220 && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
4221 withinRange(p.x(), p1.x(), p2.x()) :
4222 withinRange(p.y(), p1.y(), p2.y()))) {
4255 return m_v4value.value();
4260 return QStringList() << QStringLiteral(
"2d");
4267 m_canvas = canvasItem;
4268 m_renderTarget = canvasItem->renderTarget();
4269 m_renderStrategy = canvasItem->renderStrategy();
4272 if (m_renderTarget == QQuickCanvasItem::FramebufferObject
4273 && m_renderStrategy == QQuickCanvasItem::Threaded
4274 && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
4275 m_renderTarget = QQuickCanvasItem::Image;
4281 if (m_renderTarget == QQuickCanvasItem::FramebufferObject)
4282 m_renderTarget = QQuickCanvasItem::Image;
4284 m_texture =
new QQuickContext2DImageTexture;
4287 m_texture->setCanvasWindow(canvasItem->canvasWindow().toRect());
4288 m_texture->setTileSize(canvasItem->tileSize());
4289 m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
4290 m_texture->setSmooth(canvasItem->smooth());
4291 m_texture->setAntialiasing(canvasItem->antialiasing());
4292 m_texture->setOnCustomThread(m_renderStrategy == QQuickCanvasItem::Threaded);
4293 m_thread = QThread::currentThread();
4295 QThread *renderThread = m_thread;
4296 if (m_renderStrategy == QQuickCanvasItem::Threaded)
4298 if (renderThread && renderThread != QThread::currentThread())
4300 connect(
m_texture, SIGNAL(textureChanged()), SIGNAL(textureChanged()));
4305void QQuickContext2D::
prepare(
const QSize& canvasSize,
const QSize& tileSize,
const QRect& canvasWindow,
const QRect& dirtyRect,
bool smooth,
bool antialiasing)
4307 if (m_texture->thread() == QThread::currentThread()) {
4308 m_texture->canvasChanged(canvasSize, tileSize, canvasWindow, dirtyRect, smooth, antialiasing);
4310 QEvent *e =
new QQuickContext2DTexture::CanvasChangeEvent(canvasSize,
4316 QCoreApplication::postEvent(m_texture, e);
4323 if (m_texture->thread() == QThread::currentThread())
4326 QCoreApplication::postEvent(m_texture,
new QQuickContext2DTexture::PaintEvent(m_buffer));
4338 if (m_texture->thread() == QThread::currentThread()) {
4341 }
else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
4342 qWarning() <<
"Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode";
4346 QCoreApplication::postEvent(m_texture,
new QEvent(QEvent::Type(QEvent::User + 10)));
4347 QMetaObject::invokeMethod(m_texture,
4349 Qt::BlockingQueuedConnection,
4350 Q_ARG(QRectF, bounds));
4352 QImage img = m_grabbedImage;
4353 m_grabbedImage = QImage();
4361 QV4::Scope scope(v4);
4363 QV4::ScopedObject proto(scope, QQuickJSContext2DPrototype::create(v4));
4364 proto->defineAccessorProperty(QStringLiteral(
"strokeStyle"), QQuickJSContext2D::method_get_strokeStyle, QQuickJSContext2D::method_set_strokeStyle);
4365 proto->defineAccessorProperty(QStringLiteral(
"font"), QQuickJSContext2D::method_get_font, QQuickJSContext2D::method_set_font);
4366 proto->defineAccessorProperty(QStringLiteral(
"fillRule"), QQuickJSContext2D::method_get_fillRule, QQuickJSContext2D::method_set_fillRule);
4367 proto->defineAccessorProperty(QStringLiteral(
"globalAlpha"), QQuickJSContext2D::method_get_globalAlpha, QQuickJSContext2D::method_set_globalAlpha);
4368 proto->defineAccessorProperty(QStringLiteral(
"lineCap"), QQuickJSContext2D::method_get_lineCap, QQuickJSContext2D::method_set_lineCap);
4369 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetX"), QQuickJSContext2D::method_get_shadowOffsetX, QQuickJSContext2D::method_set_shadowOffsetX);
4370 proto->defineAccessorProperty(QStringLiteral(
"shadowOffsetY"), QQuickJSContext2D::method_get_shadowOffsetY, QQuickJSContext2D::method_set_shadowOffsetY);
4371 proto->defineAccessorProperty(QStringLiteral(
"globalCompositeOperation"), QQuickJSContext2D::method_get_globalCompositeOperation, QQuickJSContext2D::method_set_globalCompositeOperation);
4372 proto->defineAccessorProperty(QStringLiteral(
"miterLimit"), QQuickJSContext2D::method_get_miterLimit, QQuickJSContext2D::method_set_miterLimit);
4373 proto->defineAccessorProperty(QStringLiteral(
"fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle);
4374 proto->defineAccessorProperty(QStringLiteral(
"shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor);
4375 proto->defineAccessorProperty(QStringLiteral(
"textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline);
4376#if QT_CONFIG(quick_path)
4377 proto->defineAccessorProperty(QStringLiteral(
"path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path);
4379 proto->defineAccessorProperty(QStringLiteral(
"lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin);
4380 proto->defineAccessorProperty(QStringLiteral(
"lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
4381 proto->defineAccessorProperty(QStringLiteral(
"textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
4382 proto->defineAccessorProperty(QStringLiteral(
"shadowBlur"), QQuickJSContext2D::method_get_shadowBlur, QQuickJSContext2D::method_set_shadowBlur);
4383 proto->defineAccessorProperty(QStringLiteral(
"lineDashOffset"), QQuickJSContext2D::method_get_lineDashOffset, QQuickJSContext2D::method_set_lineDashOffset);
4384 contextPrototype = proto;
4386 proto = scope.engine->newObject();
4387 proto->defineDefaultProperty(QStringLiteral(
"addColorStop"), QQuickContext2DStyle::gradient_proto_addColorStop, 0);
4388 gradientProto = proto;
4390 proto = scope.engine->newObject();
4391 proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length,
nullptr);
4392 pixelArrayProto = proto;
4401 if (m_stateStack.isEmpty())
4406 if (state.matrix != newState.matrix)
4407 buffer()->updateMatrix(newState.matrix);
4409 if (newState.globalAlpha != state.globalAlpha)
4410 buffer()->setGlobalAlpha(newState.globalAlpha);
4412 if (newState.globalCompositeOperation != state.globalCompositeOperation)
4413 buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
4415 if (newState.fillStyle != state.fillStyle)
4416 buffer()->setFillStyle(newState.fillStyle);
4418 if (newState.strokeStyle != state.strokeStyle)
4419 buffer()->setStrokeStyle(newState.strokeStyle);
4421 if (newState.lineWidth != state.lineWidth)
4422 buffer()->setLineWidth(newState.lineWidth);
4424 if (newState.lineCap != state.lineCap)
4425 buffer()->setLineCap(newState.lineCap);
4427 if (newState.lineJoin != state.lineJoin)
4428 buffer()->setLineJoin(newState.lineJoin);
4430 if (newState.miterLimit != state.miterLimit)
4431 buffer()->setMiterLimit(newState.miterLimit);
4433 if (newState.clip != state.clip || newState.clipPath != state.clipPath)
4436 if (newState.shadowBlur != state.shadowBlur)
4437 buffer()->setShadowBlur(newState.shadowBlur);
4439 if (newState.shadowColor != state.shadowColor)
4440 buffer()->setShadowColor(newState.shadowColor);
4442 if (newState.shadowOffsetX != state.shadowOffsetX)
4443 buffer()->setShadowOffsetX(newState.shadowOffsetX);
4445 if (newState.shadowOffsetY != state.shadowOffsetY)
4446 buffer()->setShadowOffsetY(newState.shadowOffsetY);
4448 if (newState.lineDash != state.lineDash)
4449 buffer()->setLineDash(newState.lineDash);
4451 m_path = state.matrix.map(m_path);
4453 m_path = state.matrix.inverted().map(m_path);
4457 m_stateStack.push(state);
4464 m_path = QPainterPath();
4466 newState.clipPath.setFillRule(Qt::WindingFill);
4468 m_stateStack.clear();
4469 m_stateStack.push(newState);
4471 m_buffer->clearRect(QRectF(0, 0, m_canvas->width(), m_canvas->height()));
4488 QV4::Scope scope(engine);
4489 QV4::Scoped<QQuickJSContext2D> wrapper(scope, engine->memoryManager->allocate<QQuickJSContext2D>());
4490 QV4::ScopedObject p(scope, ed->contextPrototype.value());
4491 wrapper->setPrototypeOf(p);
4492 wrapper->d()->setContext(
this);
4493 m_v4value = wrapper;
4499#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)
DEFINE_OBJECT_VTABLE(QQuickContext2DStyle)
QImage qt_image_convolute_filter(const QImage &src, const QVector< qreal > &weights, int radius=0)
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 bool qSetFontFamilyFromTokens(QFont &font, const QStringList &fontFamilyTokens)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData)
static bool areCollinear(const QPointF &a, const QPointF &b, const QPointF &c)
#define CHECK_CONTEXT_SETTER(r)
static bool qSetFontSizeFromToken(QFont &font, QStringView fontSizeToken)
static int qParseFontSizeFromToken(QStringView fontSizeToken, bool &ok)
static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionEngine *v4, QImage &&image)
DEFINE_OBJECT_VTABLE(QQuickJSContext2DPixelData)
static QString qt_composite_mode_to_string(QPainter::CompositionMode op)
static QStringList qExtractFontFamiliesFromString(QStringView fontFamiliesString)
DEFINE_OBJECT_VTABLE(QQuickJSContext2D)
QDebug Q_QUICK_EXPORT operator<<(QDebug debug, const QQuickWindow *item)
static QV4::ReturnedValue method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty object QtQuick::CanvasImageData::data Holds the one-dimensional array containing the dat...
static QV4::ReturnedValue method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty int QtQuick::CanvasImageData::height Holds the actual height dimension of the data in th...
static bool virtualPut(QV4::Managed *m, QV4::PropertyKey id, const QV4::Value &value, Value *receiver)
static QV4::ReturnedValue proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmltype CanvasPixelArray \inqmlmodule QtQuick
static QV4::ReturnedValue method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::isPointInPath(real x, real y)
static QV4::ReturnedValue method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::measureText(text)
static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::moveTo(real x, real y)
static QV4::ReturnedValue method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::bezierCurveTo(real cp1x, real cp1y, real cp2x,...
static QV4::ReturnedValue method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real x, real y, real w,...
static QV4::ReturnedValue method_setLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod QtQuick::Context2D::setLineDash(array pattern)
static QV4::ReturnedValue method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::quadraticCurveTo(real cpx, real cpy, real x,...
static QV4::ReturnedValue method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod QtQuick::Context2D::drawImage(variant image, real dx, real dy) Draws the given image on th...
static QV4::ReturnedValue method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::scale(real x, real y)
static QV4::ReturnedValue method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::stroke()
static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::closePath() Closes the current subpath by drawing a line to the...
static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::strokeRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::transform(real a, real b, real c, real d, real e,...
static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::translate(real x, real y)
static QV4::ReturnedValue method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::ellipse(real x, real y, real w, real h)
static QV4::ReturnedValue method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::resetTransform()
static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createRadialGradient(real x0, real y0, real r0,...
static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::clip()
static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createLinearGradient(real x0, real y0, real x1,...
static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::reset() Resets the context state and properties to the default ...
static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fillText(text, x, y)
static QV4::ReturnedValue method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::arc(real x, real y, real radius, real startAngle,...
static QV4::ReturnedValue method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::save() Pushes the current state onto the state stack.
static QV4::ReturnedValue method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::shear(real sh, real sv)
static QV4::ReturnedValue method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::lineTo(real x, real y)
static QV4::ReturnedValue method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::setTransform(real a, real b, real c, real d,...
static QV4::ReturnedValue method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::createConicalGradient(real x, real y, real angle)
static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::strokeText(text, x, y)
static QV4::ReturnedValue method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::restore() Pops the top state on the stack, restoring the contex...
static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::rect(real x, real y, real w, real h)
static QV4::ReturnedValue method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::beginPath()
static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::rotate(real angle) Rotate the canvas around the current origin ...
static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fillRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_getLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod array QtQuick::Context2D::getLineDash()
static QV4::ReturnedValue method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::arcTo(real x1, real y1, real x2, real y2,...
static QV4::ReturnedValue method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::fill()
static QV4::ReturnedValue method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod CanvasImageData QtQuick::Context2D::createImageData(real sw, real sh)
static QV4::ReturnedValue method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode) This is an...
static QV4::ReturnedValue method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::roundedRect(real x, real y, real w, real h, real xRadius,...
static QV4::ReturnedValue method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx,...
static QV4::ReturnedValue method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::text(string text, real x, real y)
static QV4::ReturnedValue method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h)
static QV4::ReturnedValue method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::lineJoin Holds the current line join style.
static QV4::ReturnedValue method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::globalCompositeOperation Holds the current the current compos...
static QV4::ReturnedValue method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty enumeration QtQuick::Context2D::fillRule Holds the current fill rule used for filling sh...
static QV4::ReturnedValue method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::lineCap Holds the current line cap style.
static QV4::ReturnedValue method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::lineDashOffset
static QV4::ReturnedValue method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::textAlign
static QV4::ReturnedValue method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::lineWidth Holds the current line width.
static QV4::ReturnedValue method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::font Holds the current font settings.
static QV4::ReturnedValue method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty variant QtQuick::Context2D::fillStyle Holds the current style used for filling shapes.
static QV4::ReturnedValue method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowBlur Holds the current level of blur applied to shadows
static QV4::ReturnedValue method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowOffsetY Holds the current shadow offset in the positive v...
static QV4::ReturnedValue method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::miterLimit Holds the current miter limit ratio.
static QV4::ReturnedValue method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::shadowColor Holds the current shadow color.
static QV4::ReturnedValue method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty variant QtQuick::Context2D::strokeStyle Holds the current color or style to use for the ...
static QV4::ReturnedValue method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
static QV4::ReturnedValue method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty string QtQuick::Context2D::textBaseline
static QV4::ReturnedValue method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
\qmlproperty real QtQuick::Context2D::shadowOffsetX Holds the current shadow offset in the positive h...
static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack)
QQuickContext2D * context()
void setContext(QQuickContext2D *context)