LibreOffice Module svx (master) 1
Palette.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <svx/Palette.hxx>
21#include <tools/stream.hxx>
22
23#include <palettes.hxx>
24#include <utility>
25
27{
28}
29
31{
32}
33
34PaletteASE::PaletteASE( OUString aFPath, OUString aFName ) :
35 mbValidPalette( false ),
36 maFPath (std::move( aFPath )),
37 maASEPaletteName (std::move( aFName ))
38{
40}
41
43{
44 rColorSet.Clear();
45 int nIx = 1;
46 for (const auto& rColor : maColors)
47 {
48 rColorSet.InsertItem(nIx, rColor.m_aColor, rColor.m_aName);
49 ++nIx;
50 }
51}
52
53const OUString& PaletteASE::GetName()
54{
55 return maASEPaletteName;
56}
57
58const OUString& PaletteASE::GetPath()
59{
60 return maFPath;
61}
62
64{
65 return mbValidPalette;
66}
67
68// CMYK values from 0 to 1
69// TODO: Deduplicate me (taken from core/cui/source/dialogs/colorpicker.cxx)
70static void lcl_CMYKtoRGB( float fCyan, float fMagenta, float fYellow, float fKey, float& dR, float& dG, float& dB )
71{
72 fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
73 fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
74 fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
75
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 );
79}
80
82{
83 SvFileStream aFile(maFPath, StreamMode::READ);
84 aFile.SetEndian(SvStreamEndian::BIG);
85
86 // Verify magic first 4 characters
87 char cMagic[5] = {0};
88 if ((aFile.ReadBytes(cMagic, 4) != 4) || (strncmp(cMagic, "ASEF", 4) != 0))
89 {
90 mbValidPalette = false;
91 return;
92 }
93
94 // Ignore the version number
95 aFile.SeekRel(4);
96
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;
105
106 // Grab chunk size, name length
107 sal_uInt16 nChunkSize = 0;
108 sal_uInt16 nChars = 0;
109 aFile.ReadUInt16(nChunkSize);
110 aFile.ReadUInt16(nChars);
111
112 OUString aPaletteName("");
113 if (nChars > 1)
114 aPaletteName = read_uInt16s_ToOUString(aFile, nChars);
115 else
116 aFile.SeekRel(2);
117
118 if (nChunkType == 0xC0010000)
119 {
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;
127 }
128
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;
134
135 if (aColorModel.equalsIgnoreAsciiCase("cmyk"))
136 {
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);
143 }
144 else if (aColorModel.equalsIgnoreAsciiCase("rgb "))
145 {
146 aFile.ReadFloat(r);
147 aFile.ReadFloat(g);
148 aFile.ReadFloat(b);
149 }
150 else if (aColorModel.equalsIgnoreAsciiCase("gray"))
151 {
152 float nVal = 0;
153 aFile.ReadFloat(nVal);
154 r = g = b = nVal;
155 }
156 else
157 {
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;
164 }
165
166 // Ignore color type
167 aFile.SeekRel(2);
168 maColors.emplace_back(Color(r * 255, g * 255, b * 255), aPaletteName);
169 }
170
171 mbValidPalette = true;
172}
173
175{
176 return new PaletteASE(*this);
177}
178
179// PaletteGPL ------------------------------------------------------------------
180
181static OString lcl_getToken(OStringBuffer& rStr, sal_Int32& index);
182
183PaletteGPL::PaletteGPL( OUString aFPath, OUString aFName ) :
184 mbLoadedPalette( false ),
185 mbValidPalette( false ),
186 maFName(std::move( aFName )),
187 maFPath(std::move( aFPath ))
188{
190}
191
193{
194}
195
196const OUString& PaletteGPL::GetName()
197{
198 return maGPLPaletteName;
199}
200
201const OUString& PaletteGPL::GetPath()
202{
203 return maFPath;
204}
205
207{
208 LoadPalette();
209
210 rColorSet.Clear();
211 int nIx = 1;
212 for (const auto& rColor : maColors)
213 {
214 rColorSet.InsertItem(nIx, rColor.m_aColor, rColor.m_aName);
215 ++nIx;
216 }
217}
218
220{
221 return mbValidPalette;
222}
223
225{
226 OString aLine;
227 OString aPaletteName;
228
229 rFileStream.ReadLine(aLine);
230 if( !aLine.startsWith("GIMP Palette") ) return false;
231 rFileStream.ReadLine(aLine);
232 if( aLine.startsWith("Name: ", &aPaletteName) )
233 {
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
238 }
239 else
240 {
242 }
243 return true;
244}
245
247{
248 SvFileStream aFile(maFPath, StreamMode::READ);
250}
251
253{
254 if( mbLoadedPalette ) return;
255 mbLoadedPalette = true;
256
257 // TODO add error handling!!!
258 SvFileStream aFile(maFPath, StreamMode::READ);
260
261 if( !mbValidPalette ) return;
262
263 OStringBuffer aLine;
264 do {
265 if (aLine[0] != '#' && aLine[0] != '\n')
266 {
267 // TODO check if r,g,b are 0<= x <=255, or just clamp?
268 sal_Int32 nIndex = 0;
269 OString token;
270
271 token = lcl_getToken(aLine, nIndex);
272 if(token.isEmpty() || nIndex == -1) continue;
273 sal_Int32 r = token.toInt32();
274
275 token = lcl_getToken(aLine, nIndex);
276 if(token.isEmpty() || nIndex == -1) continue;
277 sal_Int32 g = token.toInt32();
278
279 token = lcl_getToken(aLine, nIndex);
280 if(token.isEmpty()) continue;
281 sal_Int32 b = token.toInt32();
282
283 std::string_view name;
284 if(nIndex != -1)
285 name = std::string_view(aLine).substr(nIndex);
286
287 maColors.emplace_back(
288 Color(r, g, b),
289 OStringToOUString(name, RTL_TEXTENCODING_ASCII_US));
290 }
291 } while (aFile.ReadLine(aLine));
292}
293
295{
296 return new PaletteGPL(*this);
297}
298
299// finds first token in rStr from index, separated by whitespace
300// returns position of next token in index
301static OString lcl_getToken(OStringBuffer& rStr, sal_Int32& index)
302{
303 sal_Int32 substart, toklen = 0;
304 OUString aWhitespaceChars( " \n\t" );
305
306 while(index < rStr.getLength() &&
307 aWhitespaceChars.indexOf( rStr[index] ) != -1)
308 ++index;
309 if(index == rStr.getLength())
310 {
311 index = -1;
312 return OString();
313 }
314 substart = index;
315
316 //counts length of token
317 while(index < rStr.getLength() &&
318 aWhitespaceChars.indexOf( rStr[index] ) == -1 )
319 {
320 ++index;
321 ++toklen;
322 }
323
324 //counts to position of next token
325 while(index < rStr.getLength() &&
326 aWhitespaceChars.indexOf( rStr[index] ) != -1 )
327 ++index;
328 if(index == rStr.getLength())
329 index = -1;
330
331 return OString(std::string_view(rStr).substr(substart, toklen));
332}
333
334// PaletteSOC ------------------------------------------------------------------
335
336PaletteSOC::PaletteSOC( OUString aFPath, OUString aFName ) :
337 mbLoadedPalette( false ),
338 maFPath(std::move( aFPath )),
339 maSOCPaletteName(std::move( aFName ))
340{
341}
342
344{
345}
346
347const OUString& PaletteSOC::GetName()
348{
349 return maSOCPaletteName;
350}
351
352const OUString& PaletteSOC::GetPath()
353{
354 return maFPath;
355}
356
358{
359 if( !mbLoadedPalette )
360 {
361 mbLoadedPalette = true;
363 (void)mpColorList->Load();
364 }
365 rColorSet.Clear();
366 if( mpColorList.is() )
368}
369
371{
372 return true;
373}
374
376{
377 return new PaletteSOC(*this);
378}
379
380/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OString lcl_getToken(OStringBuffer &rStr, sal_Int32 &index)
Definition: Palette.cxx:301
static void lcl_CMYKtoRGB(float fCyan, float fMagenta, float fYellow, float fKey, float &dR, float &dG, float &dB)
Definition: Palette.cxx:70
PaletteASE(const PaletteASE &)=default
virtual ~PaletteASE() override
Definition: Palette.cxx:30
virtual const OUString & GetName() override
Definition: Palette.cxx:53
OUString maASEPaletteName
Definition: palettes.hxx:36
bool mbValidPalette
Definition: palettes.hxx:34
ColorList maColors
Definition: palettes.hxx:37
virtual void LoadColorSet(SvxColorValueSet &rColorSet) override
Definition: Palette.cxx:42
OUString maFPath
Definition: palettes.hxx:35
virtual Palette * Clone() const override
Definition: Palette.cxx:174
void LoadPalette()
Definition: Palette.cxx:81
virtual const OUString & GetPath() override
Definition: Palette.cxx:58
virtual bool IsValid() override
Definition: Palette.cxx:63
void LoadPaletteHeader()
Definition: Palette.cxx:246
OUString maFName
Definition: palettes.hxx:60
bool ReadPaletteHeader(SvFileStream &rFileStream)
Definition: Palette.cxx:224
void LoadPalette()
Definition: Palette.cxx:252
virtual Palette * Clone() const override
Definition: Palette.cxx:294
virtual void LoadColorSet(SvxColorValueSet &rColorSet) override
Definition: Palette.cxx:206
virtual bool IsValid() override
Definition: Palette.cxx:219
ColorList maColors
Definition: palettes.hxx:63
virtual const OUString & GetPath() override
Definition: Palette.cxx:201
OUString maFPath
Definition: palettes.hxx:61
virtual const OUString & GetName() override
Definition: Palette.cxx:196
virtual ~PaletteGPL() override
Definition: Palette.cxx:192
PaletteGPL(const PaletteGPL &)=default
bool mbValidPalette
Definition: palettes.hxx:59
OUString maGPLPaletteName
Definition: palettes.hxx:62
bool mbLoadedPalette
Definition: palettes.hxx:58
virtual ~PaletteSOC() override
Definition: Palette.cxx:343
virtual bool IsValid() override
Definition: Palette.cxx:370
virtual const OUString & GetPath() override
Definition: Palette.cxx:352
OUString maFPath
Definition: palettes.hxx:87
bool mbLoadedPalette
Definition: palettes.hxx:86
virtual Palette * Clone() const override
Definition: Palette.cxx:375
XColorListRef mpColorList
Definition: palettes.hxx:89
PaletteSOC(const PaletteSOC &)=default
virtual const OUString & GetName() override
Definition: Palette.cxx:347
OUString maSOCPaletteName
Definition: palettes.hxx:88
virtual void LoadColorSet(SvxColorValueSet &rColorSet) override
Definition: Palette.cxx:357
virtual ~Palette()
Definition: Palette.cxx:26
void SetEndian(SvStreamEndian SvStreamEndian)
SvStream & ReadFloat(float &rFloat)
bool ReadLine(OStringBuffer &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt64 SeekRel(sal_Int64 nPos)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
void addEntriesForXColorList(const XColorList &rXColorList, sal_uInt32 nStartIndex=1)
void InsertItem(sal_uInt16 nItemId, const Image &rImage)
void Clear()
static XColorListRef AsColorList(rtl::Reference< XPropertyList > const &plist)
Definition: xtable.hxx:378
static XPropertyListRef CreatePropertyListFromURL(XPropertyListType t, std::u16string_view rUrl)
Definition: xtable.cxx:354
float y
const char * name
sal_Int32 nIndex
index
m
TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nUnits)