Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorSet::Private Class Reference

#include <KoColorSet_p.h>

Public Member Functions

KisSwatchGroupSP global ()
 
bool init ()
 
bool loadAcb ()
 
bool loadAco ()
 
bool loadAct ()
 
bool loadAse ()
 
bool loadCss ()
 
bool loadGpl ()
 
bool loadKpl ()
 
bool loadPsp ()
 
bool loadRiff ()
 
bool loadSbz ()
 
bool loadXml ()
 
 Private (KoColorSet *a_colorSet)
 
bool saveGpl (QIODevice *dev) const
 
bool saveKpl (QIODevice *dev) const
 

Public Attributes

KoColorSetcolorSet {0}
 
int columns
 
QString comment
 
QByteArray data
 
bool isLocked {false}
 
KoColorSet::PaletteType paletteType {UNKNOWN}
 
QList< KisSwatchGroupSPswatchGroups
 
KUndo2Stack undoStack
 

Private Member Functions

KoColorSet::PaletteType detectFormat (const QString &fileName, const QByteArray &ba)
 
const KoColorProfileloadColorProfile (QScopedPointer< KoStore > &store, const QString &path, const QString &modelId, const QString &colorDepthId)
 
bool loadKplColorset (QScopedPointer< KoStore > &store)
 
void loadKplGroup (const QDomDocument &doc, const QDomElement &parentElement, KisSwatchGroupSP group, QString version)
 
bool loadKplProfiles (QScopedPointer< KoStore > &store)
 
bool loadSbzSwatchbook (QScopedPointer< KoStore > &store)
 
bool loadScribusXmlPalette (KoColorSet *set, QXmlStreamReader *xml)
 
quint8 readByte (QIODevice *io)
 
float readFloat (QIODevice *io)
 
qint32 readInt (QIODevice *io)
 
quint16 readShort (QIODevice *io)
 
QString readUnicodeString (QIODevice *io, bool sizeIsInt=false)
 
void saveKplGroup (QDomDocument &doc, QDomElement &groupEle, const KisSwatchGroupSP group, QSet< const KoColorSpace * > &colorSetSet) const
 
void scribusParseColor (KoColorSet *set, QXmlStreamReader *xml)
 

Friends

struct AddGroupCommand
 
struct AddSwatchCommand
 
struct ChangeGroupNameCommand
 
struct ClearCommand
 
struct MoveGroupCommand
 
struct RemoveGroupCommand
 
struct RemoveSwatchCommand
 
struct SetColumnCountCommand
 
struct SetCommentCommand
 
struct SetPaletteTypeCommand
 

Detailed Description

Definition at line 27 of file KoColorSet_p.h.

Constructor & Destructor Documentation

◆ Private()

KoColorSet::Private::Private ( KoColorSet * a_colorSet)

Definition at line 1041 of file KoColorSet.cpp.

1042 : colorSet(a_colorSet)
1043{
1046 group->setName(KoColorSet::GLOBAL_GROUP_NAME);
1047 swatchGroups.clear();
1048 swatchGroups.append(group);
1049}
void setUndoLimit(int limit)
The KisSwatchGroup class stores a matrix of color swatches swatches can accessed using (x,...
KUndo2Stack undoStack
KoColorSet * colorSet
QList< KisSwatchGroupSP > swatchGroups
static const QString GLOBAL_GROUP_NAME
Definition KoColorSet.h:33

References KoColorSet::GLOBAL_GROUP_NAME, KUndo2QStack::setUndoLimit(), swatchGroups, and undoStack.

Member Function Documentation

◆ detectFormat()

KoColorSet::PaletteType KoColorSet::Private::detectFormat ( const QString & fileName,
const QByteArray & ba )
private

Definition at line 1051 of file KoColorSet.cpp.

1052{
1053 QFileInfo fi(fileName);
1054
1055 // .pal
1056 if (ba.startsWith("RIFF") && ba.indexOf("PAL data", 8)) {
1057 return KoColorSet::RIFF_PAL;
1058 }
1059 // .gpl
1060 else if (ba.startsWith("GIMP Palette")) {
1061 return KoColorSet::GPL;
1062 }
1063 // .pal
1064 else if (ba.startsWith("JASC-PAL")) {
1065 return KoColorSet::PSP_PAL;
1066 }
1067 else if (ba.contains("krita/x-colorset") || ba.contains("application/x-krita-palette")) {
1068 return KoColorSet::KPL;
1069 }
1070 else if (fi.suffix().toLower() == "aco") {
1071 return KoColorSet::ACO;
1072 }
1073 else if (fi.suffix().toLower() == "act") {
1074 return KoColorSet::ACT;
1075 }
1076 else if (fi.suffix().toLower() == "xml") {
1077 return KoColorSet::XML;
1078 }
1079 else if (fi.suffix().toLower() == "sbz") {
1080 return KoColorSet::SBZ;
1081 }
1082 else if (fi.suffix().toLower() == "ase" || ba.startsWith("ASEF")) {
1083 return KoColorSet::ASE;
1084 }
1085 else if (fi.suffix().toLower() == "acb" || ba.startsWith("8BCB")) {
1086 return KoColorSet::ACB;
1087 }
1088 else if (fi.suffix().toLower() == "css") {
1089 return KoColorSet::CSS;
1090 }
1091 return KoColorSet::UNKNOWN;
1092}

References KoColorSet::ACB, KoColorSet::ACO, KoColorSet::ACT, KoColorSet::ASE, KoColorSet::CSS, KoColorSet::GPL, KoColorSet::KPL, KoColorSet::PSP_PAL, KoColorSet::RIFF_PAL, KoColorSet::SBZ, KoColorSet::UNKNOWN, and KoColorSet::XML.

◆ global()

KisSwatchGroupSP KoColorSet::Private::global ( )
inline

Definition at line 34 of file KoColorSet_p.h.

34 {
35 Q_ASSERT(swatchGroups.size() > 0 && swatchGroups.first()->name() == GLOBAL_GROUP_NAME);
36 return swatchGroups.first();
37 }

References KoColorSet::GLOBAL_GROUP_NAME, and swatchGroups.

◆ init()

bool KoColorSet::Private::init ( )

Definition at line 1270 of file KoColorSet.cpp.

1271{
1272 // just in case this is a reload (eg by KoEditColorSetDialog),
1273 swatchGroups.clear();
1274 KisSwatchGroupSP globalGroup(new KisSwatchGroup);
1275 globalGroup->setName(KoColorSet::GLOBAL_GROUP_NAME);
1276 swatchGroups.append(globalGroup);
1277 undoStack.clear();
1278
1279 if (colorSet->filename().isNull()) {
1280 warnPigment << "Cannot load palette" << colorSet->name() << "there is no filename set";
1281 return false;
1282 }
1283 if (data.isNull()) {
1284 QFile file(colorSet->filename());
1285 if (file.size() == 0) {
1286 warnPigment << "Cannot load palette" << colorSet->name() << "there is no data available";
1287 return false;
1288 }
1289 if (!file.open(QIODevice::ReadOnly)) {
1290 warnPigment << "Cannot load palette" << colorSet->name() << ":" << file.errorString();
1291 return false;
1292 }
1293 data = file.readAll();
1294 file.close();
1295 }
1296
1297 bool res = false;
1299 switch(paletteType) {
1300 case GPL:
1301 res = loadGpl();
1302 break;
1303 case ACT:
1304 res = loadAct();
1305 break;
1306 case RIFF_PAL:
1307 res = loadRiff();
1308 break;
1309 case PSP_PAL:
1310 res = loadPsp();
1311 break;
1312 case ACO:
1313 res = loadAco();
1314 break;
1315 case XML:
1316 res = loadXml();
1317 break;
1318 case KPL:
1319 res = loadKpl();
1320 break;
1321 case SBZ:
1322 res = loadSbz();
1323 break;
1324 case ASE:
1325 res = loadAse();
1326 break;
1327 case ACB:
1328 res = loadAcb();
1329 break;
1330 case CSS:
1331 res = loadCss();
1332 break;
1333 default:
1334 res = false;
1335 }
1336 if (paletteType != KPL) {
1337 int rowCount = global()->colorCount() / global()->columnCount();
1338 if (global()->colorCount() % global()->columnCount() > 0) {
1339 rowCount ++;
1340 }
1341 global()->setRowCount(rowCount);
1342 }
1343 colorSet->setValid(res);
1345
1346 data.clear();
1347 undoStack.clear();
1348
1349 return res;
1350}
#define warnPigment
KoColorSet::PaletteType detectFormat(const QString &fileName, const QByteArray &ba)
KoColorSet::PaletteType paletteType
KisSwatchGroupSP global()
int rowCount() const
void updateThumbnail() override
updateThumbnail updates the thumbnail for this resource. Reimplement if your thumbnail is something e...
int columnCount() const
quint32 colorCount() const
void setValid(bool valid)
QString filename
QString name

References KoColorSet::ACB, KoColorSet::ACO, KoColorSet::ACT, KoColorSet::ASE, KUndo2QStack::clear(), KoColorSet::colorCount(), KoColorSet::columnCount(), KoColorSet::CSS, KoColorSet::GLOBAL_GROUP_NAME, KoColorSet::GPL, KoColorSet::KPL, KoColorSet::paletteType(), KoColorSet::PSP_PAL, KoColorSet::RIFF_PAL, KoColorSet::rowCount(), KoColorSet::SBZ, KoColorSet::undoStack(), warnPigment, and KoColorSet::XML.

◆ loadAcb()

bool KoColorSet::Private::loadAcb ( )

Definition at line 2321 of file KoColorSet.cpp.

2322{
2323
2324 QFileInfo info(colorSet->filename());
2325
2326 QBuffer buf(&data);
2327 buf.open(QBuffer::ReadOnly);
2328
2329 QByteArray signature; // should be "8BCB";
2330 signature = buf.read(4);
2331 quint16 version = readShort(&buf);
2332 quint16 bookID = readShort(&buf);
2333 Q_UNUSED(bookID);
2334
2335 if (signature != "8BCB" && version!= 1) {
2336 return false;
2337 }
2338
2340 for (int i = 0; i< 4; i++) {
2341
2342 QString metadataString = readUnicodeString(&buf, true);
2343 if (metadataString.startsWith("\"")) {
2344 metadataString = metadataString.remove(0, 1);
2345 }
2346 if (metadataString.endsWith("\"")) {
2347 metadataString.chop(1);
2348 }
2349 if (metadataString.startsWith("$$$/")) {
2350 if (metadataString.contains("=")) {
2351 metadataString = metadataString.split("=").last();
2352 } else {
2353 metadataString = QString();
2354 }
2355 }
2356 metadata.append(metadataString);
2357 }
2358 QString title = metadata.at(0);
2359 colorSet->setName(title);
2360 QString prefix = metadata.at(1);
2361 QString postfix = metadata.at(2);
2362 QString description = metadata.at(3);
2363 colorSet->setComment(description);
2364
2365 quint16 numColors = readShort(&buf);
2366 quint16 numColumns = readShort(&buf);
2367 numColumns = numColumns > 0 ? numColumns : 8; // overwrite with sane default in case of 0
2368 colorSet->setColumnCount(numColumns);
2369 quint16 numKeyColorPage = readShort(&buf);
2370 Q_UNUSED(numKeyColorPage);
2371 quint16 colorType = readShort(&buf);
2372
2374 if (colorType == 2) {
2375 QString profileName = "U.S. Web Coated (SWOP) v2";
2377 } else if (colorType == 7) {
2379 }
2380
2381 for (quint16 i = 0; i < numColors; i++) {
2382 KisSwatch swatch;
2384 name << prefix;
2385 name << readUnicodeString(&buf, true);
2386 name << postfix;
2387 swatch.setName(name.join(" ").trimmed());
2388 QByteArray key; // should be "8BCB";
2389 key = buf.read(6);
2390 swatch.setId(QString::fromLatin1(key));
2391 swatch.setSpotColor(true);
2392 quint8 c1 = readByte(&buf);
2393 quint8 c2 = readByte(&buf);
2394 quint8 c3 = readByte(&buf);
2395 KoColor c(cs);
2396 if (colorType == 0) {
2397 c.data()[0] = c3;
2398 c.data()[1] = c2;
2399 c.data()[2] = c1;
2400 } else if (colorType == 2) {
2401 quint8 c4 = readByte(&buf);
2402 c.data()[0] = c1;
2403 c.data()[1] = c2;
2404 c.data()[2] = c3;
2405 c.data()[3] = c4;
2406 } else if (colorType == 7) {
2407 c.data()[0] = c1;
2408 c.data()[1] = c2;
2409 c.data()[2] = c3;
2410 }
2411 c.setOpacity(1.0);
2412 swatch.setColor(c);
2413 colorSet->addSwatch(swatch);
2414 }
2415
2416 return true;
2417}
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
void setSpotColor(bool spotColor)
Definition KisSwatch.cpp:38
void setColor(const KoColor &color)
Definition KisSwatch.cpp:32
void setId(const QString &id)
Definition KisSwatch.cpp:26
void setName(const QString &name)
Definition KisSwatch.cpp:20
quint8 readByte(QIODevice *io)
quint16 readShort(QIODevice *io)
QString readUnicodeString(QIODevice *io, bool sizeIsInt=false)
void setColumnCount(int columns)
void addSwatch(const KisSwatch &swatch, const QString &groupName=GLOBAL_GROUP_NAME, int column=-1, int row=-1)
Add a color to the palette.
void setComment(QString comment)
QString id() const
Definition KoID.cpp:63
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())
void setName(const QString &name)
QMap< QString, QVariant > metadata
KoResourceSignature signature() const

References CMYKAColorModelID, KoColorSpaceRegistry::colorSpace(), KoColor::data(), KoID::id(), KoColorSpaceRegistry::instance(), Integer8BitsColorDepthID, LABAColorModelID, KoResource::metadata, KoResource::name, KoColorSpaceRegistry::rgb8(), KisSwatch::setColor(), KisSwatch::setId(), KisSwatch::setName(), KoColor::setOpacity(), KisSwatch::setSpotColor(), KoResource::signature(), and KoResource::version.

◆ loadAco()

bool KoColorSet::Private::loadAco ( )

Definition at line 1817 of file KoColorSet.cpp.

1818{
1819 QFileInfo info(colorSet->filename());
1820 colorSet->setName(info.completeBaseName());
1821
1822 QBuffer buf(&data);
1823 buf.open(QBuffer::ReadOnly);
1824
1825 quint16 version = readShort(&buf);
1826 quint16 numColors = readShort(&buf);
1827 KisSwatch swatch;
1828
1829 if (version == 1 && buf.size() > 4+numColors*10) {
1830 buf.seek(4+numColors*10);
1831 version = readShort(&buf);
1832 numColors = readShort(&buf);
1833 }
1834
1835 const quint16 quint16_MAX = 65535;
1836
1838
1839 for (int i = 0; i < numColors && !buf.atEnd(); ++i) {
1840
1841 quint16 colorSpace = readShort(&buf);
1842 quint16 ch1 = readShort(&buf);
1843 quint16 ch2 = readShort(&buf);
1844 quint16 ch3 = readShort(&buf);
1845 quint16 ch4 = readShort(&buf);
1846
1847 bool skip = false;
1848 if (colorSpace == 0) { // RGB
1850 KoColor c(KoColorSpaceRegistry::instance()->rgb16(srgb));
1851 reinterpret_cast<quint16*>(c.data())[0] = ch3;
1852 reinterpret_cast<quint16*>(c.data())[1] = ch2;
1853 reinterpret_cast<quint16*>(c.data())[2] = ch1;
1854 c.setOpacity(OPACITY_OPAQUE_U8);
1855 swatch.setColor(c);
1856 }
1857 else if (colorSpace == 1) { // HSB
1858 QColor qc;
1859 qc.setHsvF(ch1 / 65536.0, ch2 / 65536.0, ch3 / 65536.0);
1860 KoColor c(qc, KoColorSpaceRegistry::instance()->rgb16());
1861 c.setOpacity(OPACITY_OPAQUE_U8);
1862 swatch.setColor(c);
1863 }
1864 else if (colorSpace == 2) { // CMYK
1866 reinterpret_cast<quint16*>(c.data())[0] = quint16_MAX - ch1;
1867 reinterpret_cast<quint16*>(c.data())[1] = quint16_MAX - ch2;
1868 reinterpret_cast<quint16*>(c.data())[2] = quint16_MAX - ch3;
1869 reinterpret_cast<quint16*>(c.data())[3] = quint16_MAX - ch4;
1870 c.setOpacity(OPACITY_OPAQUE_U8);
1871 swatch.setColor(c);
1872 }
1873 else if (colorSpace == 7) { // LAB
1875 reinterpret_cast<quint16*>(c.data())[0] = ch3;
1876 reinterpret_cast<quint16*>(c.data())[1] = ch2;
1877 reinterpret_cast<quint16*>(c.data())[2] = ch1;
1879 swatch.setColor(c);
1880 }
1881 else if (colorSpace == 8) { // GRAY
1883 reinterpret_cast<quint16*>(c.data())[0] = ch1 * (quint16_MAX / 10000);
1885 swatch.setColor(c);
1886 }
1887 else {
1888 warnPigment << "Unsupported colorspace in palette" << colorSet->filename() << "(" << colorSpace << ")";
1889 skip = true;
1890 }
1891
1892 if (version == 2) {
1893 QString name = readUnicodeString(&buf, true);
1894 swatch.setName(name);
1895 }
1896 if (!skip) {
1897 group->addSwatch(swatch);
1898 }
1899 }
1900 return true;
1901}
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const quint8 OPACITY_OPAQUE_U8
KisSwatchGroupSP getGlobalGroup() const
getGlobalGroup
virtual const KoColorProfile * profile() const =0
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
quint8 * data()
Definition KoColor.h:144
const quint16 quint16_MAX
Definition kis_global.h:25

References CMYKAColorModelID, KoColor::data(), GrayAColorModelID, KoID::id(), KoColorSpaceRegistry::instance(), Integer16BitsColorDepthID, KoResource::name, OPACITY_OPAQUE_U8, KoColorSpace::profile(), quint16_MAX, KoColorSpaceRegistry::rgb8(), KisSwatch::setColor(), KisSwatch::setName(), KoColor::setOpacity(), KoResource::version, and warnPigment.

◆ loadAct()

bool KoColorSet::Private::loadAct ( )

Definition at line 1455 of file KoColorSet.cpp.

1456{
1457 QFileInfo info(colorSet->filename());
1458 colorSet->setName(info.completeBaseName());
1459 KisSwatch swatch;
1460 int numOfTriplets = int(data.size() / 3);
1461 for (int i = 0; i < numOfTriplets * 3; i += 3) {
1462 quint8 r = data[i];
1463 quint8 g = data[i+1];
1464 quint8 b = data[i+2];
1465 swatch.setColor(KoColor(QColor(r, g, b), KoColorSpaceRegistry::instance()->rgb8()));
1466 global()->addSwatch(swatch);
1467 }
1468 return true;
1469}

References KoColorSpaceRegistry::instance(), and KisSwatch::setColor().

◆ loadAse()

bool KoColorSet::Private::loadAse ( )

Definition at line 2216 of file KoColorSet.cpp.

