Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / tbxctrls / Palette.cxx
blobb3f1965de31b453cd4be2f847b76f3633aec0c98
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/Palette.hxx>
21 #include <tools/stream.hxx>
23 #include <palettes.hxx>
24 #include <utility>
26 Palette::~Palette()
30 PaletteASE::~PaletteASE()
34 PaletteASE::PaletteASE( OUString aFPath, OUString aFName ) :
35 mbValidPalette( false ),
36 maFPath (std::move( aFPath )),
37 maASEPaletteName (std::move( aFName ))
39 LoadPalette();
42 void PaletteASE::LoadColorSet(SvxColorValueSet& rColorSet)
44 rColorSet.Clear();
45 int nIx = 1;
46 for (const auto& rColor : maColors)
48 rColorSet.InsertItem(nIx, rColor.m_aColor, rColor.m_aName);
49 ++nIx;
53 const OUString& PaletteASE::GetName()
55 return maASEPaletteName;
58 const OUString& PaletteASE::GetPath()
60 return maFPath;
63 bool PaletteASE::IsValid()
65 return mbValidPalette;
68 // CMYK values from 0 to 1
69 // TODO: Deduplicate me (taken from core/cui/source/dialogs/colorpicker.cxx)
70 static void lcl_CMYKtoRGB( float fCyan, float fMagenta, float fYellow, float fKey, float& dR, float& dG, float& dB )
72 fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
73 fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
74 fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
76 dR = std::clamp( 1.0 - fCyan, 0.0, 1.0 );
77 dG = std::clamp( 1.0 - fMagenta, 0.0, 1.0 );
78 dB = std::clamp( 1.0 - fYellow, 0.0, 1.0 );
81 void PaletteASE::LoadPalette()
83 SvFileStream aFile(maFPath, StreamMode::READ);
84 aFile.SetEndian(SvStreamEndian::BIG);
86 // Verify magic first 4 characters
87 char cMagic[5] = {0};
88 if ((aFile.ReadBytes(cMagic, 4) != 4) || (strncmp(cMagic, "ASEF", 4) != 0))
90 mbValidPalette = false;
91 return;
94 // Ignore the version number
95 aFile.SeekRel(4);
97 sal_uInt32 nBlocks = 0;
98 aFile.ReadUInt32(nBlocks);
99 for (sal_uInt32 nI = 0; nI < nBlocks; nI++) {
100 sal_uInt32 nChunkType = 0;
101 aFile.ReadUInt32(nChunkType);
102 // End chunk
103 if (nChunkType == 0)
104 break;
106 // Grab chunk size, name length
107 sal_uInt16 nChunkSize = 0;
108 sal_uInt16 nChars = 0;
109 aFile.ReadUInt16(nChunkSize);
110 aFile.ReadUInt16(nChars);
112 OUString aPaletteName("");
113 if (nChars > 1)
114 aPaletteName = read_uInt16s_ToOUString(aFile, nChars);
115 else
116 aFile.SeekRel(2);
118 if (nChunkType == 0xC0010000)
120 // Got a start chunk, so set palette name
121 maASEPaletteName = aPaletteName;
122 // Is there color data? (shouldn't happen in a start block, but check anyway)
123 if (nChunkSize > ((nChars * 2) + 2))
124 aPaletteName.clear();
125 else
126 continue;
129 char cColorModel[5] = {0};
130 aFile.ReadBytes(cColorModel, 4);
131 OString aColorModel(cColorModel);
132 // r, g, and b are floats ranging from 0 to 1
133 float r = 0, g = 0, b = 0;
135 if (aColorModel.equalsIgnoreAsciiCase("cmyk"))
137 float c = 0, m = 0, y = 0, k = 0;
138 aFile.ReadFloat(c);
139 aFile.ReadFloat(m);
140 aFile.ReadFloat(y);
141 aFile.ReadFloat(k);
142 lcl_CMYKtoRGB(c, m, y, k, r, g, b);
144 else if (aColorModel.equalsIgnoreAsciiCase("rgb "))
146 aFile.ReadFloat(r);
147 aFile.ReadFloat(g);
148 aFile.ReadFloat(b);
150 else if (aColorModel.equalsIgnoreAsciiCase("gray"))
152 float nVal = 0;
153 aFile.ReadFloat(nVal);
154 r = g = b = nVal;
156 else
158 float nL = 0, nA = 0, nB = 0;
159 aFile.ReadFloat(nL);
160 aFile.ReadFloat(nA);
161 aFile.ReadFloat(nB);
162 // TODO: How to convert LAB to RGB?
163 r = g = b = 0;
166 // Ignore color type
167 aFile.SeekRel(2);
168 maColors.emplace_back(Color(r * 255, g * 255, b * 255), aPaletteName);
171 mbValidPalette = true;
174 Palette* PaletteASE::Clone() const
176 return new PaletteASE(*this);
179 // PaletteGPL ------------------------------------------------------------------
181 static OString lcl_getToken(OStringBuffer& rStr, sal_Int32& index);
183 PaletteGPL::PaletteGPL( OUString aFPath, OUString aFName ) :
184 mbLoadedPalette( false ),
185 mbValidPalette( false ),
186 maFName(std::move( aFName )),
187 maFPath(std::move( aFPath ))
189 LoadPaletteHeader();
192 PaletteGPL::~PaletteGPL()
196 const OUString& PaletteGPL::GetName()
198 return maGPLPaletteName;
201 const OUString& PaletteGPL::GetPath()
203 return maFPath;
206 void PaletteGPL::LoadColorSet(SvxColorValueSet& rColorSet)
208 LoadPalette();
210 rColorSet.Clear();
211 int nIx = 1;
212 for (const auto& rColor : maColors)
214 rColorSet.InsertItem(nIx, rColor.m_aColor, rColor.m_aName);
215 ++nIx;
219 bool PaletteGPL::IsValid()
221 return mbValidPalette;
224 bool PaletteGPL::ReadPaletteHeader(SvFileStream& rFileStream)
226 OString aLine;
227 OString aPaletteName;
229 rFileStream.ReadLine(aLine);
230 if( !aLine.startsWith("GIMP Palette") ) return false;
231 rFileStream.ReadLine(aLine);
232 if( aLine.startsWith("Name: ", &aPaletteName) )
234 maGPLPaletteName = OStringToOUString(aPaletteName, RTL_TEXTENCODING_ASCII_US);
235 rFileStream.ReadLine(aLine);
236 if( aLine.startsWith("Columns: "))
237 rFileStream.ReadLine(aLine); // we can ignore this
239 else
241 maGPLPaletteName = maFName;
243 return true;
246 void PaletteGPL::LoadPaletteHeader()
248 SvFileStream aFile(maFPath, StreamMode::READ);
249 mbValidPalette = ReadPaletteHeader( aFile );
252 void PaletteGPL::LoadPalette()
254 if( mbLoadedPalette ) return;
255 mbLoadedPalette = true;
257 // TODO add error handling!!!
258 SvFileStream aFile(maFPath, StreamMode::READ);
259 mbValidPalette = ReadPaletteHeader( aFile );
261 if( !mbValidPalette ) return;
263 OStringBuffer aLine;
264 do {
265 if (aLine.isEmpty())
266 continue;
268 if (aLine[0] != '#' && aLine[0] != '\n')
270 // TODO check if r,g,b are 0<= x <=255, or just clamp?
271 sal_Int32 nIndex = 0;
272 OString token;
274 token = lcl_getToken(aLine, nIndex);
275 if(token.isEmpty() || nIndex == -1) continue;
276 sal_Int32 r = token.toInt32();
278 token = lcl_getToken(aLine, nIndex);
279 if(token.isEmpty() || nIndex == -1) continue;
280 sal_Int32 g = token.toInt32();
282 token = lcl_getToken(aLine, nIndex);
283 if(token.isEmpty()) continue;
284 sal_Int32 b = token.toInt32();
286 std::string_view name;
287 if(nIndex != -1)
288 name = std::string_view(aLine).substr(nIndex);
290 maColors.emplace_back(
291 Color(r, g, b),
292 OStringToOUString(name, RTL_TEXTENCODING_ASCII_US));
294 } while (aFile.ReadLine(aLine));
297 Palette* PaletteGPL::Clone() const
299 return new PaletteGPL(*this);
302 // finds first token in rStr from index, separated by whitespace
303 // returns position of next token in index
304 static OString lcl_getToken(OStringBuffer& rStr, sal_Int32& index)
306 sal_Int32 substart, toklen = 0;
307 OUString aWhitespaceChars( " \n\t" );
309 while(index < rStr.getLength() &&
310 aWhitespaceChars.indexOf( rStr[index] ) != -1)
311 ++index;
312 if(index == rStr.getLength())
314 index = -1;
315 return OString();
317 substart = index;
319 //counts length of token
320 while(index < rStr.getLength() &&
321 aWhitespaceChars.indexOf( rStr[index] ) == -1 )
323 ++index;
324 ++toklen;
327 //counts to position of next token
328 while(index < rStr.getLength() &&
329 aWhitespaceChars.indexOf( rStr[index] ) != -1 )
330 ++index;
331 if(index == rStr.getLength())
332 index = -1;
334 return OString(std::string_view(rStr).substr(substart, toklen));
337 // PaletteSOC ------------------------------------------------------------------
339 PaletteSOC::PaletteSOC( OUString aFPath, OUString aFName ) :
340 mbLoadedPalette( false ),
341 maFPath(std::move( aFPath )),
342 maSOCPaletteName(std::move( aFName ))
346 PaletteSOC::~PaletteSOC()
350 const OUString& PaletteSOC::GetName()
352 return maSOCPaletteName;
355 const OUString& PaletteSOC::GetPath()
357 return maFPath;
360 void PaletteSOC::LoadColorSet(SvxColorValueSet& rColorSet)
362 if( !mbLoadedPalette )
364 mbLoadedPalette = true;
365 mpColorList = XPropertyList::AsColorList(XPropertyList::CreatePropertyListFromURL(XPropertyListType::Color, maFPath));
366 (void)mpColorList->Load();
368 rColorSet.Clear();
369 if( mpColorList.is() )
370 rColorSet.addEntriesForXColorList( *mpColorList );
373 bool PaletteSOC::IsValid()
375 return true;
378 Palette* PaletteSOC::Clone() const
380 return new PaletteSOC(*this);
383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */