1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
27 PaletteASE::~PaletteASE()
31 PaletteASE::PaletteASE( const OUString
&rFPath
, const OUString
&rFName
) :
32 mbValidPalette( false ),
39 void PaletteASE::LoadColorSet( SvxColorValueSet
& rColorSet
)
43 for (ColorList::const_iterator it
= maColors
.begin(); it
!= maColors
.end(); ++it
)
45 rColorSet
.InsertItem(nIx
, it
->first
, it
->second
);
50 const OUString
& PaletteASE::GetName()
55 bool PaletteASE::IsValid()
57 return mbValidPalette
;
60 // CMYK values from 0 to 1
61 // TODO: Deduplicate me (taken from core/cui/source/dialogs/colorpicker.cxx)
62 static void lcl_CMYKtoRGB( float fCyan
, float fMagenta
, float fYellow
, float fKey
, float& dR
, float& dG
, float& dB
)
64 fCyan
= (fCyan
* ( 1.0 - fKey
)) + fKey
;
65 fMagenta
= (fMagenta
* ( 1.0 - fKey
)) + fKey
;
66 fYellow
= (fYellow
* ( 1.0 - fKey
)) + fKey
;
68 dR
= std::max( std::min( ( 1.0 - fCyan
), 1.0), 0.0 );
69 dG
= std::max( std::min( ( 1.0 - fMagenta
), 1.0), 0.0 );
70 dB
= std::max( std::min( ( 1.0 - fYellow
), 1.0), 0.0 );
73 void PaletteASE::LoadPalette()
75 SvFileStream
aFile(maFPath
, StreamMode::READ
);
76 aFile
.SetEndian(SvStreamEndian::BIG
);
78 // Verify magic first 4 characters
79 sal_Char cMagic
[5] = {0};
80 if ((aFile
.Read(cMagic
, 4) != 4) || (strncmp(cMagic
, "ASEF", 4) != 0))
82 mbValidPalette
= false;
86 // Ignore the version number
89 sal_uInt32 nBlocks
= 0;
90 aFile
.ReadUInt32(nBlocks
);
91 for (sal_uInt32 nI
= 0; nI
< nBlocks
; nI
++) {
92 sal_uInt32 nChunkType
= 0;
93 aFile
.ReadUInt32(nChunkType
);
98 // Grab chunk size, name length
99 sal_uInt16 nChunkSize
= 0;
100 sal_uInt16 nChars
= 0;
101 aFile
.ReadUInt16(nChunkSize
);
102 aFile
.ReadUInt16(nChars
);
106 aName
= read_uInt16s_ToOUString(aFile
, nChars
);
110 if (nChunkType
== 0xC0010000)
112 // Got a start chunk, so set palette name
114 // Is there color data? (shouldn't happen in a start block, but check anyway)
115 if (nChunkSize
> ((nChars
* 2) + 2))
121 sal_Char cColorModel
[5] = {0};
122 aFile
.Read(cColorModel
, 4);
123 OString
aColorModel(cColorModel
);
124 // r, g, and b are floats ranging from 0 to 1
125 float r
= 0, g
= 0, b
= 0;
127 if (aColorModel
.equalsIgnoreAsciiCase("cmyk"))
129 float c
= 0, m
= 0, y
= 0, k
= 0;
134 lcl_CMYKtoRGB(c
, m
, y
, k
, r
, g
, b
);
136 else if (aColorModel
.equalsIgnoreAsciiCase("rgb "))
142 else if (aColorModel
.equalsIgnoreAsciiCase("gray"))
145 aFile
.ReadFloat(nVal
);
150 float nL
= 0, nA
= 0, nB
= 0;
154 // TODO: How to convert LAB to RGB?
160 maColors
.push_back(std::make_pair(Color(r
* 255, g
* 255, b
* 255), aName
));
163 mbValidPalette
= true;
166 // PaletteGPL ------------------------------------------------------------------
168 OString
lcl_getToken(const OString
& rStr
, sal_Int32
& index
);
170 PaletteGPL::PaletteGPL( const OUString
&rFPath
, const OUString
&rFName
) :
171 mbLoadedPalette( false ),
172 mbValidPalette( false ),
179 PaletteGPL::~PaletteGPL()
183 const OUString
& PaletteGPL::GetName()
188 void PaletteGPL::LoadColorSet( SvxColorValueSet
& rColorSet
)
194 for (ColorList::const_iterator it
= maColors
.begin(); it
!= maColors
.end(); ++it
)
196 rColorSet
.InsertItem(nIx
, it
->first
, it
->second
);
201 bool PaletteGPL::IsValid()
203 return mbValidPalette
;
206 bool PaletteGPL::ReadPaletteHeader(SvFileStream
& rFileStream
)
211 rFileStream
.ReadLine(aLine
);
212 if( !aLine
.startsWith("GIMP Palette") ) return false;
213 rFileStream
.ReadLine(aLine
);
214 if( aLine
.startsWith("Name: ", &aName
) )
216 maName
= OStringToOUString(aName
, RTL_TEXTENCODING_ASCII_US
);
217 rFileStream
.ReadLine(aLine
);
218 if( aLine
.startsWith("Columns: "))
219 rFileStream
.ReadLine(aLine
); // we can ignore this
228 void PaletteGPL::LoadPaletteHeader()
230 SvFileStream
aFile(maFPath
, StreamMode::READ
);
231 mbValidPalette
= ReadPaletteHeader( aFile
);
234 void PaletteGPL::LoadPalette()
236 if( mbLoadedPalette
) return;
237 mbLoadedPalette
= true;
239 // TODO add error handling!!!
240 SvFileStream
aFile(maFPath
, StreamMode::READ
);
241 mbValidPalette
= ReadPaletteHeader( aFile
);
243 if( !mbValidPalette
) return;
247 if (aLine
[0] != '#' && aLine
[0] != '\n')
249 // TODO check if r,g,b are 0<= x <=255, or just clamp?
250 sal_Int32 nIndex
= 0;
253 token
= lcl_getToken(aLine
, nIndex
);
254 if(token
.isEmpty() || nIndex
== -1) continue;
255 sal_Int32 r
= token
.toInt32();
257 token
= lcl_getToken(aLine
, nIndex
);
258 if(token
.isEmpty() || nIndex
== -1) continue;
259 sal_Int32 g
= token
.toInt32();
261 token
= lcl_getToken(aLine
, nIndex
);
262 if(token
.isEmpty()) continue;
263 sal_Int32 b
= token
.toInt32();
267 name
= aLine
.copy(nIndex
);
269 maColors
.push_back(std::make_pair(
271 OStringToOUString(name
, RTL_TEXTENCODING_ASCII_US
)));
273 } while (aFile
.ReadLine(aLine
));
276 // finds first token in rStr from index, separated by whitespace
277 // returns position of next token in index
278 OString
lcl_getToken(const OString
& rStr
, sal_Int32
& index
)
280 sal_Int32 substart
, toklen
= 0;
281 OUString
aWhitespaceChars( " \n\t" );
283 while(index
< rStr
.getLength() &&
284 aWhitespaceChars
.indexOf( rStr
[index
] ) != -1)
286 if(index
== rStr
.getLength())
293 //counts length of token
294 while(index
< rStr
.getLength() &&
295 aWhitespaceChars
.indexOf( rStr
[index
] ) == -1 )
301 //counts to position of next token
302 while(index
< rStr
.getLength() &&
303 aWhitespaceChars
.indexOf( rStr
[index
] ) != -1 )
305 if(index
== rStr
.getLength())
308 return rStr
.copy(substart
, toklen
);
311 // PaletteSOC ------------------------------------------------------------------
313 PaletteSOC::PaletteSOC( const OUString
&rFPath
, const OUString
&rFName
) :
314 mbLoadedPalette( false ),
320 PaletteSOC::~PaletteSOC()
324 const OUString
& PaletteSOC::GetName()
329 void PaletteSOC::LoadColorSet( SvxColorValueSet
& rColorSet
)
331 if( !mbLoadedPalette
)
333 mbLoadedPalette
= true;
334 mpColorList
= XPropertyList::AsColorList(XPropertyList::CreatePropertyListFromURL(XCOLOR_LIST
, maFPath
));
335 (void)mpColorList
->Load();
338 if( mpColorList
.is() )
339 rColorSet
.addEntriesForXColorList( *mpColorList
);
342 bool PaletteSOC::IsValid()
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */