1 #include <iostream>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "../support/util.h"
6 #include "devicencolorant.h"
7
8 #include "../support/debug.h"
9
10 #include "../config.h"
11 #include "../gettext.h"
12
13 using namespace std;
14
15
DeviceNColorantList()16 DeviceNColorantList::DeviceNColorantList() : first(NULL)
17 {
18 }
19
20
DeviceNColorantList(IS_TYPE type)21 DeviceNColorantList::DeviceNColorantList(IS_TYPE type) : first(NULL)
22 {
23 switch(STRIP_ALPHA(type))
24 {
25 case IS_TYPE_GREY:
26 case IS_TYPE_BW:
27 new DeviceNColorant(*this,"Black");
28 break;
29 case IS_TYPE_RGB:
30 new DeviceNColorant(*this,"Red");
31 new DeviceNColorant(*this,"Green");
32 new DeviceNColorant(*this,"Blue");
33 break;
34 case IS_TYPE_CMYK:
35 new DeviceNColorant(*this,"Cyan");
36 new DeviceNColorant(*this,"Magenta");
37 new DeviceNColorant(*this,"Yellow");
38 new DeviceNColorant(*this,"Black");
39 break;
40 default:
41 throw "Can't yet automatically construct a DeviceNColorantList for non-standard colourspaces";
42 break;
43 }
44 if(HAS_ALPHA(type))
45 new DeviceNColorant(*this,"Alpha");
46 }
47
48
~DeviceNColorantList()49 DeviceNColorantList::~DeviceNColorantList()
50 {
51 while(first)
52 delete first;
53 }
54
55
GetColorantCount()56 int DeviceNColorantList::GetColorantCount()
57 {
58 int result=0;
59 DeviceNColorant *c=first;
60 while(c)
61 {
62 ++result;
63 c=c->NextColorant();
64 }
65 return(result);
66 }
67
68
69 // Create a string representation of which colorants are active,
70 // suitable for storing in a config file.
71
GetEnabledColorants()72 char *DeviceNColorantList::GetEnabledColorants()
73 {
74 char *result=NULL;
75 DeviceNColorant *col=FirstColorant();
76 int len=2; // Initial ":" and null-terminator
77 while(col)
78 {
79 if(col->GetEnabled())
80 {
81 const char *name=col->GetName();
82 if(name)
83 len+=strlen(name)+2;
84 }
85 col=col->NextColorant();
86 }
87 result=(char *)malloc(len);
88 result[0]=':';
89 result[1]=0;
90 col=FirstColorant();
91 while(col)
92 {
93 if(col->GetEnabled())
94 {
95 const char *name=col->GetName();
96 if(name)
97 {
98 strcat(result,name);
99 strcat(result,":");
100 }
101 }
102 col=col->NextColorant();
103 }
104 if(!result)
105 result=strdup("");
106 return(result);
107 }
108
109
110 // Given a string respresention as produced by GetEnabledColorants()
111 // sets the "enabled" flag in the colorants
112
SetEnabledColorants(const char * colstr)113 void DeviceNColorantList::SetEnabledColorants(const char *colstr)
114 {
115 if(colstr && strlen(colstr))
116 {
117 DeviceNColorant *col=FirstColorant();
118 while(col)
119 {
120 col->Disable();
121 const char *name=col->GetName();
122 if(name && strlen(name))
123 {
124 const char *tmp=strstr(colstr,name);
125 while(tmp)
126 {
127 if(tmp[-1]==':' && tmp[strlen(name)]==':')
128 {
129 col->Enable();
130 tmp=NULL;
131 }
132 else
133 tmp=strstr(tmp+1,name);
134 }
135 }
136 col=col->NextColorant();
137 }
138 }
139 }
140
141
FirstColorant()142 DeviceNColorant *DeviceNColorantList::FirstColorant()
143 {
144 return(first);
145 }
146
147
GetColorantIndex(const char * name)148 int DeviceNColorantList::GetColorantIndex(const char *name)
149 {
150 if(!name)
151 return(-1);
152 DeviceNColorant *col=FirstColorant();
153 int result=0;
154 while(col)
155 {
156 const char *colname;
157 if((colname=col->GetName()))
158 {
159 if(StrcasecmpIgnoreSpaces(colname,name)==0)
160 return(result);
161 }
162 ++result;
163 col=col->NextColorant();
164 }
165 return(-1);
166 }
167
168
operator [](int idx)169 DeviceNColorant *DeviceNColorantList::operator[](int idx)
170 {
171 DeviceNColorant *result=FirstColorant();
172 while(idx && result)
173 {
174 result=result->NextColorant();
175 --idx;
176 }
177 return(result);
178 }
179
180
181 /////////////////////////////////////////////////////////////////////////////
182
183 struct colorantdefinition
184 {
185 const char *name;
186 int red,green,blue;
187 };
188
189 static struct colorantdefinition colorantdefinitions[]=
190 {
191 {"Cyan",0,190,255},
192 {"Magenta",255,0,190},
193 {"Vivid Magenta",255,0,190},
194 {"Yellow",255,255,0},
195 {"Black",0,0,0},
196 {"Photo Black",0,0,0},
197 {"Matte Black",0,0,0},
198 {"Light Cyan",127,220,255},
199 {"Light Magenta",255,127,220},
200 {"Vivid Light Magenta",255,127,220},
201 {"Light Black",127,127,127},
202 {"Light Light Black",191,191,191},
203 {"Medium Black",63,63,63},
204 {"Dark Yellow",160,140,0},
205 {"Red",255,0,0},
206 {"Blue",0,0,255},
207 {"Green",0,255,0},
208 {"Orange",255,128,0},
209 {"Alpha",192,192,192},
210 {"White",255,255,255},
211 {NULL,0,0,0}
212 };
213
214
DeviceNColorant(DeviceNColorantList & header,const char * name,const char * displayname)215 DeviceNColorant::DeviceNColorant(DeviceNColorantList &header,const char *name,const char *displayname)
216 : red(0), green(0), blue(0), header(header), enabled(true), name(NULL), displayname(NULL), next(NULL), prev(NULL)
217 {
218 struct colorantdefinition *c=colorantdefinitions;
219 if(name)
220 {
221 while(c->name)
222 {
223 if(StrcasecmpIgnoreSpaces(name,c->name)==0)
224 {
225 if(name)
226 this->name=strdup(name);
227
228 if(displayname)
229 this->displayname=strdup(displayname);
230 else
231 this->displayname=strdup(gettext(name));
232
233 red=c->red;
234 green=c->green;
235 blue=c->blue;
236
237 linknode();
238
239 return;
240 }
241 ++c;
242 }
243 Debug[WARN] << "Can't find colorant: " << name << endl;
244 throw "Colorant not recognised";
245 }
246 else
247 {
248 red=c->red;
249 green=c->green;
250 blue=c->blue;
251
252 linknode();
253 }
254 }
255
256
DeviceNColorant(DeviceNColorantList & header,const char * name,const char * displayname,int r,int g,int b)257 DeviceNColorant::DeviceNColorant(DeviceNColorantList &header,const char *name,const char *displayname,int r,int g, int b)
258 : red(r), green(g), blue(b), header(header), enabled(true), name(NULL), displayname(NULL), next(NULL), prev(NULL)
259 {
260 if(name)
261 this->name=strdup(name);
262 if(displayname)
263 this->displayname=strdup(displayname);
264 else
265 this->displayname=strdup(gettext(name));
266 linknode();
267 }
268
269
~DeviceNColorant()270 DeviceNColorant::~DeviceNColorant()
271 {
272 if(name)
273 free(name);
274 if(displayname)
275 free(displayname);
276 if(prev)
277 prev->next=next;
278 else
279 header.first=next;
280 if(next)
281 next->prev=prev;
282 }
283
284
linknode()285 void DeviceNColorant::linknode()
286 {
287 prev=header.first;
288 if(prev)
289 {
290 while(prev->next)
291 prev=prev->next;
292 prev->next=this;
293 }
294 else
295 header.first=this;
296 }
297
298
GetName()299 const char *DeviceNColorant::GetName()
300 {
301 return(name);
302 }
303
304
GetDisplayName()305 const char *DeviceNColorant::GetDisplayName()
306 {
307 return(displayname);
308 }
309
310
Enable()311 void DeviceNColorant::Enable()
312 {
313 enabled=true;
314 }
315
316
Disable()317 void DeviceNColorant::Disable()
318 {
319 enabled=false;
320 }
321
322
GetEnabled()323 bool DeviceNColorant::GetEnabled()
324 {
325 return(enabled);
326 }
327
328
NextColorant()329 DeviceNColorant *DeviceNColorant::NextColorant()
330 {
331 return(next);
332 }
333
334
PrevColorant()335 DeviceNColorant *DeviceNColorant::PrevColorant()
336 {
337 return(prev);
338 }
339
340
341 #ifdef STANDALONETEST
342
main(int argc,char ** argv)343 int main(int argc,char **argv)
344 {
345 DeviceNColorantList list;
346
347 try
348 {
349 new GPColorant(list,"Yellow");
350 new GPColorant(list,"Cyan");
351 new GPColorant(list,"Magenta");
352 new GPColorant(list,"Sky blue pink");
353 }
354 catch(const char *err)
355 {
356 Debug[ERROR] << "Caught error: " << err << endl;
357 }
358 Debug[COMMENT] << "Have " << list.GetColorantCount() << " colorants" << endl;
359
360 Debug[COMMENT] << "Name of colorant 2: " << list[2]->GetName() << endl;
361
362
363 DeviceNColorant *c=list.FirstColorant();
364 while(c)
365 {
366 Debug[COMMENT] << c->GetName() << endl;
367 c=c->NextColorant();
368 }
369
370 return(0);
371 }
372
373 #endif
374
375