2217{
2218 QFileInfo info(colorSet->filename());
2219 colorSet->setName(info.completeBaseName());
2220
2221 QBuffer buf(&data);
2222 buf.open(QBuffer::ReadOnly);
2223
2224 QByteArray signature; // should be "ASEF";
2225 signature = buf.read(4);
2226 quint16 version = readShort(&buf);
2227 quint16 version2 = readShort(&buf);
2228
2229 if (signature != "ASEF" && version!= 1 && version2 != 0) {
2230 qWarning() << "incorrect header:" << signature << version << version2;
2231 return false;
2232 }
2233 qint32 numBlocks = readInt(&buf);
2234
2235 QByteArray groupStart("\xC0\x01");
2236 QByteArray groupEnd("\xC0\x02");
2237 QByteArray swatchSig("\x00\x01");
2238
2239 bool inGroup = false;
2240 QString groupName;
2241 for (qint32 i = 0; i < numBlocks; i++) {
2242 QByteArray blockType;
2243 blockType = buf.read(2);
2244 qint32 blockSize = readInt(&buf);
2245 qint64 pos = buf.pos();
2246
2247 if (blockType == groupStart) {
2248 groupName = readUnicodeString(&buf);
2249 colorSet->addGroup(groupName);
2250 inGroup = true;
2251 }
2252 else if (blockType == groupEnd) {
2253 int colorCount = colorSet->getGroup(groupName)->colorCount();
2254 int columns = colorSet->columnCount();
2255 int rows = colorCount/columns;
2256 if (colorCount % columns > 0) {
2257 rows += 1;
2258 }
2259 colorSet->getGroup(groupName)->setRowCount(rows);
2260 inGroup = false;
2261 }
2262 else /* if (blockType == swatchSig)*/ {
2263 KisSwatch swatch;
2264 swatch.setName(readUnicodeString(&buf).trimmed());
2265 QByteArray colorModel;
2266 QDomDocument doc;
2267 colorModel = buf.read(4);
2268 if (colorModel == "RGB ") {
2269 QDomElement elt = doc.createElement("sRGB");
2270
2271 elt.setAttribute("r", readFloat(&buf));
2272 elt.setAttribute("g", readFloat(&buf));
2273 elt.setAttribute("b", readFloat(&buf));
2274
2275 KoColor color = KoColor::fromXML(elt, "U8");
2276 swatch.setColor(color);
2277 } else if (colorModel == "CMYK") {
2278 QDomElement elt = doc.createElement("CMYK");
2279
2280 elt.setAttribute("c", readFloat(&buf));
2281 elt.setAttribute("m", readFloat(&buf));
2282 elt.setAttribute("y", readFloat(&buf));
2283 elt.setAttribute("k", readFloat(&buf));
2284 //try to select the default PS icc profile if possible.
2285 elt.setAttribute("space", "U.S. Web Coated (SWOP) v2");
2286
2287 KoColor color = KoColor::fromXML(elt, "U8");
2288 swatch.setColor(color);
2289 } else if (colorModel == "LAB ") {
2290 QDomElement elt = doc.createElement("Lab");
2291
2292 elt.setAttribute("L", readFloat(&buf)*100.0);
2293 elt.setAttribute("a", readFloat(&buf));
2294 elt.setAttribute("b", readFloat(&buf));
2295
2296 KoColor color = KoColor::fromXML(elt, "U16");
2297 swatch.setColor(color);
2298 } else if (colorModel == "GRAY") {
2299 QDomElement elt = doc.createElement("Gray");
2300
2301 elt.setAttribute("g", readFloat(&buf));
2302
2303 KoColor color = KoColor::fromXML(elt, "U8");
2304 swatch.setColor(color);
2305 }
2306 qint16 type = readShort(&buf);
2307 if (type == 1) { //0 is global, 2 is regular;
2308 swatch.setSpotColor(true);
2309 }
2310 if (inGroup) {
2311 colorSet->addSwatch(swatch, groupName);
2312 } else {
2313 colorSet->addSwatch(swatch);
2314 }
2315 }
2316 buf.seek(pos + qint64(blockSize));
2317 }
2318 return true;
2319}
float readFloat(QIODevice *io)
qint32 readInt(QIODevice *io)
KisSwatchGroupSP getGroup(const QString &name) const
getGroup
void addGroup(const QString &groupName, int columnCount=KisSwatchGroup::DEFAULT_COLUMN_COUNT, int rowCount=KisSwatchGroup::DEFAULT_ROW_COUNT)
addGroup Adds a new group.
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
Definition KoColor.cpp:350
QString trimmed(const QString &string)

References KoColorSet::colorCount(), KoColor::fromXML(), KisSwatch::setColor(), KisSwatch::setName(), KisSwatch::setSpotColor(), KoResource::signature(), and KoResource::version.

◆ loadColorProfile()

const KoColorProfile * KoColorSet::Private::loadColorProfile ( QScopedPointer< KoStore > & store,
const QString & path,
const QString & modelId,
const QString & colorDepthId )
private

Definition at line 1694 of file KoColorSet.cpp.

1698{
1699 if (!store->open(path)) {
1700 return nullptr;
1701 }
1702
1703 QByteArray bytes = store->read(store->size());
1704 store->close();
1705
1707 ->createColorProfile(modelId, colorDepthId, bytes);
1708 if (!profile || !profile->valid()) {
1709 return nullptr;
1710 }
1711
1713 return profile;
1714}
virtual bool valid() const =0
const KoColorProfile * createColorProfile(const QString &colorModelId, const QString &colorDepthId, const QByteArray &rawData)
void addProfile(KoColorProfile *profile)

References KoColorSpaceRegistry::addProfile(), KoColorSpaceRegistry::createColorProfile(), KoColorSpaceRegistry::instance(), and KoColorProfile::valid().

◆ loadCss()

bool KoColorSet::Private::loadCss ( )

Definition at line 1534 of file KoColorSet.cpp.

1535{
1536 QFileInfo info(colorSet->filename());
1537 colorSet->setName(info.completeBaseName());
1538
1539 QString text = readAllLinesSafe(&data).join("").replace("\t", "").replace(" ", "");
1540
1541 QRegularExpression re("/\\*.*?\\*/");
1542
1543 text.remove(re); // Remove comments
1544
1545 KisSwatch swatch;
1546
1547 // Regex to detect a color in the palette
1548 QRegularExpression palette("(.*?){(?:[^:;]+:[^;]+;)*?color:(.*?)(?:;.*?)*?}");
1549
1550 QRegularExpressionMatchIterator colors = palette.globalMatch(text);
1551
1552 if (!colors.hasNext()) {
1553 warnPigment << "No color found in CSS palette : " << colorSet->filename();
1554 return false;
1555 }
1556
1557 while (colors.hasNext()) {
1558 QRegularExpressionMatch match = colors.next();
1559 QString colorInfo = match.captured();
1560 QString colorName = match.captured(1);
1561 QString colorValue = match.captured(2);
1562
1563 if (!colorInfo.startsWith(".") || colorValue.isEmpty()) {
1564 warnPigment << "Illegal CSS palette syntax : " << colorInfo;
1565 return false;
1566 }
1567
1568 QColor qColor;
1569
1570 colorName.remove(".");
1571 swatch.setName(colorName);
1572
1573 if (colorValue.startsWith("rgb")) {
1574 QStringList color;
1575
1576 if (colorValue.startsWith("rgba")) {
1577 colorValue.remove("rgba(").remove(")");
1578 color = colorValue.split(",");
1579
1580 if (color.size() != 4) {
1581 warnPigment << "Invalid RGBA color definition : " << colorInfo;
1582 return false;
1583 }
1584
1585 int alpha = color[3].toFloat() * 255;
1586
1587 if (alpha < 0 || alpha > 255) {
1588 warnPigment << "Invalid alpha parameter : " << colorInfo;
1589 return false;
1590 }
1591 }
1592 else {
1593 colorValue.remove("rgb(").remove(")");
1594
1595 color = colorValue.split(",");
1596
1597 if (color.size() != 3) {
1598 warnPigment << "Invalid RGB color definition : " << colorInfo;
1599 return false;
1600 }
1601 }
1602
1603 int rgb[3];
1604
1605 for (int i = 0; i < 3; i++) {
1606 if (color[i].endsWith("%")) {
1607 color[i].replace("%", "");
1608 rgb[i] = color[i].toFloat() / 100 * 255 ;
1609 }
1610 else {
1611 rgb[i] = color[i].toInt();
1612 };
1613 }
1614
1615 qColor = QColor(rgb[0], rgb[1], rgb[2]);
1616 }
1617 else if (colorValue.startsWith("hsl")) {
1618 QStringList color;
1619
1620 if (colorValue.startsWith("hsla")) {
1621 colorValue.remove("hsla(").remove(")").replace("%", "");
1622 color = colorValue.split(",");
1623 if (color.size() != 4) {
1624 warnPigment << "Invalid HSLA color definition : " << colorInfo;
1625 return false;
1626 }
1627
1628 float alpha = color[3].toFloat();
1629
1630 if (alpha < 0.0 || alpha > 1.0) {
1631 warnPigment << "Invalid alpha parameter : " << colorInfo;
1632 return false;
1633 }
1634
1635 }
1636 else {
1637 colorValue.remove("hsl(").remove(")").replace("%", "");
1638 color = colorValue.split(",");
1639 if (color.size() != 3) {
1640 warnPigment << "Invalid HSL color definition : " << colorInfo;
1641 return false;
1642 }
1643 }
1644
1645 float hue = color[0].toFloat() / 359;
1646 float saturation = color[1].toFloat() / 100;
1647 float lightness = color[2].toFloat() / 100;
1648
1649 if (hue < 0.0 || hue > 1.0) {
1650 warnPigment << "Invalid hue parameter : " << colorInfo;
1651 return false;
1652 }
1653
1654 if (saturation < 0.0 || saturation > 1.0) {
1655 warnPigment << "Invalid saturation parameter : " << colorInfo;
1656 return false;
1657 }
1658
1659 if (lightness < 0.0 || lightness > 1.0) {
1660 warnPigment << "Invalid lightness parameter : " << colorInfo;
1661 return false;
1662 }
1663
1664 qColor = QColor::fromHslF(hue, saturation, lightness);
1665
1666 }
1667 else if (colorValue.startsWith("#")) {
1668 if (colorValue.size() == 9) {
1669 // Convert the CSS format #RRGGBBAA to #RRGGBB
1670 // Due to QColor's 8 digits format being #AARRGGBB and that we do not load the alpha channel
1671 colorValue.truncate(7);
1672 }
1673
1674 qColor = QColor(colorValue);
1675 }
1676 else {
1677 warnPigment << "Unknown color declaration : " << colorInfo;
1678 return false;
1679 }
1680
1681 if (!qColor.isValid()) {
1682 warnPigment << "Invalid color definition : " << colorInfo;
1683 return false;
1684 }
1685
1686 swatch.setColor(KoColor(qColor, KoColorSpaceRegistry::instance()->rgb8()));
1687
1688 global()->addSwatch(swatch);
1689 }
1690
1691 return true;
1692}
rgba palette[MAX_PALETTE]
Definition palette.c:35

References KoColorSpaceRegistry::instance(), palette, KisSwatch::setColor(), KisSwatch::setName(), and warnPigment.

◆ loadGpl()

bool KoColorSet::Private::loadGpl ( )

Definition at line 1380 of file KoColorSet.cpp.

