11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
21PROMEKI_NAMESPACE_BEGIN
65 PROMEKI_DATATYPE(XYZColor, DataTypeXYZColor, 1)
68 Error writeToStream(DataStream &s) const;
70 template <uint32_t V> static Result<XYZColor> readFromStream(DataStream &s);
73 using DataType = Array<
double, 3>;
76 XYZColor() : d{-1.0, -1.0, -1.0} {}
82 XYZColor(
const DataType &val) : d(val) {}
90 XYZColor(
double x,
double y,
double z) : d(x, y, z) {}
98 bool isValid()
const {
99 for (
size_t i = 0; i < d.size(); ++i)
100 if (d[i] < 0.0)
return false;
105 const DataType &data()
const {
return d; }
107 DataType &data() {
return d; }
109 double x() {
return d[0]; }
111 double y() {
return d[1]; }
113 double z() {
return d[2]; }
115 void set(
double x,
double y,
double z) { d = {x, y, z}; }
117 void setX(
double val) { d[0] = val; }
119 void setY(
double val) { d[1] = val; }
121 void setZ(
double val) { d[2] = val; }
129 XYZColor lerp(
const XYZColor &val,
double t)
const {
return d.lerp(val.d, t); }
132 operator String() {
return toString(); }
135 String toString()
const {
return String::sprintf(
"XYZ(%g, %g, %g)", d[0], d[1], d[2]); }
144 static Result<XYZColor> fromString(
const String &s) {
145 String body = s.trim();
146 if (body.startsWith(
"XYZ(") || body.startsWith(
"xyz(")) body = body.mid(4);
147 if (body.startsWith(
"(")) body = body.mid(1);
148 if (body.endsWith(
")")) body = body.left(body.length() - 1);
149 StringList parts = body.split(
",");
150 if (parts.size() != 3)
return makeError<XYZColor>(Error::ParseFailed);
152 for (
size_t i = 0; i < 3; ++i) {
154 double v = parts[i].trim().to<
double>(&ex);
155 if (ex.isError())
return makeError<XYZColor>(Error::ParseFailed);
158 return makeResult(std::move(out));
167PROMEKI_FORMAT_VIA_TOSTRING(promeki::XYZColor);