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