1381{
1382 if (data.isEmpty() || data.isNull() || data.length() < 50) {
1383 warnPigment << "Illegal Gimp palette file: " << colorSet->filename();
1384 return false;
1385 }
1386
1387 quint32 index = 0;
1388
1389 QStringList lines = readAllLinesSafe(&data);
1390
1391 if (lines.size() < 3) {
1392 warnPigment << "Not enough lines in palette file: " << colorSet->filename();
1393 return false;
1394 }
1395
1396 QString columnsText;
1397 qint32 r, g, b;
1398 KisSwatch swatch;
1399
1400 // Read name
1401 if (!lines[0].startsWith("GIMP") || !lines[1].toLower().contains("name")) {
1402 warnPigment << "Illegal Gimp palette file: " << colorSet->filename();
1403 return false;
1404 }
1405
1406 // translated name will be in a tooltip, here don't translate
1407 colorSet->setName(lines[1].split(":")[1].trimmed());
1408
1409 index = 2;
1410
1411 // Read columns
1412 int columns = 0;
1413 if (lines[index].toLower().contains("columns")) {
1414 columnsText = lines[index].split(":")[1].trimmed();
1415 columns = columnsText.toInt();
1417 warnPigment << "Refusing to set unreasonable number of columns (" << columns << ") in GIMP Palette file " << colorSet->filename() << " - using maximum number of allowed columns instead";
1418 global()->setColumnCount(MAXIMUM_ALLOWED_COLUMNS);
1419 }
1420 else {
1421 global()->setColumnCount(columns);
1422 }
1423 index = 3;
1424 }
1425
1426
1427 for (qint32 i = index; i < lines.size(); i++) {
1428 if (lines[i].startsWith('#')) {
1429 comment += lines[i].mid(1).trimmed() + ' ';
1430 } else if (!lines[i].isEmpty()) {
1431 QStringList a = lines[i].replace('\t', ' ').split(' ', Qt::SkipEmptyParts);
1432
1433 if (a.count() < 3) {
1434 continue;
1435 }
1436
1437 r = qBound(0, a[0].toInt(), 255);
1438 g = qBound(0, a[1].toInt(), 255);
1439 b = qBound(0, a[2].toInt(), 255);
1440
1441 swatch.setColor(KoColor(QColor(r, g, b), KoColorSpaceRegistry::instance()->rgb8()));
1442
1443 for (int i = 0; i != 3; i++) {
1444 a.pop_front();
1445 }
1446 QString name = a.join(" ");
1447 swatch.setName(name.isEmpty() || name == "Untitled" ? i18n("Untitled") : name);
1448
1449 global()->addSwatch(swatch);
1450 }
1451 }
1452 return true;
1453}
const int MAXIMUM_ALLOWED_COLUMNS
QList< KoSubpath * > split(const KoPathShape &path)
int toInt(const QString &str, bool *ok=nullptr)

References KoColorSet::comment(), KoColorSpaceRegistry::instance(), MAXIMUM_ALLOWED_COLUMNS, KoResource::name, KisSwatch::setColor(), KisSwatch::setName(), and warnPigment.

◆ loadKpl()

bool KoColorSet::Private::loadKpl ( )

Definition at line 1792 of file KoColorSet.cpp.

1793{
1794 QBuffer buf(&data);
1795 buf.open(QBuffer::ReadOnly);
1796
1797 QScopedPointer<KoStore> store(
1799 "application/x-krita-palette",
1800 KoStore::Zip));
1801 if (!store || store->bad()) {
1802 return false;
1803 }
1804
1805 if (store->hasFile("profiles.xml") && !loadKplProfiles(store)) {
1806 return false;
1807 }
1808
1809 if (!loadKplColorset(store)) {
1810 return false;
1811 }
1812
1813 buf.close();
1814 return true;
1815}
bool loadKplColorset(QScopedPointer< KoStore > &store)
bool loadKplProfiles(QScopedPointer< KoStore > &store)
@ Read
Definition KoStore.h:29
@ Zip
Definition KoStore.h:30
static KoStore * createStore(const QString &fileName, Mode mode, const QByteArray &appIdentification=QByteArray(), Backend backend=Auto, bool writeMimetype=true)
Definition KoStore.cpp:39

References KoStore::createStore(), KoStore::Read, and KoStore::Zip.

◆ loadKplColorset()

bool KoColorSet::Private::loadKplColorset ( QScopedPointer< KoStore > & store)
private

Definition at line 1750 of file KoColorSet.cpp.

1751{
1752 if (!store->open("colorset.xml")) {
1753 return false;
1754 }
1755
1756 QByteArray bytes = store->read(store->size());
1757 store->close();
1758
1759 QDomDocument doc;
1760 if (!doc.setContent(bytes)) {
1761 return false;
1762 }
1763
1764 QDomElement root = doc.documentElement();
1765 colorSet->setName(root.attribute(KPL_PALETTE_NAME_ATTR));
1766 QString version = root.attribute(KPL_VERSION_ATTR);
1767 comment = root.attribute(KPL_PALETTE_COMMENT_ATTR);
1768
1769 int desiredColumnCount = root.attribute(KPL_PALETTE_COLUMN_COUNT_ATTR).toInt();
1770 if (desiredColumnCount > MAXIMUM_ALLOWED_COLUMNS) {
1771 warnPigment << "Refusing to set unreasonable number of columns (" << desiredColumnCount
1772 << ") in KPL palette file " << colorSet->filename()
1773 << " - setting maximum allowed column count instead.";
1775 } else {
1776 colorSet->setColumnCount(desiredColumnCount);
1777 }
1778
1780
1781 for (QDomElement g = root.firstChildElement(KPL_GROUP_TAG);
1782 !g.isNull();
1783 g = g.nextSiblingElement(KPL_GROUP_TAG)) {
1784 QString groupName = g.attribute(KPL_GROUP_NAME_ATTR);
1785 colorSet->addGroup(groupName);
1786 loadKplGroup(doc, g, colorSet->getGroup(groupName), version);
1787 }
1788
1789 return true;
1790}
void loadKplGroup(const QDomDocument &doc, const QDomElement &parentElement, KisSwatchGroupSP group, QString version)
static const QString KPL_PALETTE_COMMENT_ATTR
Definition KoColorSet.h:38
static const QString KPL_PALETTE_NAME_ATTR
Definition KoColorSet.h:37
static const QString KPL_PALETTE_COLUMN_COUNT_ATTR
Definition KoColorSet.h:36
static const QString KPL_GROUP_TAG
Definition KoColorSet.h:53
static const QString KPL_GROUP_NAME_ATTR
Definition KoColorSet.h:43
static const QString KPL_VERSION_ATTR
Definition KoColorSet.h:34

References KoColorSet::comment(), KoColorSet::KPL_GROUP_NAME_ATTR, KoColorSet::KPL_GROUP_TAG, KoColorSet::KPL_PALETTE_COLUMN_COUNT_ATTR, KoColorSet::KPL_PALETTE_COMMENT_ATTR, KoColorSet::KPL_PALETTE_NAME_ATTR, KoColorSet::KPL_VERSION_ATTR, MAXIMUM_ALLOWED_COLUMNS, KoResource::version, and warnPigment.

◆ loadKplGroup()

void KoColorSet::Private::loadKplGroup ( const QDomDocument & doc,
const QDomElement & parentElement,
KisSwatchGroupSP group,
QString version )
private

Definition at line 2554 of file KoColorSet.cpp.

2555{
2556 Q_UNUSED(doc);
2557 if (!parentEle.attribute(KPL_GROUP_ROW_COUNT_ATTR).isNull()) {
2558 group->setRowCount(parentEle.attribute(KPL_GROUP_ROW_COUNT_ATTR).toInt());
2559 }
2560 group->setColumnCount(colorSet->columnCount());
2561
2562 for (QDomElement swatchEle = parentEle.firstChildElement(KPL_SWATCH_TAG);
2563 !swatchEle.isNull();
2564 swatchEle = swatchEle.nextSiblingElement(KPL_SWATCH_TAG)) {
2565 QString colorDepthId = swatchEle.attribute(KPL_SWATCH_BITDEPTH_ATTR, Integer8BitsColorDepthID.id());
2566 KisSwatch swatch;
2567
2568 if (version == "1.0" && swatchEle.firstChildElement().tagName() == "Lab") {
2569 // previous version of krita had the values wrong, and scaled everything between 0 to 1,
2570 // but lab requires L = 0-100 and AB = -128-127.
2571 // TODO: write unittest for this.
2572 QDomElement el = swatchEle.firstChildElement();
2573 double L = KisDomUtils::toDouble(el.attribute("L"));
2574 el.setAttribute("L", L*100.0);
2575 double ab = KisDomUtils::toDouble(el.attribute("a"));
2576 if (ab <= .5) {
2577 ab = (0.5 - ab) * 2 * -128.0;
2578 } else {
2579 ab = (ab - 0.5) * 2 * 127.0;
2580 }
2581 el.setAttribute("a", ab);
2582
2583 ab = KisDomUtils::toDouble(el.attribute("b"));
2584 if (ab <= .5) {
2585 ab = (0.5 - ab) * 2 * -128.0;
2586 } else {
2587 ab = (ab - 0.5) * 2 * 127.0;
2588 }
2589 el.setAttribute("b", ab);
2590 swatch.setColor(KoColor::fromXML(el, colorDepthId));
2591 } else {
2592 swatch.setColor(KoColor::fromXML(swatchEle.firstChildElement(), colorDepthId));
2593 }
2594 swatch.setName(swatchEle.attribute(KPL_SWATCH_NAME_ATTR));
2595 swatch.setId(swatchEle.attribute(KPL_SWATCH_ID_ATTR));
2596 swatch.setSpotColor(swatchEle.attribute(KPL_SWATCH_SPOT_ATTR, "false") == "true" ? true : false);
2597 QDomElement positionEle = swatchEle.firstChildElement(KPL_SWATCH_POS_TAG);
2598 if (!positionEle.isNull()) {
2599 int rowNumber = positionEle.attribute(KPL_SWATCH_ROW_ATTR).toInt();
2600 int columnNumber = positionEle.attribute(KPL_SWATCH_COL_ATTR).toInt();
2601 if (columnNumber < 0 ||
2602 columnNumber >= colorSet->columnCount() ||
2603 rowNumber < 0
2604 ) {
2605 warnPigment << "Swatch" << swatch.name()
2606 << "of palette" << colorSet->name()
2607 << "has invalid position.";
2608 continue;
2609 }
2610 group->setSwatch(swatch, columnNumber, rowNumber);
2611 } else {
2612 group->addSwatch(swatch);
2613 }
2614 }
2615
2616 if (parentEle.attribute(KPL_GROUP_ROW_COUNT_ATTR).isNull()
2617 && group->colorCount() > 0
2618 && group->columnCount() > 0
2619 && (group->colorCount() / (group->columnCount()) + 1) < 20) {
2620 group->setRowCount((group->colorCount() / group->columnCount()) + 1);
2621 }
2622
2623}
QString name() const
Definition KisSwatch.h:24
static const QString KPL_SWATCH_TAG
Definition KoColorSet.h:52
static const QString KPL_SWATCH_ROW_ATTR
Definition KoColorSet.h:44
static const QString KPL_SWATCH_COL_ATTR
Definition KoColorSet.h:45
static const QString KPL_SWATCH_POS_TAG
Definition KoColorSet.h:51
static const QString KPL_GROUP_ROW_COUNT_ATTR
Definition KoColorSet.h:35
static const QString KPL_SWATCH_BITDEPTH_ATTR
Definition KoColorSet.h:49
static const QString KPL_SWATCH_SPOT_ATTR
Definition KoColorSet.h:47
static const QString KPL_SWATCH_NAME_ATTR
Definition KoColorSet.h:46
static const QString KPL_SWATCH_ID_ATTR
Definition KoColorSet.h:48
double toDouble(const QString &str, bool *ok=nullptr)

