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