Skip to content

Commit

Permalink
Add QColor support to v4.
Browse files Browse the repository at this point in the history
Change-Id: I033e92007f894d45695ea48d7f954d534a2fadee
Reviewed-by: Chris Adams <christopher.adams@nokia.com>
Reviewed-by: Matthew Vogt <matthew.vogt@nokia.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
  • Loading branch information
Michael Brasser authored and Qt by Nokia committed Mar 2, 2012
1 parent 04fb631 commit 4dde313
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 1 deletion.
76 changes: 76 additions & 0 deletions src/declarative/qml/v4/qv4bindings.cpp
Expand Up @@ -50,6 +50,7 @@
#include <private/qdeclarativeprofilerservice_p.h>
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativetrace_p.h>
#include <private/qdeclarativestringconverters_p.h>

#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtCore/qnumeric.h>
Expand Down Expand Up @@ -86,9 +87,11 @@ struct Register {
QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
QString *getstringptr() { return (QString *)typeDataPtr(); }
QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
QColor *getcolorptr() { return (QColor *)typeDataPtr(); }
const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
const QString *getstringptr() const { return (QString *)typeDataPtr(); }
const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); }

void *typeDataPtr() { return (void *)&data; }
void *typeMemory() { return (void *)data; }
Expand All @@ -112,6 +115,7 @@ struct Register {
inline void cleanup();
inline void cleanupString();
inline void cleanupUrl();
inline void cleanupColor();
inline void cleanupVariant();

inline void copy(const Register &other);
Expand All @@ -135,6 +139,8 @@ void Register::cleanup()
getstringptr()->~QString();
} else if (dataType == QUrlType) {
geturlptr()->~QUrl();
} else if (dataType == QColorType) {
getcolorptr()->~QColor();
} else if (dataType == QVariantType) {
getvariantptr()->~QVariant();
}
Expand All @@ -154,6 +160,12 @@ void Register::cleanupUrl()
setUndefined();
}

void Register::cleanupColor()
{
getcolorptr()->~QColor();
setUndefined();
}

void Register::cleanupVariant()
{
getvariantptr()->~QVariant();
Expand All @@ -168,6 +180,8 @@ void Register::copy(const Register &other)
new (getstringptr()) QString(*other.getstringptr());
else if (other.dataType == QUrlType)
new (geturlptr()) QUrl(*other.geturlptr());
else if (other.dataType == QColorType)
new (getcolorptr()) QColor(*other.getcolorptr());
else if (other.dataType == QVariantType)
new (getvariantptr()) QVariant(*other.getvariantptr());
}
Expand All @@ -181,6 +195,8 @@ void Register::init(Type type)
new (getstringptr()) QString();
else if (dataType == QUrlType)
new (geturlptr()) QUrl();
else if (dataType == QColorType)
new (getcolorptr()) QColor();
else if (dataType == QVariantType)
new (getvariantptr()) QVariant();
}
Expand Down Expand Up @@ -663,6 +679,11 @@ inline quint32 QV4Bindings::toUint32(qreal n)
MARK_REGISTER(reg); \
}

#define COLOR_REGISTER(reg) { \
registers[(reg)].settype(QColorType); \
MARK_REGISTER(reg); \
}

#define VARIANT_REGISTER(reg) { \
registers[(reg)].settype(QVariantType); \
MARK_REGISTER(reg); \
Expand Down Expand Up @@ -1023,6 +1044,27 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertStringToUrl, unaryop)

QML_V4_BEGIN_INSTR(ConvertStringToColor, unaryop)
{
const Register &src = registers[instr->unaryop.src];
Register &output = registers[instr->unaryop.output];
// ### NaN
if (src.isUndefined()) {
output.setUndefined();
} else {
const QString tmp(*src.getstringptr());
if (instr->unaryop.src == instr->unaryop.output) {
output.cleanupString();
MARK_CLEAN_REGISTER(instr->unaryop.output);
}
QColor *colorPtr = output.getcolorptr();
new (colorPtr) QColor(QDeclarativeStringConverters::colorFromString(tmp));

COLOR_REGISTER(instr->unaryop.output);
}
}
QML_V4_END_INSTR(ConvertStringToUrl, unaryop)

QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
Expand Down Expand Up @@ -1060,6 +1102,40 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertUrlToString, unaryop)

QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
Register &output = registers[instr->unaryop.output];
// ### NaN
if (src.isUndefined()) {
output.setUndefined();
} else {
// for compatibility with color behavior in v8, always true
output.setbool(true);
}
}
QML_V4_END_INSTR(ConvertColorToBool, unaryop)

QML_V4_BEGIN_INSTR(ConvertColorToString, unaryop)
{
const Register &src = registers[instr->unaryop.src];
Register &output = registers[instr->unaryop.output];
// ### NaN
if (src.isUndefined()) {
output.setUndefined();
} else {
const QColor tmp(*src.getcolorptr());
if (instr->unaryop.src == instr->unaryop.output) {
output.cleanupColor();
MARK_CLEAN_REGISTER(instr->unaryop.output);
}
// to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
new (output.getstringptr()) QString(QVariant(tmp).toString());
STRING_REGISTER(instr->unaryop.output);
}
}
QML_V4_END_INSTR(ConvertColorToString, unaryop)

QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
{
const Register &src = registers[instr->unaryop.src];
Expand Down
20 changes: 20 additions & 0 deletions src/declarative/qml/v4/qv4compiler.cpp
Expand Up @@ -344,6 +344,9 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
case QMetaType::QUrl:
regType = QUrlType;
break;
case QMetaType::QColor:
regType = QColorType;
break;

default:
if (propTy == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) {
Expand Down Expand Up @@ -581,6 +584,12 @@ void QV4CompilerPrivate::convertToBool(IR::Expr *expr, int reg)
gen(i);
} return;

case IR::ColorType: {
Instr::ConvertColorToBool i;
i.output = i.src = reg;
gen(i);
} return;

default:
discard();
break;
Expand Down Expand Up @@ -880,6 +889,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::RealType: opcode = V4Instr::ConvertRealToBool; break;
case IR::StringType: opcode = V4Instr::ConvertStringToBool; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break;
case IR::ColorType: opcode = V4Instr::ConvertColorToBool; break;
default: break;
} // switch
} else if (targetTy == IR::IntType) {
Expand Down Expand Up @@ -908,6 +918,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::IntType: opcode = V4Instr::ConvertIntToString; break;
case IR::RealType: opcode = V4Instr::ConvertRealToString; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToString; break;
case IR::ColorType: opcode = V4Instr::ConvertColorToString; break;
default: break;
} // switch
} else if (targetTy == IR::UrlType) {
Expand All @@ -920,11 +931,17 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::BoolType: gen(V4Instr::ConvertBoolToString, convToString); sourceTy = IR::StringType; break;
case IR::IntType: gen(V4Instr::ConvertIntToString, convToString); sourceTy = IR::StringType; break;
case IR::RealType: gen(V4Instr::ConvertRealToString, convToString); sourceTy = IR::StringType; break;
case IR::ColorType: gen(V4Instr::ConvertColorToString, convToString); sourceTy = IR::StringType; break;
default: break;
} // switch

