1903{
1904 if (!store->open("swatchbook.xml")) {
1905 return false;
1906 }
1907
1908 QByteArray bytes = store->read(store->size());
1909 store->close();
1910
1912
1913 QDomDocument doc;
1914#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
1915 int errorLine, errorColumn;
1916 QString errorMessage;
1917 if (!doc.setContent(bytes, &errorMessage, &errorLine, &errorColumn)) {
1920 << ", column" << errorColumn
1921 << "):" << errorMessage;
1922#else
1923 QDomDocument::ParseResult result = doc.setContent(bytes);
1924 if (!result) {
1927 << ", column" << result.errorColumn
1928 << "):" << result.errorMessage;
1929#endif
1930 return false;
1931 }
1932
1933 QDomElement root = doc.documentElement();
1934
1935
1936 QDomElement
metadata = root.firstChildElement(
"metadata");
1939 return false;
1940 }
1941
1942 QDomElement title =
metadata.firstChildElement(
"dc:title");
1943 QString colorName = title.text();
1944 colorName = colorName.isEmpty() ? i18n("Untitled") : colorName;
1947
1948
1949
1950 QDomElement book = root.firstChildElement("book");
1951 if (book.isNull()) {
1952 warnPigment <<
"Palette book (swatch composition) not found (line" << root.lineNumber()
1953 << ", column" << root.columnNumber()
1954 << ")";
1955 return false;
1956 }
1957
1958
1959 QDomElement swatch = book.firstChildElement();
1960 if (swatch.isNull()) {
1961 warnPigment <<
"Swatches/groups definition not found (line" << book.lineNumber()
1962 << ", column" << book.columnNumber()
1963 << ")";
1964 return false;
1965 }
1966
1967
1968 QDomElement materials = root.firstChildElement("materials");
1969 if (materials.isNull()) {
1970 warnPigment <<
"Materials (color definitions) not found";
1971 return false;
1972 }
1973
1974
1975 if (materials.firstChildElement("color").isNull()) {
1976 warnPigment <<
"Color definitions not found (line" << materials.lineNumber()
1977 << ", column" << materials.columnNumber()
1978 << ")";
1979 return false;
1980 }
1981
1982
1983
1984 QHash<QString, KisSwatch> materialsBook;
1985 QHash<QString, const KoColorSpace*> fileColorSpaces;
1986
1987
1988 store->enterDirectory("profiles");
1989 for (QDomElement colorElement = materials.firstChildElement("color");
1990 !colorElement.isNull();
1991 colorElement = colorElement.nextSiblingElement("color")) {
1993
1994 currentEntry.
setSpotColor(colorElement.attribute(
"usage") ==
"spot");
1995
1996
1997
1998 QDomElement currentColorMetadata = colorElement.firstChildElement("metadata");
1999
2000 QDomElement colorTitle = currentColorMetadata.firstChildElement("dc:title");
2001 QDomElement colorId = currentColorMetadata.firstChildElement("dc:identifier");
2002
2003 if (colorId.text().isEmpty()) {
2004 warnPigment <<
"Unidentified color (line" << colorId.lineNumber()
2005 << ", column" << colorId.columnNumber()
2006 << ")";
2007 return false;
2008 }
2009
2010 if (materialsBook.contains(colorId.text())) {
2011 warnPigment <<
"Duplicated color definition (line" << colorId.lineNumber()
2012 << ", column" << colorId.columnNumber()
2013 << ")";
2014 return false;
2015 }
2016
2017
2018 currentEntry.
setId(colorId.text());
2019 currentEntry.
setName(colorTitle.text().isEmpty() ? colorId.text() : colorTitle.text());
2020
2021
2022 if (colorElement.firstChildElement("values").isNull()) {
2023 warnPigment <<
"Color definitions not found (line" << colorElement.lineNumber()
2024 << ", column" << colorElement.columnNumber()
2025 << ")";
2026 return false;
2027 }
2028
2029 bool status;
2030 bool firstDefinition = false;
2033
2034 for (QDomElement colorValueE = colorElement.firstChildElement("values");
2035 !colorValueE.isNull();
2036 colorValueE = colorValueE.nextSiblingElement("values")) {
2037 QString model = colorValueE.attribute("model");
2038
2039 QString modelId;
2041 if (model == "Lab") {
2043 } else if (model == "sRGB") {
2046 } else if (model == "XYZ") {
2048 } else if (model == "CMYK") {
2050 } else if (model == "GRAY") {
2052 } else if (model == "RGB") {
2054 } else {
2055 warnPigment <<
"Color space not implemented:" << model
2056 << "(line" << colorValueE.lineNumber()
2057 << ", column "<< colorValueE.columnNumber()
2058 << ")";
2059 continue;
2060 }
2061
2063
2064
2065
2066 QString space = colorValueE.attribute("space");
2067 if (!space.isEmpty()) {
2068 if (fileColorSpaces.contains(space)) {
2069 colorSpace = fileColorSpaces.value(space);
2070 } else {
2071
2073 if (profile) {
2074 colorSpace = colorSpaceRegistry->
colorSpace(modelId, colorDepthId, profile);
2075 fileColorSpaces.insert(space, colorSpace);
2076 }
2077 }
2078 }
2079
2081
2082
2083
2084
2085
2087 for (
const QString &str : colorValueE.text().
split(
" ")) {
2088 float channelValue = str.toFloat(&status);
2089 if (!status) {
2090 warnPigment <<
"Invalid float definition (line" << colorValueE.lineNumber()
2091 << ", column" << colorValueE.columnNumber()
2092 << ")";
2093
2094 channelValue = 0;
2095 }
2096
2097 channels.append(channelValue);
2098 }
2101
2103 firstDefinition = true;
2104
2105 if (model == "Lab") {
2106 break;
2107 }
2108 }
2109
2110 if (firstDefinition) {
2111 materialsBook.insert(currentEntry.
id(), currentEntry);
2112 } else {
2113 warnPigment <<
"No supported color spaces for the current color (line" << colorElement.lineNumber()
2114 << ", column "<< colorElement.columnNumber()
2115 << ")";
2116 return false;
2117 }
2118 }
2119
2120 store->leaveDirectory();
2121
2122
2123
2125 for(; !swatch.isNull(); swatch = swatch.nextSiblingElement()) {
2126 QString type = swatch.tagName();
2127 if (type.isEmpty() || type.isNull()) {
2128 warnPigment <<
"Invalid swatch/group definition (no id) (line" << swatch.lineNumber()
2129 << ", column" << swatch.columnNumber()
2130 << ")";
2131 return false;
2132 } else if (type == "swatch") {
2133 QString id = swatch.attribute("material");
2134 if (id.isEmpty() || id.isNull()) {
2135 warnPigment <<
"Invalid swatch definition (no material id) (line" << swatch.lineNumber()
2136 << ", column" << swatch.columnNumber()
2137 << ")";
2138 return false;
2139 }
2140
2141 if (materialsBook.contains(id)) {
2142 global->addSwatch(materialsBook.value(
id));
2143 } else {
2144 warnPigment <<
"Invalid swatch definition (material not found) (line" << swatch.lineNumber()
2145 << ", column" << swatch.columnNumber()
2146 << ")";
2147 return false;
2148 }
2149 } else if (type == "group") {
2150 QDomElement groupMetadata = swatch.firstChildElement("metadata");
2151 if (groupMetadata.isNull()) {
2152 warnPigment <<
"Invalid group definition (missing metadata) (line" << groupMetadata.lineNumber()
2153 << ", column" << groupMetadata.columnNumber()
2154 << ")";
2155 return false;
2156 }
2157 QDomElement groupTitle =
metadata.firstChildElement(
"dc:title");
2158 if (groupTitle.isNull()) {
2159 warnPigment <<
"Invalid group definition (missing title) (line" << groupTitle.lineNumber()
2160 << ", column" << groupTitle.columnNumber()
2161 << ")";
2162 return false;
2163 }
2164 QString currentGroupName = groupTitle.text();
2166
2167 for (QDomElement groupSwatch = swatch.firstChildElement("swatch");
2168 !groupSwatch.isNull();
2169 groupSwatch = groupSwatch.nextSiblingElement("swatch")) {
2170 QString id = groupSwatch.attribute("material");
2171 if (id.isEmpty() || id.isNull()) {
2172 warnPigment <<
"Invalid swatch definition (no material id) (line" << groupSwatch.lineNumber()
2173 << ", column" << groupSwatch.columnNumber()
2174 << ")";
2175 return false;
2176 }
2177
2178 if (materialsBook.contains(id)) {
2180 } else {
2181 warnPigment <<
"Invalid swatch definition (material not found) (line" << groupSwatch.lineNumber()
2182 << ", column" << groupSwatch.columnNumber()
2183 << ")";
2184 return false;
2185 }
2186 }
2187 }
2188 }
2189
2190
2191 return true;
2192}
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
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0