References KoColor::fromXML(), KoID::id(), Integer8BitsColorDepthID, KoColorSet::KPL_GROUP_ROW_COUNT_ATTR, KoColorSet::KPL_SWATCH_BITDEPTH_ATTR, KoColorSet::KPL_SWATCH_COL_ATTR, KoColorSet::KPL_SWATCH_ID_ATTR, KoColorSet::KPL_SWATCH_NAME_ATTR, KoColorSet::KPL_SWATCH_POS_TAG, KoColorSet::KPL_SWATCH_ROW_ATTR, KoColorSet::KPL_SWATCH_SPOT_ATTR, KoColorSet::KPL_SWATCH_TAG, KisSwatch::name(), KisSwatch::setColor(), KisSwatch::setId(), KisSwatch::setName(), KisSwatch::setSpotColor(), KisDomUtils::toDouble(), KoResource::version, and warnPigment.

◆ loadKplProfiles()

bool KoColorSet::Private::loadKplProfiles ( QScopedPointer< KoStore > & store)
private

Definition at line 1716 of file KoColorSet.cpp.

1717{
1718 if (!store->open("profiles.xml")) {
1719 return false;
1720 }
1721
1722 QByteArray bytes = store->read(store->size());
1723 store->close();
1724
1725 QDomDocument doc;
1726 if(!doc.setContent(bytes)) {
1727 return false;
1728 }
1729
1730 QDomElement root = doc.documentElement();
1731 for (QDomElement c = root.firstChildElement(KPL_PALETTE_PROFILE_TAG);
1732 !c.isNull();
1733 c = c.nextSiblingElement(KPL_PALETTE_PROFILE_TAG)) {
1734 QString name = c.attribute(KPL_PALETTE_NAME_ATTR);
1735 QString filename = c.attribute(KPL_PALETTE_FILENAME_ATTR);
1736 QString colorModelId = c.attribute(KPL_COLOR_MODEL_ID_ATTR);
1737 QString colorDepthId = c.attribute(KPL_COLOR_DEPTH_ID_ATTR);
1738
1740 continue;
1741 }
1742
1743 loadColorProfile(store, filename, colorModelId, colorDepthId);
1744 // TODO: What should happen if this fails?
1745 }
1746
1747 return true;
1748}
const KoColorProfile * loadColorProfile(QScopedPointer< KoStore > &store, const QString &path, const QString &modelId, const QString &colorDepthId)
static const QString KPL_COLOR_DEPTH_ID_ATTR
Definition KoColorSet.h:42
static const QString KPL_COLOR_MODEL_ID_ATTR
Definition KoColorSet.h:41
static const QString KPL_PALETTE_PROFILE_TAG
Definition KoColorSet.h:50
static const QString KPL_PALETTE_FILENAME_ATTR
Definition KoColorSet.h:39
const KoColorProfile * profileByName(const QString &name) const

References KoResource::filename, KoColorSpaceRegistry::instance(), KoColorSet::KPL_COLOR_DEPTH_ID_ATTR, KoColorSet::KPL_COLOR_MODEL_ID_ATTR, KoColorSet::KPL_PALETTE_FILENAME_ATTR, KoColorSet::KPL_PALETTE_NAME_ATTR, KoColorSet::KPL_PALETTE_PROFILE_TAG, KoResource::name, and KoColorSpaceRegistry::profileByName().

◆ loadPsp()

bool KoColorSet::Private::loadPsp ( )

Definition at line 1495 of file KoColorSet.cpp.

