1904{
1905 if (!store->open("swatchbook.xml")) {
1906 return false;
1907 }
1908
1909 QByteArray bytes = store->read(store->size());
1910 store->close();
1911
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)) {
1921 << ", column" << errorColumn
1922 << "):" << errorMessage;
1923#else
1924 QDomDocument::ParseResult result = doc.setContent(bytes);
1925 if (!result) {
1928 << ", column" << result.errorColumn
1929 << "):" << result.errorMessage;
1930#endif
1931 return false;
1932 }
1933
1934 QDomElement root = doc.documentElement();
1935
1936
1937 QDomElement
metadata = root.firstChildElement(
"metadata");
1940 return false;
1941 }
1942
1943 QDomElement title =
metadata.firstChildElement(
"dc:title");
1944 QString colorName = title.text();
1945 colorName = colorName.isEmpty() ? i18n("Untitled") : colorName;
1948
1949
1950
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
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
1969 QDomElement materials = root.firstChildElement("materials");
1970 if (materials.isNull()) {
1971 warnPigment <<
"Materials (color definitions) not found";
1972 return false;
1973 }
1974
1975
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
1984
1985 QHash<QString, KisSwatch> materialsBook;
1986 QHash<QString, const KoColorSpace*> fileColorSpaces;
1987
1988
1989 store->enterDirectory("profiles");
1990 for (QDomElement colorElement = materials.firstChildElement("color");
1991 !colorElement.isNull();
1992 colorElement = colorElement.nextSiblingElement("color")) {
1994
1995 currentEntry.
setSpotColor(colorElement.attribute(
"usage") ==
"spot");
1996
1997
1998
1999 QDomElement currentColorMetadata = colorElement.firstChildElement("metadata");
2000
2001 QDomElement colorTitle = currentColorMetadata.firstChildElement("dc:title");
2002 QDomElement colorId = currentColorMetadata.firstChildElement("dc:identifier");
2003
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
2019 currentEntry.
setId(colorId.text());
2020 currentEntry.
setName(colorTitle.text().isEmpty() ? colorId.text() : colorTitle.text());
2021
2022
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;
2034
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;
2042 if (model == "Lab") {
2044 } else if (model == "sRGB") {
2047 } else if (model == "XYZ") {
2049 } else if (model == "CMYK") {
2051 } else if (model == "GRAY") {
2053 } else if (model == "RGB") {
2055 } else {
2056 warnPigment <<
"Color space not implemented:" << model
2057 << "(line" << colorValueE.lineNumber()
2058 << ", column "<< colorValueE.columnNumber()
2059 << ")";
2060 continue;
2061 }
2062
2064
2065
2066
2067 QString space = colorValueE.attribute("space");
2068 if (!space.isEmpty()) {
2069 if (fileColorSpaces.contains(space)) {
2070 colorSpace = fileColorSpaces.value(space);
2071 } else {
2072
2074 if (profile) {
2075 colorSpace = colorSpaceRegistry->
colorSpace(modelId, colorDepthId, profile);
2076 fileColorSpaces.insert(space, colorSpace);
2077 }
2078 }
2079 }
2080
2082
2083
2084
2085
2086
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 }
2102
2104 firstDefinition = true;
2105
2106 if (model == "Lab") {
2107 break;
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();
2122
2123
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();
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)) {
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
2191
2192 return true;
2193}
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