if (sourceTy == IR::StringType)
opcode = V4Instr::ConvertStringToUrl;
} else if (targetTy == IR::ColorType) {
switch (sourceTy) {
case IR::StringType: opcode = V4Instr::ConvertStringToColor; break;
default: break;
} // switch
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
Expand Down Expand Up @@ -989,6 +1006,9 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
case IR::UrlType:
test.regType = QMetaType::QUrl;
break;
case IR::ColorType:
test.regType = QMetaType::QColor;
break;
case IR::SGAnchorLineType:
test.regType = QDeclarativeMetaType::QQuickAnchorLineMetaTypeId();
break;
Expand Down
9 changes: 9 additions & 0 deletions src/declarative/qml/v4/qv4instruction.cpp
Expand Up @@ -171,12 +171,21 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertStringToUrl:
INSTR_DUMP << "\t" << "ConvertStringToUrl" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertStringToColor:
INSTR_DUMP << "\t" << "ConvertStringToColor" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertUrlToBool:
INSTR_DUMP << "\t" << "ConvertUrlToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertUrlToString:
INSTR_DUMP << "\t" << "ConvertUrlToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertColorToBool:
INSTR_DUMP << "\t" << "ConvertColorToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertColorToString:
INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
Expand Down
3 changes: 3 additions & 0 deletions src/declarative/qml/v4/qv4instruction_p.h
Expand Up @@ -92,8 +92,11 @@ QT_BEGIN_NAMESPACE
F(ConvertStringToInt, unaryop) \
F(ConvertStringToReal, unaryop) \
F(ConvertStringToUrl, unaryop) \
F(ConvertStringToColor, unaryop) \
F(ConvertUrlToBool, unaryop) \
F(ConvertUrlToString, unaryop) \
F(ConvertColorToBool, unaryop) \
F(ConvertColorToString, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinReal, unaryop) \
F(MathCosReal, unaryop) \
Expand Down
3 changes: 2 additions & 1 deletion src/declarative/qml/v4/qv4ir.cpp
Expand Up @@ -59,6 +59,7 @@ inline const char *typeName(Type t)
case VoidType: return "void";
case StringType: return "string";
case UrlType: return "url";
case ColorType: return "color";
case SGAnchorLineType: return "SGAnchorLine";
case AttachType: return "AttachType";
case ObjectType: return "object";
Expand All @@ -77,7 +78,7 @@ inline bool isNumberType(IR::Type ty)

inline bool isStringType(IR::Type ty)
{
return ty == IR::StringType || ty == IR::UrlType;
return ty == IR::StringType || ty == IR::UrlType || ty == IR::ColorType;
}

IR::Type maxType(IR::Type left, IR::Type right)
Expand Down
1 change: 1 addition & 0 deletions src/declarative/qml/v4/qv4ir_p.h
Expand Up @@ -142,6 +142,7 @@ enum Type {
VoidType,
StringType,
UrlType,
ColorType,
SGAnchorLineType,
AttachType,
ObjectType,
Expand Down
3 changes: 3 additions & 0 deletions src/declarative/qml/v4/qv4irbuilder.cpp
Expand Up @@ -69,6 +69,9 @@ static IR::Type irTypeFromVariantType(int t, QDeclarativeEnginePrivate *engine,
case QMetaType::QUrl:
return IR::UrlType;

case QMetaType::QColor:
return IR::ColorType;

default:
if (t == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) {
return IR::SGAnchorLineType;
Expand Down
1 change: 1 addition & 0 deletions src/declarative/qml/v4/qv4program_p.h
Expand Up @@ -96,6 +96,7 @@ enum QDeclarativeRegisterType {
QStringType = FirstCleanupType,
QUrlType,
QVariantType,
QColorType
};

const char *QV4Program::data() const
Expand Down
18 changes: 18 additions & 0 deletions tests/auto/declarative/v4/data/colorType.qml
@@ -0,0 +1,18 @@
import QtQuick 2.0

QtObject {
property bool useMyColor: true
property color myColor: "red"
property color myOtherColor: "green"

property color test1: useMyColor ? myColor : myOtherColor
property color test2: useMyColor ? "red" : "green"
property color test3: useMyColor ? myColor : "green"

property bool test4: !myColor ? false : true

property bool test5: myColor != "red"
property bool test6: myColor == "#ff0000"
property bool test7: myColor != "#00ff00"
}

18 changes: 18 additions & 0 deletions tests/auto/declarative/v4/tst_v4.cpp
Expand Up @@ -45,6 +45,7 @@
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
#include <QtGui/qcolor.h>

#include <private/qv4compiler_p.h>

Expand Down Expand Up @@ -73,6 +74,7 @@ private slots:
void stringComparison();
void unaryMinus();
void unaryPlus();
void colorType();

private:
QDeclarativeEngine engine;
Expand Down Expand Up @@ -348,6 +350,22 @@ void tst_v4::unaryPlus()
delete o;
}

void tst_v4::colorType()
{
QDeclarativeComponent component(&engine, testFileUrl("colorType.qml"));

QObject *o = component.create();
QVERIFY(o != 0);
QCOMPARE(o->property("test1").value<QColor>(), QColor("red"));
QCOMPARE(o->property("test2").value<QColor>(), QColor("red"));
QCOMPARE(o->property("test3").value<QColor>(), QColor("red"));
QCOMPARE(o->property("test4").toBool(), true);
QCOMPARE(o->property("test5").toBool(), true);
QCOMPARE(o->property("test6").toBool(), true);
QCOMPARE(o->property("test7").toBool(), true);
delete o;
}

QTEST_MAIN(tst_v4)

#include "tst_v4.moc"

0 comments on commit 4dde313

Please sign in to comment.