1496{
1497 QFileInfo info(colorSet->filename());
1498 colorSet->setName(info.completeBaseName());
1499 KisSwatch swatch;
1500 qint32 r, g, b;
1501
1502 QStringList l = readAllLinesSafe(&data);
1503 if (l.size() < 4) return false;
1504 if (l[0] != "JASC-PAL") return false;
1505 if (l[1] != "0100") return false;
1506
1507 int entries = l[2].toInt();
1508
1510
1511 for (int i = 0; i < entries; ++i) {
1512
1513 QStringList a = l[i + 3].replace('\t', ' ').split(' ', Qt::SkipEmptyParts);
1514
1515 if (a.count() != 3) {
1516 continue;
1517 }
1518
1519 r = qBound(0, a[0].toInt(), 255);
1520 g = qBound(0, a[1].toInt(), 255);
1521 b = qBound(0, a[2].toInt(), 255);
1522
1523 swatch.setColor(KoColor(QColor(r, g, b),
1525
1526 QString name = a.join(" ");
1527 swatch.setName(name.isEmpty() ? i18n("Untitled") : name);
1528
1529 global->addSwatch(swatch);
1530 }
1531 return true;
1532}

References KoColorSpaceRegistry::instance(), KoResource::name, KisSwatch::setColor(), and KisSwatch::setName().

◆ loadRiff()

bool KoColorSet::Private::loadRiff ( )

Definition at line 1471 of file KoColorSet.cpp.

1472{
1473 // https://worms2d.info/Palette_file
1474 QFileInfo info(colorSet->filename());
1475 colorSet->setName(info.completeBaseName());
1476 KisSwatch swatch;
1477
1478 RiffHeader header;
1479 memcpy(&header, data.constData(), sizeof(RiffHeader));
1480 header.colorcount = qFromBigEndian(header.colorcount);
1481
1482 for (int i = sizeof(RiffHeader);
1483 (i < (int)(sizeof(RiffHeader) + (header.colorcount * 4)) && i < data.size());
1484 i += 4) {
1485 quint8 r = data[i];
1486 quint8 g = data[i+1];
1487 quint8 b = data[i+2];
1488 swatch.setColor(KoColor(QColor(r, g, b), KoColorSpaceRegistry::instance()->rgb8()));
1489 colorSet->getGlobalGroup()->addSwatch(swatch);
1490 }
1491 return true;
1492}
quint16 colorcount

References RiffHeader::colorcount, KoColorSpaceRegistry::instance(), KoColorSpaceRegistry::rgb8(), and KisSwatch::setColor().

◆ loadSbz()

bool KoColorSet::Private::loadSbz ( )

Definition at line 2195 of file KoColorSet.cpp.

2195 {
2196 QBuffer buf(&data);
2197 buf.open(QBuffer::ReadOnly);
2198
2199 // &buf is a subclass of QIODevice
2200 QScopedPointer<KoStore> store(
2202 "application/x-swatchbook",
2203 KoStore::Zip));
2204 if (!store || store->bad()) {
2205 return false;
2206 }
2207
2208 if (store->hasFile("swatchbook.xml") && !loadSbzSwatchbook(store)) {
2209 return false;
2210 }
2211
2212 buf.close();
2213 return true;
2214}
bool loadSbzSwatchbook(QScopedPointer< KoStore > &store)

References KoStore::createStore(), KoStore::Read, and KoStore::Zip.

◆ loadSbzSwatchbook()

bool KoColorSet::Private::loadSbzSwatchbook ( QScopedPointer< KoStore > & store)
private

Definition at line 1903 of file KoColorSet.cpp.

1904{
1905 if (!store->open("swatchbook.xml")) {
1906 return false;
1907 }
1908
1909 QByteArray bytes = store->read(store->size());
1910 store->close();
1911
1912 dbgPigment << "XML palette: " << colorSet->filename() << ", SwatchBooker format";
1913
1914 QDomDocument doc;
1915#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
1916 int errorLine, errorColumn;
1917 QString errorMessage;
1918 if (!doc.setContent(bytes, &errorMessage, &errorLine, &errorColumn)) {
1919 warnPigment << "Illegal XML palette:" << colorSet->filename();
1920 warnPigment << "Error (line" << errorLine
1921 << ", column" << errorColumn
1922 << "):" << errorMessage;
1923#else
1924 QDomDocument::ParseResult result = doc.setContent(bytes);
1925 if (!result) {
1926 warnPigment << "Illegal XML palette:" << colorSet->filename();
1927 warnPigment << "Error (line" << result.errorLine
1928 << ", column" << result.errorColumn
1929 << "):" << result.errorMessage;
1930#endif
1931 return false;
1932 }
1933
1934 QDomElement root = doc.documentElement(); // SwatchBook
1935
1936 // Start reading properties...
1937 QDomElement metadata = root.firstChildElement("metadata");
1938 if (metadata.isNull()) {
1939 warnPigment << "Palette metadata not found";
1940 return false;
1941 }
1942
1943 QDomElement title = metadata.firstChildElement("dc:title");
1944 QString colorName = title.text();
1945 colorName = colorName.isEmpty() ? i18n("Untitled") : colorName;
1946 colorSet->setName(colorName);
1947 dbgPigment << "Processed name of palette:" << colorSet->name();
1948 // End reading properties
1949
1950 // Also read the swatch book...
1951 QDomElement book = root.firstChildElement("book");
1952 if (book.isNull()) {
1953 warnPigment << "Palette book (swatch composition) not found (line" << root.lineNumber()
1954 << ", column" << root.columnNumber()
1955 << ")";
1956 return false;
1957 }
1958
1959 // Which has lots of "swatch"es (todo: support groups)
1960 QDomElement swatch = book.firstChildElement();
1961 if (swatch.isNull()) {
1962 warnPigment << "Swatches/groups definition not found (line" << book.lineNumber()
1963 << ", column" << book.columnNumber()
1964 << ")";
1965 return false;
1966 }
1967
1968 // Now read colors...
1969 QDomElement materials = root.firstChildElement("materials");
1970 if (materials.isNull()) {
1971 warnPigment << "Materials (color definitions) not found";
1972 return false;
1973 }
1974
1975 // This one has lots of "color" elements
1976 if (materials.firstChildElement("color").isNull()) {
1977 warnPigment << "Color definitions not found (line" << materials.lineNumber()
1978 << ", column" << materials.columnNumber()
1979 << ")";
1980 return false;
1981 }
1982
1983 // We'll store colors here, and as we process swatches
1984 // we'll add them to the palette
1985 QHash<QString, KisSwatch> materialsBook;
1986 QHash<QString, const KoColorSpace*> fileColorSpaces;
1987
1988 // Color processing
1989 store->enterDirectory("profiles"); // Color profiles (icc files) live here
1990 for (QDomElement colorElement = materials.firstChildElement("color");
1991 !colorElement.isNull();
1992 colorElement = colorElement.nextSiblingElement("color")) {
1993 KisSwatch currentEntry;
1994 // Set if color is spot
1995 currentEntry.setSpotColor(colorElement.attribute("usage") == "spot");
1996
1997 // <metadata> inside contains id and name
1998 // one or more <values> define the color
1999 QDomElement currentColorMetadata = colorElement.firstChildElement("metadata");
2000 // Get color name
2001 QDomElement colorTitle = currentColorMetadata.firstChildElement("dc:title");
2002 QDomElement colorId = currentColorMetadata.firstChildElement("dc:identifier");
2003 // Is there an id? (we need that at the very least for identifying a color)
2004 if (colorId.text().isEmpty()) {
2005 warnPigment << "Unidentified color (line" << colorId.lineNumber()
2006 << ", column" << colorId.columnNumber()
2007 << ")";
2008 return false;
2009 }
2010
2011 if (materialsBook.contains(colorId.text())) {
2012 warnPigment << "Duplicated color definition (line" << colorId.lineNumber()
2013 << ", column" << colorId.columnNumber()
2014 << ")";
2015 return false;
2016 }
2017
2018 // Get a valid color name
2019 currentEntry.setId(colorId.text());
2020 currentEntry.setName(colorTitle.text().isEmpty() ? colorId.text() : colorTitle.text());
2021
2022 // Get a valid color definition
2023 if (colorElement.firstChildElement("values").isNull()) {
2024 warnPigment << "Color definitions not found (line" << colorElement.lineNumber()
2025 << ", column" << colorElement.columnNumber()
2026 << ")";
2027 return false;
2028 }
2029
2030 bool status;
2031 bool firstDefinition = false;
2033 const QString colorDepthId = Float32BitsColorDepthID.id();
2034 // Priority: Lab, otherwise the first definition found
2035 for (QDomElement colorValueE = colorElement.firstChildElement("values");
2036 !colorValueE.isNull();
2037 colorValueE = colorValueE.nextSiblingElement("values")) {
2038 QString model = colorValueE.attribute("model");
2039
2040 QString modelId;
2041 const KoColorProfile *profile = nullptr;
2042 if (model == "Lab") {
2043 modelId = LABAColorModelID.id();
2044 } else if (model == "sRGB") {
2045 modelId = RGBAColorModelID.id();
2046 profile = colorSpaceRegistry->rgb8()->profile();
2047 } else if (model == "XYZ") {
2048 modelId = XYZAColorModelID.id();
2049 } else if (model == "CMYK") {
2050 modelId = CMYKAColorModelID.id();
2051 } else if (model == "GRAY") {
2052 modelId = GrayAColorModelID.id();
2053 } else if (model == "RGB") {
2054 modelId = RGBAColorModelID.id();
2055 } else {
2056 warnPigment << "Color space not implemented:" << model
2057 << "(line" << colorValueE.lineNumber()
2058 << ", column "<< colorValueE.columnNumber()
2059 << ")";
2060 continue;
2061 }
2062
2063 const KoColorSpace *colorSpace = colorSpaceRegistry->colorSpace(modelId, colorDepthId, profile);
2064
2065 // The 'space' attribute is the name of the icc file
2066 // sitting in the 'profiles' directory in the zip.
2067 QString space = colorValueE.attribute("space");
2068 if (!space.isEmpty()) {
2069 if (fileColorSpaces.contains(space)) {
2070 colorSpace = fileColorSpaces.value(space);
2071 } else {
2072 // Try loading the profile and add it to the registry
2073 profile = loadColorProfile(store, space, modelId, colorDepthId);
2074 if (profile) {
2075 colorSpace = colorSpaceRegistry->colorSpace(modelId, colorDepthId, profile);
2076 fileColorSpaces.insert(space, colorSpace);
2077 }
2078 }
2079 }
2080
2081 KoColor c(colorSpace);
2082
2083 // sRGB,RGB,HSV,HSL,CMY,CMYK,nCLR: 0 -> 1
2084 // YIQ: Y 0 -> 1 : IQ -0.5 -> 0.5
2085 // Lab: L 0 -> 100 : ab -128 -> 127
2086 // XYZ: 0 -> ~100
2087 QVector<float> channels;
2088 for (const QString &str : colorValueE.text().split(" ")) {
2089 float channelValue = str.toFloat(&status);
2090 if (!status) {
2091 warnPigment << "Invalid float definition (line" << colorValueE.lineNumber()
2092 << ", column" << colorValueE.columnNumber()
2093 << ")";
2094
2095 channelValue = 0;
2096 }
2097
2098 channels.append(channelValue);
2099 }
2100 channels.append(OPACITY_OPAQUE_F); // Alpha channel
2101 colorSpace->fromNormalisedChannelsValue(c.data(), channels);
2102
2103 currentEntry.setColor(c);
2104 firstDefinition = true;
2105
2106 if (model == "Lab") {
2107 break; // Immediately add this one
2108 }
2109 }
2110
2111 if (firstDefinition) {
2112 materialsBook.insert(currentEntry.id(), currentEntry);
2113 } else {
2114 warnPigment << "No supported color spaces for the current color (line" << colorElement.lineNumber()
2115 << ", column "<< colorElement.columnNumber()
2116 << ")";
2117 return false;
2118 }
2119 }
2120
2121 store->leaveDirectory(); // Return to root
2122 // End colors
2123 // Now decide which ones will go into the palette
2124
2126 for(; !swatch.isNull(); swatch = swatch.nextSiblingElement()) {
2127 QString type = swatch.tagName();
2128 if (type.isEmpty() || type.isNull()) {
2129 warnPigment << "Invalid swatch/group definition (no id) (line" << swatch.lineNumber()
2130 << ", column" << swatch.columnNumber()
2131 << ")";
2132 return false;
2133 } else if (type == "swatch") {
2134 QString id = swatch.attribute("material");
2135 if (id.isEmpty() || id.isNull()) {
2136 warnPigment << "Invalid swatch definition (no material id) (line" << swatch.lineNumber()
2137 << ", column" << swatch.columnNumber()
2138 << ")";
2139 return false;
2140 }
2141
2142 if (materialsBook.contains(id)) {
2143 global->addSwatch(materialsBook.value(id));
2144 } else {
2145 warnPigment << "Invalid swatch definition (material not found) (line" << swatch.lineNumber()
2146 << ", column" << swatch.columnNumber()
2147 << ")";
2148 return false;
2149 }
2150 } else if (type == "group") {
2151 QDomElement groupMetadata = swatch.firstChildElement("metadata");
2152 if (groupMetadata.isNull()) {
2153 warnPigment << "Invalid group definition (missing metadata) (line" << groupMetadata.lineNumber()
2154 << ", column" << groupMetadata.columnNumber()
2155 << ")";
2156 return false;
2157 }
2158 QDomElement groupTitle = metadata.firstChildElement("dc:title");
2159 if (groupTitle.isNull()) {
2160 warnPigment << "Invalid group definition (missing title) (line" << groupTitle.lineNumber()
2161 << ", column" << groupTitle.columnNumber()
2162 << ")";
2163 return false;
2164 }
2165 QString currentGroupName = groupTitle.text();
2166 colorSet->addGroup(currentGroupName);
2167
2168 for (QDomElement groupSwatch = swatch.firstChildElement("swatch");
2169 !groupSwatch.isNull();
2170 groupSwatch = groupSwatch.nextSiblingElement("swatch")) {
2171 QString id = groupSwatch.attribute("material");
2172 if (id.isEmpty() || id.isNull()) {
2173 warnPigment << "Invalid swatch definition (no material id) (line" << groupSwatch.lineNumber()
2174 << ", column" << groupSwatch.columnNumber()
2175 << ")";
2176 return false;
2177 }
2178
2179 if (materialsBook.contains(id)) {
2180 colorSet->getGroup(currentGroupName)->addSwatch(materialsBook.value(id));
2181 } else {
2182 warnPigment << "Invalid swatch definition (material not found) (line" << groupSwatch.lineNumber()
2183 << ", column" << groupSwatch.columnNumber()
2184 << ")";
2185 return false;
2186 }
2187 }
2188 }
2189 }
2190 // End palette
2191
2192 return true;
2193}
#define dbgPigment
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID XYZAColorModelID("XYZA", ki18n("XYZ/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
const qreal OPACITY_OPAQUE_F
QString id() const
Definition KisSwatch.h:27
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0

References CMYKAColorModelID, KoColorSpaceRegistry::colorSpace(), KoColor::data(), dbgPigment, Float32BitsColorDepthID, KoColorSpace::fromNormalisedChannelsValue(), GrayAColorModelID, KoID::id(), KisSwatch::id(), KoColorSpaceRegistry::instance(), LABAColorModelID, KoResource::metadata, OPACITY_OPAQUE_F, KoColorSpace::profile(), KoColorSpaceRegistry::rgb8(), RGBAColorModelID, KisSwatch::setColor(), KisSwatch::setId(), KisSwatch::setName(), KisSwatch::setSpotColor(), warnPigment, and XYZAColorModelID.

◆ loadScribusXmlPalette()

bool KoColorSet::Private::loadScribusXmlPalette ( KoColorSet * set,
QXmlStreamReader * xml )
private

Definition at line 1187 of file KoColorSet.cpp.

1188{
1189
1190 //1. Get name
1191 QXmlStreamAttributes paletteProperties = xml->attributes();
1192 auto paletteName = paletteProperties.value("Name");
1193 dbgPigment << "Processed name of palette:" << paletteName;
1194 set->setName(paletteName.toString());
1195
1196 //2. Inside the SCRIBUSCOLORS, there are lots of colors. Retrieve them
1197
1198 while(xml->readNextStartElement()) {
1199 auto currentElement = xml->name();
1200 if (currentElement.compare(QString("COLOR"), Qt::CaseInsensitive) == 0) {
1201 scribusParseColor(set, xml);
1202 }
1203 else {
1204 xml->skipCurrentElement();
1205 }
1206 }
1207
1208 if(xml->hasError()) {
1209 return false;
1210 }
1211
1212 return true;
1213}
void scribusParseColor(KoColorSet *set, QXmlStreamReader *xml)

References dbgPigment, and KoResource::setName().

◆ loadXml()

bool KoColorSet::Private::loadXml ( )

Definition at line 2419 of file KoColorSet.cpp.

2419 {
2420 bool res = false;
2421
2422 QXmlStreamReader *xml = new QXmlStreamReader(data);
2423
2424 if (xml->readNextStartElement()) {
2425 auto paletteId = xml->name();
2426 if (paletteId.compare(QString("SCRIBUSCOLORS"), Qt::CaseInsensitive) == 0) { // Scribus
2427 dbgPigment << "XML palette: " << colorSet->filename() << ", Scribus format";
2428 res = loadScribusXmlPalette(colorSet, xml);
2429 }
2430 else {
2431 // Unknown XML format
2432 xml->raiseError("Unknown XML palette format. Expected SCRIBUSCOLORS, found " + paletteId);
2433 }
2434 }
2435
2436 // If there is any error (it should be returned through the stream)
2437 if (xml->hasError() || !res) {
2438 warnPigment << "Illegal XML palette:" << colorSet->filename();
2439 warnPigment << "Error (line"<< xml->lineNumber() << ", column" << xml->columnNumber() << "):" << xml->errorString();
2440 return false;
2441 }
2442 else {
2443 dbgPigment << "XML palette parsed successfully:" << colorSet->filename();
2444 return true;
2445 }
2446}
bool loadScribusXmlPalette(KoColorSet *set, QXmlStreamReader *xml)

References dbgPigment, and warnPigment.

◆ readByte()

quint8 KoColorSet::Private::readByte ( QIODevice * io)
private

Definition at line 1215 of file KoColorSet.cpp.

1216{
1217 quint8 val;
1218 quint64 read = io->read((char*)&val, 1);
1219 if (read != 1) return false;
1220 return val;
1221}

◆ readFloat()

float KoColorSet::Private::readFloat ( QIODevice * io)
private

Definition at line 1238 of file KoColorSet.cpp.

1239{
1240 float val;
1241 quint64 read = io->read((char*)&val, 4);
1242 if (read != 4) return false;
1243 return qFromBigEndian(val);
1244}

◆ readInt()

qint32 KoColorSet::Private::readInt ( QIODevice * io)
private

Definition at line 1230 of file KoColorSet.cpp.

1231{
1232 qint32 val;
1233 quint64 read = io->read((char*)&val, 4);
1234 if (read != 4) return false;
1235 return qFromBigEndian(val);
1236}

◆ readShort()

quint16 KoColorSet::Private::readShort ( QIODevice * io)
private

Definition at line 1223 of file KoColorSet.cpp.

1223 {
1224 quint16 val;
1225 quint64 read = io->read((char*)&val, 2);
1226 if (read != 2) return false;
1227 return qFromBigEndian(val);
1228}

◆ readUnicodeString()

QString KoColorSet::Private::readUnicodeString ( QIODevice * io,
bool sizeIsInt = false )
private

Definition at line 1246 of file KoColorSet.cpp.

1247{
1248 QString unicode;
1249 qint32 size = 0;
1250 if (sizeIsInt) {
1251 size = readInt(io);
1252 } else {
1253 size = readShort(io)-1;
1254 }
1255 if (size>0) {
1256 QByteArray ba = io->read(size*2);
1257 if (ba.size() == int(size)*2) {
1258 QTextCodec *Utf16Codec = QTextCodec::codecForName("UTF-16BE");
1259 unicode = Utf16Codec->toUnicode(ba);
1260 } else {
1261 warnPigment << "Unicode name block is the wrong size" << colorSet->filename();
1262 }
1263 }
1264 if (!sizeIsInt) {
1265 readShort(io); // when the size is quint16, the string is 00 terminated;
1266 }
1267 return unicode.trimmed();
1268}
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References warnPigment.

◆ saveGpl()

bool KoColorSet::Private::saveGpl ( QIODevice * dev) const

Definition at line 1352 of file KoColorSet.cpp.

1353{
1354 Q_ASSERT(dev->isOpen());
1355 Q_ASSERT(dev->isWritable());
1356
1357 QTextStream stream(dev);
1359 stream << "GIMP Palette\nName: " << colorSet->name() << "\nColumns: " << colorSet->columnCount() << "\n#\n";
1360
1362 for (int y = 0; y < global->rowCount(); y++) {
1363 for (int x = 0; x < colorSet->columnCount(); x++) {
1364 if (!global->checkSwatchExists(x, y)) {
1365 continue;
1366 }
1367 const KisSwatch& entry = global->getSwatch(x, y);
1368 QColor c = entry.color().toQColor();
1369 stream << c.red() << " " << c.green() << " " << c.blue() << "\t";
1370 if (entry.name().isEmpty())
1371 stream << "Untitled\n";
1372 else
1373 stream << entry.name() << "\n";
1374 }
1375 }
1376
1377 return true;
1378}
KoColor color() const
Definition KisSwatch.h:30
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
void setUtf8OnStream(QTextStream &stream)

References KisSwatch::color(), KisSwatch::name(), KisPortingUtils::setUtf8OnStream(), and KoColor::toQColor().

◆ saveKpl()

bool KoColorSet::Private::saveKpl ( QIODevice * dev) const

Definition at line 2448 of file KoColorSet.cpp.

2449{
2450 QScopedPointer<KoStore> store(KoStore::createStore(dev, KoStore::Write, "application/x-krita-palette", KoStore::Zip));
2451 if (!store || store->bad()) {
2452 qWarning() << "saveKpl could not create store";
2453 return false;
2454 }
2455
2456 QSet<const KoColorSpace *> colorSpaces;
2457
2458 {
2459 QDomDocument doc;
2460 QDomElement root = doc.createElement(KPL_PALETTE_TAG);
2461 root.setAttribute(KPL_VERSION_ATTR, "2.0");
2462 root.setAttribute(KPL_PALETTE_NAME_ATTR, colorSet->name());
2463 root.setAttribute(KPL_PALETTE_COMMENT_ATTR, comment);
2464 root.setAttribute(KPL_PALETTE_COLUMN_COUNT_ATTR, colorSet->columnCount());
2465 root.setAttribute(KPL_GROUP_ROW_COUNT_ATTR, colorSet->getGlobalGroup()->rowCount());
2466
2468
2469 for (const KisSwatchGroupSP &group : swatchGroups) {
2470 if (group->name() == KoColorSet::GLOBAL_GROUP_NAME) { continue; }
2471 QDomElement gl = doc.createElement(KPL_GROUP_TAG);
2472 gl.setAttribute(KPL_GROUP_NAME_ATTR, group->name());
2473 root.appendChild(gl);
2474 saveKplGroup(doc, gl, group, colorSpaces);
2475 }
2476
2477 doc.appendChild(root);
2478 if (!store->open("colorset.xml")) { return false; }
2479 QByteArray ba = doc.toByteArray();
2480 if (store->write(ba) != ba.size()) { return false; }
2481 if (!store->close()) { return false; }
2482 }
2483
2484 QDomDocument doc;
2485 QDomElement profileElement = doc.createElement("Profiles");
2486
2487 for (const KoColorSpace *colorSpace : colorSpaces) {
2488 QString fn = QFileInfo(colorSpace->profile()->fileName()).fileName();
2489 if (!store->open(fn)) { qWarning() << "Could not open the store for profiles directory"; return false; }
2490 QByteArray profileRawData = colorSpace->profile()->rawData();
2491 if (!store->write(profileRawData)) { qWarning() << "Could not write the profiles data into the store"; return false; }
2492 if (!store->close()) { qWarning() << "Could not close the store for profiles directory"; return false; }
2493 QDomElement el = doc.createElement(KPL_PALETTE_PROFILE_TAG);
2494 el.setAttribute(KPL_PALETTE_FILENAME_ATTR, fn);
2495 el.setAttribute(KPL_PALETTE_NAME_ATTR, colorSpace->profile()->name());
2496 el.setAttribute(KPL_COLOR_MODEL_ID_ATTR, colorSpace->colorModelId().id());
2497 el.setAttribute(KPL_COLOR_DEPTH_ID_ATTR, colorSpace->colorDepthId().id());
2498 profileElement.appendChild(el);
2499
2500 }
2501 doc.appendChild(profileElement);
2502
2503 if (!store->open("profiles.xml")) { qWarning() << "Could not open profiles.xml"; return false; }
2504 QByteArray ba = doc.toByteArray();
2505
2506 int bytesWritten = store->write(ba);
2507 if (bytesWritten != ba.size()) { qWarning() << "Bytes written is wrong" << ba.size(); return false; }
2508
2509 if (!store->close()) { qWarning() << "Could not close the store"; return false; }
2510
2511 bool r = store->finalize();
2512 if (!r) { qWarning() << "Could not finalize the store"; }
2513 return r;
2514}
void saveKplGroup(QDomDocument &doc, QDomElement &groupEle, const KisSwatchGroupSP group, QSet< const KoColorSpace * > &colorSetSet) const
static const QString KPL_PALETTE_TAG
Definition KoColorSet.h:54
@ Write
Definition KoStore.h:29

References KoColorSet::comment(), KoStore::createStore(), KoColorSet::GLOBAL_GROUP_NAME, KoColorSet::KPL_COLOR_DEPTH_ID_ATTR, KoColorSet::KPL_COLOR_MODEL_ID_ATTR, KoColorSet::KPL_GROUP_NAME_ATTR, KoColorSet::KPL_GROUP_ROW_COUNT_ATTR, KoColorSet::KPL_GROUP_TAG, KoColorSet::KPL_PALETTE_COLUMN_COUNT_ATTR, KoColorSet::KPL_PALETTE_COMMENT_ATTR, KoColorSet::KPL_PALETTE_FILENAME_ATTR, KoColorSet::KPL_PALETTE_NAME_ATTR, KoColorSet::KPL_PALETTE_PROFILE_TAG, KoColorSet::KPL_PALETTE_TAG, KoColorSet::KPL_VERSION_ATTR, KoStore::Write, and KoStore::Zip.

◆ saveKplGroup()

void KoColorSet::Private::saveKplGroup ( QDomDocument & doc,
QDomElement & groupEle,
const KisSwatchGroupSP group,
QSet< const KoColorSpace * > & colorSetSet ) const
private

Definition at line 2516 of file KoColorSet.cpp.

2520{
2521 groupEle.setAttribute(KPL_GROUP_ROW_COUNT_ATTR, QString::number(group->rowCount()));
2522
2523 for (const KisSwatchGroup::SwatchInfo &info : group->infoList()) {
2524 const KoColorProfile *profile = info.swatch.color().colorSpace()->profile();
2525 // Only save non-builtin profiles.=
2526 if (!profile->fileName().isEmpty()) {
2527 bool alreadyIncluded = false;
2528 Q_FOREACH(const KoColorSpace* colorSpace, colorSetSet) {
2529 if (colorSpace->profile()->fileName() == profile->fileName()) {
2530 alreadyIncluded = true;
2531 break;
2532 }
2533 }
2534 if(!alreadyIncluded) {
2535 colorSetSet.insert(info.swatch.color().colorSpace());
2536 }
2537 }
2538 QDomElement swatchEle = doc.createElement(KPL_SWATCH_TAG);
2539 swatchEle.setAttribute(KPL_SWATCH_NAME_ATTR, info.swatch.name());
2540 swatchEle.setAttribute(KPL_SWATCH_ID_ATTR, info.swatch.id());
2541 swatchEle.setAttribute(KPL_SWATCH_SPOT_ATTR, info.swatch.spotColor() ? "true" : "false");
2542 swatchEle.setAttribute(KPL_SWATCH_BITDEPTH_ATTR, info.swatch.color().colorSpace()->colorDepthId().id());
2543 info.swatch.color().toXML(doc, swatchEle);
2544
2545 QDomElement positionEle = doc.createElement(KPL_SWATCH_POS_TAG);
2546 positionEle.setAttribute(KPL_SWATCH_ROW_ATTR, info.row);
2547 positionEle.setAttribute(KPL_SWATCH_COL_ATTR, info.column);
2548 swatchEle.appendChild(positionEle);
2549
2550 groupEle.appendChild(swatchEle);
2551 }
2552}

References KoColorProfile::fileName, KoColorSet::KPL_GROUP_ROW_COUNT_ATTR, KoColorSet::KPL_SWATCH_BITDEPTH_ATTR, KoColorSet::KPL_SWATCH_COL_ATTR, KoColorSet::KPL_SWATCH_ID_ATTR, KoColorSet::KPL_SWATCH_NAME_ATTR, KoColorSet::KPL_SWATCH_POS_TAG, KoColorSet::KPL_SWATCH_ROW_ATTR, KoColorSet::KPL_SWATCH_SPOT_ATTR, KoColorSet::KPL_SWATCH_TAG, and KoColorSpace::profile().

◆ scribusParseColor()

void KoColorSet::Private::scribusParseColor ( KoColorSet * set,
QXmlStreamReader * xml )
private

Definition at line 1094 of file KoColorSet.cpp.

1095{
1096 KisSwatch colorEntry;
1097 // It's a color, retrieve it
1098 QXmlStreamAttributes colorProperties = xml->attributes();
1099 auto colorName = colorProperties.value("NAME");
1100 colorEntry.setName(colorName.isEmpty() || colorName.isNull() ? i18n("Untitled") : colorName.toString());
1101
1102 // RGB or CMYK?
1103 if (colorProperties.hasAttribute("RGB")) {
1104 dbgPigment << "Color " << colorProperties.value("NAME") << ", RGB " << colorProperties.value("RGB");
1105
1107 auto colorValue = colorProperties.value("RGB");
1108
1109 if (colorValue.length() != 7 && colorValue.at(0) != '#') { // Color is a hexadecimal number
1110 xml->raiseError("Invalid rgb8 color (malformed): " + colorValue);
1111 return;
1112 } else {
1113 bool rgbOk;
1114 quint32 rgb = colorValue.mid(1).toUInt(&rgbOk, 16);
1115 if (!rgbOk) {
1116 xml->raiseError("Invalid rgb8 color (unable to convert): " + colorValue);
1117 return;
1118 }
1119
1120 quint8 r = rgb >> 16 & 0xff;
1121 quint8 g = rgb >> 8 & 0xff;
1122 quint8 b = rgb & 0xff;
1123
1124 dbgPigment << "Color parsed: "<< r << g << b;
1125
1126 currentColor.data()[0] = r;
1127 currentColor.data()[1] = g;
1128 currentColor.data()[2] = b;
1130 colorEntry.setColor(currentColor);
1131
1132 set->addSwatch(colorEntry);
1133
1134 while(xml->readNextStartElement()) {
1135 //ignore - these are all unknown or the /> element tag
1136 xml->skipCurrentElement();
1137 }
1138 return;
1139 }
1140 }
1141 else if (colorProperties.hasAttribute("CMYK")) {
1142 dbgPigment << "Color " << colorProperties.value("NAME") << ", CMYK " << colorProperties.value("CMYK");
1143
1145 auto colorValue = colorProperties.value("CMYK");
1146
1147 if (colorValue.length() != 9 && colorValue.at(0) != '#') { // Color is a hexadecimal number
1148 xml->raiseError("Invalid cmyk color (malformed): " % colorValue);
1149 return;
1150 }
1151 else {
1152 bool cmykOk;
1153 quint32 cmyk = colorValue.mid(1).toUInt(&cmykOk, 16); // cmyk uses the full 32 bits
1154 if (!cmykOk) {
1155 xml->raiseError("Invalid cmyk color (unable to convert): " % colorValue);
1156 return;
1157 }
1158
1159 quint8 c = cmyk >> 24 & 0xff;
1160 quint8 m = cmyk >> 16 & 0xff;
1161 quint8 y = cmyk >> 8 & 0xff;
1162 quint8 k = cmyk & 0xff;
1163
1164 dbgPigment << "Color parsed: "<< c << m << y << k;
1165
1166 currentColor.data()[0] = c;
1167 currentColor.data()[1] = m;
1168 currentColor.data()[2] = y;
1169 currentColor.data()[3] = k;
1171 colorEntry.setColor(currentColor);
1172
1173 set->addSwatch(colorEntry);
1174
1175 while(xml->readNextStartElement()) {
1176 //ignore - these are all unknown or the /> element tag
1177 xml->skipCurrentElement();
1178 }
1179 return;
1180 }
1181 }
1182 else {
1183 xml->raiseError("Unknown color space for color " + colorEntry.name());
1184 }
1185}
KoColor currentColor(ResourceProvider *provider, ColorRole role)
QString toString(const QString &value)

References KoColorSet::addSwatch(), CMYKAColorModelID, KoColor::data(), dbgPigment, KoID::id(), KoColorSpaceRegistry::instance(), Integer8BitsColorDepthID, KisSwatch::name(), OPACITY_OPAQUE_U8, KisSwatch::setColor(), KisSwatch::setName(), and KoColor::setOpacity().

Friends And Related Symbol Documentation

◆ AddGroupCommand

friend struct AddGroupCommand
friend

Definition at line 73 of file KoColorSet_p.h.

◆ AddSwatchCommand

friend struct AddSwatchCommand
friend

Definition at line 70 of file KoColorSet_p.h.

◆ ChangeGroupNameCommand

friend struct ChangeGroupNameCommand
friend

Definition at line 72 of file KoColorSet_p.h.

◆ ClearCommand

friend struct ClearCommand
friend

Definition at line 75 of file KoColorSet_p.h.

◆ MoveGroupCommand

friend struct MoveGroupCommand
friend

Definition at line 79 of file KoColorSet_p.h.

◆ RemoveGroupCommand

friend struct RemoveGroupCommand
friend

Definition at line 74 of file KoColorSet_p.h.

◆ RemoveSwatchCommand

friend struct RemoveSwatchCommand
friend

Definition at line 71 of file KoColorSet_p.h.

◆ SetColumnCountCommand

friend struct SetColumnCountCommand
friend

Definition at line 76 of file KoColorSet_p.h.

◆ SetCommentCommand

friend struct SetCommentCommand
friend

Definition at line 77 of file KoColorSet_p.h.

◆ SetPaletteTypeCommand

friend struct SetPaletteTypeCommand
friend

Definition at line 78 of file KoColorSet_p.h.

Member Data Documentation

◆ colorSet

KoColorSet* KoColorSet::Private::colorSet {0}

Definition at line 59 of file KoColorSet_p.h.

59{0};

◆ columns

int KoColorSet::Private::columns

Definition at line 66 of file KoColorSet_p.h.

◆ comment

QString KoColorSet::Private::comment

Definition at line 62 of file KoColorSet_p.h.

◆ data

QByteArray KoColorSet::Private::data

Definition at line 61 of file KoColorSet_p.h.

◆ isLocked

bool KoColorSet::Private::isLocked {false}

Definition at line 65 of file KoColorSet_p.h.

65{false};

◆ paletteType

KoColorSet::PaletteType KoColorSet::Private::paletteType {UNKNOWN}

Definition at line 60 of file KoColorSet_p.h.

60{UNKNOWN};

◆ swatchGroups

QList<KisSwatchGroupSP> KoColorSet::Private::swatchGroups

Definition at line 63 of file KoColorSet_p.h.

◆ undoStack

KUndo2Stack KoColorSet::Private::undoStack

Definition at line 64 of file KoColorSet_p.h.


The documentation for this class was generated from the following files: