1 /*****************************************************************************/
2 /* ColorGC GC�ȿ��δ������䤤��碌�ѤΥ饤�֥��                            */
3 /*****************************************************************************/
4 
5 #include "ColorGCP.h"
6 
7 #include "Stream.h"
8 #include "etc.h"
9 
10 /*===========================================================================*/
11 /* ColorGCInstance ��Ϣ                                                      */
12 /*===========================================================================*/
13 
14 /*---------------------------------------------------------------------------*/
15 /* ���֥������Ȥκ���                                                        */
16 /*---------------------------------------------------------------------------*/
17 
ColorGCInstance_Create(Disp disp,XColor color)18 static ColorGCInstance ColorGCInstance_Create(Disp disp, XColor color)
19 {
20   ColorGCInstance instance;
21 
22   instance = (ColorGCInstance)malloc(sizeof(_ColorGCInstance));
23   if (instance == NULL)
24     Error("ColorGCInstance_Create", "Cannot allocate memory");
25 
26   instance->disp = disp;
27   instance->color = color;
28 
29   XAllocColor(Disp_GetDisplay(instance->disp),
30 	      Disp_GetColormap(instance->disp),
31 	      &(instance->color));
32 
33   /* XAllocColor �� instance->color.red �ʤɤ����Ƥ��Ѥ�äƤ��ޤ��Τǡ�   */
34   /* ��Ȥ��᤹���Ǥʤ��ȡ����Ȥ�Ʊ������RGB�ͤǸ������Ƥ⡤��ä����Ȥ��� */
35   /* ��ᤵ��Ƥ��ޤ��������Ǥ��ʤ��Τǡ����������¸�����̣��̵���ʤä�  */
36   /* ���ޤ���                                                              */
37   instance->color.red   = color.red;
38   instance->color.green = color.green;
39   instance->color.blue  = color.blue;
40 
41   instance->gc = Disp_CreateGC(instance->disp);
42 
43   XSetForeground(Disp_GetDisplay(instance->disp), instance->gc,
44 		 instance->color.pixel);
45   XSetBackground(Disp_GetDisplay(instance->disp), instance->gc,
46 		 instance->color.pixel);
47 
48   return (instance);
49 }
50 
51 /*---------------------------------------------------------------------------*/
52 /* ���֥������Ȥκ��                                                        */
53 /*---------------------------------------------------------------------------*/
54 
ColorGCInstance_Destroy(ColorGCInstance instance)55 static ColorGCInstance ColorGCInstance_Destroy(ColorGCInstance instance)
56 {
57   unsigned long pixel;
58 
59   if (instance == NULL) return (NULL);
60   if (instance->gc) Disp_DestroyGC(instance->disp, instance->gc);
61   pixel = instance->color.pixel;
62   XFreeColors(Disp_GetDisplay(instance->disp),
63 	      Disp_GetColormap(instance->disp),
64 	      &pixel, 1, 0);
65   free(instance);
66   return (NULL);
67 }
68 
69 /*===========================================================================*/
70 /* ColorGCList ��Ϣ                                                          */
71 /*===========================================================================*/
72 
73 /*---------------------------------------------------------------------------*/
74 /* ���֥������Ȥκ���                                                        */
75 /*---------------------------------------------------------------------------*/
76 
ColorGCList_Create(Disp disp,int studying_flag)77 static ColorGCList ColorGCList_Create(Disp disp, int studying_flag)
78 {
79   ColorGCList list;
80 
81   list = (ColorGCList)malloc(sizeof(_ColorGCList));
82   if (list == NULL) Error("ColorGCList_Create", "Cannot allocate memory");
83 
84   list->disp = disp;
85   list->studying_flag = studying_flag;
86   list->list = ObjList_Create();
87 
88   return (list);
89 }
90 
91 /*---------------------------------------------------------------------------*/
92 /* ���֥������Ȥκ��                                                        */
93 /*---------------------------------------------------------------------------*/
94 
ColorGCList_Destroy(ColorGCList list)95 static ColorGCList ColorGCList_Destroy(ColorGCList list)
96 {
97   if (list == NULL) return (NULL);
98 
99   if (list->list) ObjList_Destroy(list->list);
100 
101   free(list);
102 
103   return (NULL);
104 }
105 
106 /*---------------------------------------------------------------------------*/
107 /* ColorGCList ��Ǥ� ColorGCInstance �Υ������Ѥ���Ӵؿ�                   */
108 /*---------------------------------------------------------------------------*/
109 
ColorGCInstance_CmpToColor(ColorGCInstance gci,XColor color)110 static int ColorGCInstance_CmpToColor(ColorGCInstance gci, XColor color)
111 {
112   if (gci->color.red   > color.red  ) return ( 1);
113   if (gci->color.red   < color.red  ) return (-1);
114   if (gci->color.green > color.green) return ( 1);
115   if (gci->color.green < color.green) return (-1);
116   if (gci->color.blue  > color.blue ) return ( 1);
117   if (gci->color.blue  < color.blue ) return (-1);
118   return (0);
119 }
120 
121 /*---------------------------------------------------------------------------*/
122 /* �ꥹ�Ȥ��� ColorGCInstance �����롥                                       */
123 /* GC �μ����׵���Ф��ơ�GC �Υꥹ�Ȥ��������֤���                        */
124 /* ���� current �ǡ������Υ���������������ꤹ�롥                           */
125 /* ¸�ߤ��ʤ����ˤϡ��������ƥꥹ�Ȥ��ɲä��롥                            */
126 /* (��� RGB �ͤǥ����Ȥ��줿���֤��ɲä���)                                 */
127 /* ����õ���ʤΤǡ�O(n^2)���٤��ʤ롥                                        */
128 /*---------------------------------------------------------------------------*/
129 
ColorGCList_GetColorGCInstance(ColorGCList list,XColor color)130 static ColorGCInstance ColorGCList_GetColorGCInstance(ColorGCList list,
131 						      XColor color)
132 {
133   ColorGCInstance instance;
134   ObjListData current;
135   int cmp;
136 
137   for (current = ObjList_GetStart(list->list);
138        !ObjList_IsEndEdge(list->list, current);
139        current = ObjListData_GetNext(current)) {
140 
141     instance = (ColorGCInstance)ObjListData_GetObj(current);
142     cmp = ColorGCInstance_CmpToColor(instance, color);
143 
144     if (cmp == 0) { /* ���Ĥ���С�������֤� */
145 #ifdef HIT_LIST
146       fprintf(stderr, "S");
147 #endif
148       if (list->studying_flag) ObjList_MoveObjToStart(list->list, current);
149       return (instance);
150     } else if (cmp > 0) {
151       if (!list->studying_flag) break;
152     }
153   }
154 
155   /* ���Ĥ���ʤ��ä����ϡ��������ƥꥹ�Ȥ��ɲä��� */
156   instance = ColorGCInstance_Create(list->disp, color);
157 
158   if (list->studying_flag)
159     ObjList_InsertObjToStart(list->list, instance,
160 			     (ObjDestructor)ColorGCInstance_Destroy);
161   else
162     ObjList_InsertObjToPrev(list->list, current, instance,
163 			    (ObjDestructor)ColorGCInstance_Destroy);
164 
165 #ifdef HIT_LIST
166   fprintf(stderr, "A");
167 #endif
168 
169   return (instance);
170 }
171 
172 /*===========================================================================*/
173 /* ColorGCCache ��Ϣ                                                         */
174 /*===========================================================================*/
175 
176 /*---------------------------------------------------------------------------*/
177 /* ����å����ѥХåե�                                                      */
178 /*---------------------------------------------------------------------------*/
179 
ColorGCCacheBuffer_Create(ColorGCInstance instance)180 static ColorGCCacheBuffer ColorGCCacheBuffer_Create(ColorGCInstance instance)
181 {
182   ColorGCCacheBuffer buffer;
183   buffer = (ColorGCCacheBuffer)malloc(sizeof(_ColorGCCacheBuffer));
184   if (buffer == NULL) Error("ColorGCCacheBuffer_Create",
185 			    "Cannot allocate memory.");
186   buffer->instance = instance;
187   return (buffer);
188 }
189 
ColorGCCacheBuffer_Destroy(ColorGCCacheBuffer buffer)190 static ColorGCCacheBuffer ColorGCCacheBuffer_Destroy(ColorGCCacheBuffer buffer)
191 {
192   if (buffer == NULL) return (NULL);
193   free(buffer);
194   return (NULL);
195 }
196 
197 /*---------------------------------------------------------------------------*/
198 /* ����å���                                                                */
199 /*---------------------------------------------------------------------------*/
200 
ColorGCCache_Create(ColorGCList color_gc_list,int size)201 static ColorGCCache ColorGCCache_Create(ColorGCList color_gc_list, int size)
202 {
203   ColorGCCache cache;
204 
205   cache = (ColorGCCache)malloc(sizeof(_ColorGCCache));
206   if (cache == NULL) Error("ColorGCCache_Create",
207 			    "Cannot allocate memory.");
208 
209   cache->size = size;
210   cache->color_gc_list = color_gc_list;
211   cache->buffer_list = ObjList_Create();
212 
213   return (cache);
214 }
215 
ColorGCCache_Destroy(ColorGCCache cache)216 static ColorGCCache ColorGCCache_Destroy(ColorGCCache cache)
217 {
218   if (cache == NULL) return (NULL);
219 
220   if (cache->buffer_list) ObjList_Destroy(cache->buffer_list);
221   free(cache);
222 
223   return (NULL);
224 }
225 
226 /*---------------------------------------------------------------------------*/
227 /* ����å��夫�� ColorGCInstance �����롥                                   */
228 /*---------------------------------------------------------------------------*/
229 
ColorGCCache_GetColorGCInstance(ColorGCCache cache,XColor color)230 static ColorGCInstance ColorGCCache_GetColorGCInstance(ColorGCCache cache,
231 						       XColor color)
232 {
233   ObjListData current;
234   ColorGCCacheBuffer buffer;
235   ColorGCInstance instance;
236   int cmp;
237 
238   /* ����å��������� */
239   for (current = ObjList_GetStart(cache->buffer_list);
240        !ObjList_IsEndEdge(cache->buffer_list, current);
241        current = ObjListData_GetNext(current)) {
242 
243     buffer = (ColorGCCacheBuffer)ObjListData_GetObj(current);
244     cmp = ColorGCInstance_CmpToColor(buffer->instance, color);
245 
246     if (cmp == 0) { /* ����å�����˸��Ĥ������ */
247 #ifdef HIT_CACHE
248       fprintf(stderr, "H"); /* Hit! */
249 #endif
250       ObjList_MoveObjToStart(cache->buffer_list, current);
251       return (buffer->instance);
252     }
253   }
254 
255   /* ����å�����˸��Ĥ����ʤ��ä���� */
256 
257   /* �ꥹ�Ȥ��鸡������ */
258   instance = ColorGCList_GetColorGCInstance(cache->color_gc_list, color);
259 
260   /* ����å�����ɲä��� */
261   if (ObjList_GetLength(cache->buffer_list) < cache->size) {
262     buffer = ColorGCCacheBuffer_Create(instance);
263     ObjList_InsertObjToStart(cache->buffer_list, buffer,
264 			     (ObjDestructor)ColorGCCacheBuffer_Destroy);
265   } else {
266     current = ObjList_GetEnd(cache->buffer_list);
267     buffer = (ColorGCCacheBuffer)ObjListData_GetObj(current);
268     buffer->instance = instance;
269     ObjList_MoveObjToStart(cache->buffer_list, current);
270   }
271 
272 #ifdef HIT_CACHE
273   fprintf(stderr, "F"); /* False! */
274 #endif
275 
276   return (instance);
277 }
278 
279 /*===========================================================================*/
280 /* ColorGCHash ��Ϣ                                                          */
281 /*===========================================================================*/
282 
ColorGCHash_Create(Disp disp,int studying_flag,int cache_flag,int cache_size,int hash_number)283 static ColorGCHash ColorGCHash_Create(Disp disp,
284 				      int studying_flag,
285 				      int cache_flag,
286 				      int cache_size,
287 				      int hash_number)
288 {
289   ColorGCHash hash;
290   int i;
291 
292   hash = (ColorGCHash)malloc(sizeof(_ColorGCHash));
293   if (hash == NULL) Error("ColorGCHash_Create", "Cannot allocate memory.");
294 
295   hash->number = hash_number;
296   hash->cache_flag = cache_flag;
297 
298   if (cache_flag) {
299     hash->color_gc_cache =
300       (ColorGCCache *)malloc(sizeof(ColorGCCache) * hash->number);
301     if (hash->color_gc_cache == NULL) Error("ColorGCHash_Create",
302 					    "Cannot allocate memory.");
303   } else {
304     hash->color_gc_cache = NULL;
305   }
306 
307   hash->color_gc_list =
308     (ColorGCList *)malloc(sizeof(ColorGCList) * hash->number);
309   if (hash->color_gc_list == NULL) Error("ColorGCHash_Create",
310 					 "Cannot allocate memory.");
311 
312   for (i = 0; i < hash->number; i++) {
313     hash->color_gc_list[i] = ColorGCList_Create(disp, studying_flag);
314     if (cache_flag) {
315       hash->color_gc_cache[i] = ColorGCCache_Create(hash->color_gc_list[i],
316 						    cache_size);
317     }
318   }
319 
320   return (hash);
321 }
322 
ColorGCHash_Destroy(ColorGCHash hash)323 static ColorGCHash ColorGCHash_Destroy(ColorGCHash hash)
324 {
325   int i;
326 
327   if (hash == NULL) return (NULL);
328 
329   if (hash->color_gc_cache) {
330     for (i = 0; i < hash->number; i++) {
331       if (hash->color_gc_cache[i])
332 	ColorGCCache_Destroy(hash->color_gc_cache[i]);
333     }
334     free(hash->color_gc_cache);
335   }
336 
337   if (hash->color_gc_list) {
338     for (i = 0; i < hash->number; i++) {
339       if (hash->color_gc_list[i])
340 	ColorGCList_Destroy(hash->color_gc_list[i]);
341     }
342     free(hash->color_gc_list);
343   }
344 
345   free(hash);
346 
347   return (NULL);
348 }
349 
ColorGCHash_OutputHashStatus(ColorGCHash hash)350 static void ColorGCHash_OutputHashStatus(ColorGCHash hash)
351 {
352   int i;
353   printf ("\nHash :");
354   for (i = 0; i < hash->number; i++) {
355     printf("%d ", ObjList_GetLength(hash->color_gc_list[i]->list));
356   }
357   printf ("\n");
358 }
359 
360 /*---------------------------------------------------------------------------*/
361 /* �ϥå���ؿ�                                                              */
362 /* ���������Ƥ����硤����ΰ��֤������ˤ˻��Ѥ��줿�ꤷ�ʤ��褦����ա�  */
363 /* (���Ȥ��С�                                                               */
364 /*  ((int)color.red*3 + (int)color.green*2 + (int)color.blue) % hash->number */
365 /*  �Τ褦�ʥϥå���ؿ����ȡ�16��Ĵ�˸��������Ȥ��ˡ�4096 ���ܿ��ΰ��֤���  */
366 /*  ���ˤ˻��Ѥ���Ƥ��ޤ���                                                 */
367 /*---------------------------------------------------------------------------*/
368 
HashFunction(ColorGCHash hash,XColor color)369 static int HashFunction(ColorGCHash hash, XColor color)
370 {
371   return ((
372 	   (((int)color.red)   / 3000) * 11 +
373 	   (((int)color.green) % 3000) / 7 +
374 	   (((int)color.blue)  % 1000) / 3
375 	   ) % hash->number);
376 }
377 
378 /*---------------------------------------------------------------------------*/
379 /* �ϥå��夫�� ColorGCInstance �����롥                                     */
380 /*---------------------------------------------------------------------------*/
381 
ColorGCHash_GetColorGCInstance(ColorGCHash hash,XColor color)382 static ColorGCInstance ColorGCHash_GetColorGCInstance(ColorGCHash hash,
383 						      XColor color)
384 {
385   int n;
386 
387   n = HashFunction(hash, color);
388 
389   if (hash->cache_flag)
390     return (ColorGCCache_GetColorGCInstance(hash->color_gc_cache[n], color));
391   else
392     return (ColorGCList_GetColorGCInstance(hash->color_gc_list[n], color));
393 }
394 
395 /*===========================================================================*/
396 /* ColorName ��Ϣ                                                            */
397 /*===========================================================================*/
398 
399 /*---------------------------------------------------------------------------*/
400 /* ���֥������Ȥ�����                                                        */
401 /*---------------------------------------------------------------------------*/
402 
ColorName_Create(Disp disp,char * name)403 static ColorName ColorName_Create(Disp disp, char * name)
404 {
405   ColorName color_name;
406 
407   color_name = (ColorName)malloc(sizeof(_ColorName));
408   if (color_name == NULL) Error("ColorName_Create", "Cannot allocate memory");
409 
410   color_name->name = malloc(sizeof(char) * (StringLen(name) + 1));
411   if (color_name->name == NULL)
412     Error("ColorName_Create", "Cannot allocate memory");
413 
414   StringCpy(color_name->name, name);
415 
416   XParseColor(Disp_GetDisplay(disp), Disp_GetColormap(disp),
417 	      color_name->name, &(color_name->color));
418 
419   return (color_name);
420 }
421 
422 /*---------------------------------------------------------------------------*/
423 /* ���֥������Ȥκ��                                                        */
424 /*---------------------------------------------------------------------------*/
425 
ColorName_Destroy(ColorName color_name)426 static ColorName ColorName_Destroy(ColorName color_name)
427 {
428   if (color_name == NULL) return (NULL);
429   if (color_name->name) free(color_name->name);
430   free(color_name);
431   return (NULL);
432 }
433 
434 /*---------------------------------------------------------------------------*/
435 /* ���֥������Ȥ�����                                                        */
436 /*---------------------------------------------------------------------------*/
437 
ColorNameList_Create(Disp disp)438 static ColorNameList ColorNameList_Create(Disp disp)
439 {
440   ColorNameList list;
441 
442   list = (ColorNameList)malloc(sizeof(_ColorNameList));
443   if (list == NULL) Error("ColorNameList_Create", "Cannot allocate memory");
444 
445   list->disp = disp;
446   list->list = ObjList_Create();
447 
448   return (list);
449 }
450 
451 /*---------------------------------------------------------------------------*/
452 /* ���֥������Ȥκ��                                                        */
453 /*---------------------------------------------------------------------------*/
454 
ColorNameList_Destroy(ColorNameList list)455 static ColorNameList ColorNameList_Destroy(ColorNameList list)
456 {
457   if (list == NULL) return (NULL);
458   if (list->list) ObjList_Destroy(list->list);
459   free(list);
460   return (NULL);
461 }
462 
463 /*---------------------------------------------------------------------------*/
464 /* ʸ�����Ϳ����줿��̾���顤RGB�ͤ������롥                             */
465 /*---------------------------------------------------------------------------*/
466 
ColorNameList_GetColor(ColorNameList list,char * name)467 static XColor ColorNameList_GetColor(ColorNameList list, char * name)
468 {
469   ObjListData current;
470   ColorName color_name;
471 
472   for (current = ObjList_GetStart(list->list);
473        !ObjList_IsEndEdge(list->list, current);
474        current = ObjListData_GetNext(current)) {
475     color_name = (ColorName)ObjListData_GetObj(current);
476     if (StringEqual(color_name->name, name)) {
477       ObjList_MoveObjToStart(list->list, current);
478       return (color_name->color);
479     }
480   }
481 
482   color_name = ColorName_Create(list->disp, name);
483   if (color_name == NULL)
484     Error("ColorNameList_GetColor", "Cannot create ColorName");
485 
486   ObjList_InsertObjToStart(list->list, color_name,
487 			   (ObjDestructor)ColorName_Destroy);
488 
489   return (color_name->color);
490 }
491 
492 /*===========================================================================*/
493 /* ColorGC ��Ϣ                                                              */
494 /*===========================================================================*/
495 
496 /*---------------------------------------------------------------------------*/
497 /* ���֥������Ȥ�����                                                        */
498 /*---------------------------------------------------------------------------*/
499 
ColorGC_Create(ColorGCDatabase database,XColor color)500 ColorGC ColorGC_Create(ColorGCDatabase database, XColor color)
501 {
502   ColorGC color_gc;
503 
504   color_gc = (ColorGC)malloc(sizeof(_ColorGC));
505 
506   /* �ϥå��夫�鿧��GC���� */
507   color_gc->instance = ColorGCHash_GetColorGCInstance(database->hash, color);
508 
509   return (color_gc);
510 }
511 
ColorGC_CreateFromColorGC(ColorGCDatabase database,ColorGC c)512 ColorGC ColorGC_CreateFromColorGC(ColorGCDatabase database, ColorGC c)
513 {
514   ColorGC color_gc;
515 
516   color_gc = (ColorGC)malloc(sizeof(_ColorGC));
517 
518   color_gc->instance = c->instance;
519 
520   return (color_gc);
521 }
522 
523 /*---------------------------------------------------------------------------*/
524 /* RGB �ͤ����������롥                                                      */
525 /*---------------------------------------------------------------------------*/
526 
ColorGC_CreateFromRGB(ColorGCDatabase database,int red,int green,int blue)527 ColorGC ColorGC_CreateFromRGB(ColorGCDatabase database,
528 			      int red, int green, int blue)
529 {
530   XColor color;
531 
532   color.red   = red;
533   color.green = green;
534   color.blue  = blue;
535   color.flags = DoRed | DoGreen | DoBlue;
536 
537   return (ColorGC_Create(database, color));
538 }
539 
540 /*---------------------------------------------------------------------------*/
541 /* ���֥������Ȥκ��                                                        */
542 /*---------------------------------------------------------------------------*/
543 
ColorGC_Destroy(ColorGC color_gc)544 ColorGC ColorGC_Destroy(ColorGC color_gc)
545 {
546   if (!color_gc) return (NULL);
547 
548   free(color_gc);
549 
550   return (NULL);
551 }
552 
553 /*===========================================================================*/
554 /* ʸ�����ɤ߹����Ѵؿ�                                                      */
555 /*===========================================================================*/
556 
557 /*---------------------------------------------------------------------------*/
558 /* ��������Τ���Ρ������Ѥδؿ���                                          */
559 /* ��������ȡ����ζ�ͭ�����ʤߡ�����å����θ��̤��礭���ʤ롥            */
560 /* ����Ƥ��ɸ������ʤ��ȡ�������ͭ�Ǥ��ʤ��Τǡ�̵�̤�¿���ʤ롥            */
561 /*---------------------------------------------------------------------------*/
562 
DecreaseColor(XColor color,int gradation)563 static XColor DecreaseColor(XColor color, int gradation)
564 {
565   int div = RGB_MAX_VALUE / gradation + 1;
566 
567   color.red   /= div;
568   if (color.red   >= gradation - 1) color.red   = RGB_MAX_VALUE;
569   else color.red   *= div;
570 
571   color.green /= div;
572   if (color.green >= gradation - 1) color.green = RGB_MAX_VALUE;
573   else color.green *= div;
574 
575   color.blue  /= div;
576   if (color.blue  >= gradation - 1) color.blue  = RGB_MAX_VALUE;
577   else color.blue  *= div;
578 
579   return (color);
580 }
581 
582 /*---------------------------------------------------------------------------*/
583 /* ����GC�Υǡ����١������� name ��Ϳ����줿̾���ο��������롥            */
584 /*---------------------------------------------------------------------------*/
585 
ColorGC_CreateFromCharacters(ColorGCDatabase database,char * name)586 ColorGC ColorGC_CreateFromCharacters(ColorGCDatabase database, char * name)
587 {
588   XColor color;
589 
590   if (!StringCmp(name, "none") ||
591       !StringCmp(name, "None") ||
592       !StringCmp(name, "NONE") ||
593       !StringCmp(name, "back") ||
594       !StringCmp(name, "Back") ||
595       !StringCmp(name, "BACK") ||
596       !StringCmp(name, "background") ||
597       !StringCmp(name, "Background") ||
598       !StringCmp(name, "BACKGROUND")) {
599     if (database->background_color_gc)
600       return (ColorGC_CreateFromColorGC(database,
601 					database->background_color_gc));
602     else
603 #if 1
604       name = "none";
605 #else
606       name = "black";
607 #endif
608   }
609 
610   color = ColorNameList_GetColor(database->color_name_list, name);
611 
612   /* ��������Τ��ᡤ�������� */
613   color = DecreaseColor(color, database->gradation);
614 
615   return (ColorGC_Create(database, color));
616 }
617 
618 /*---------------------------------------------------------------------------*/
619 /* XColor ��¤�Τμ���                                                       */
620 /*---------------------------------------------------------------------------*/
621 
ColorGC_GetColor(ColorGC color_gc)622 XColor ColorGC_GetColor(ColorGC color_gc)
623 {
624   return (color_gc->instance->color);
625 }
626 
627 /*---------------------------------------------------------------------------*/
628 /* �ԥ������ͤμ���                                                          */
629 /*---------------------------------------------------------------------------*/
630 
ColorGC_GetPixel(ColorGC color_gc)631 unsigned long ColorGC_GetPixel(ColorGC color_gc)
632 {
633   return (color_gc->instance->color.pixel);
634 }
635 
636 /*---------------------------------------------------------------------------*/
637 /* GC �μ���                                                                 */
638 /*---------------------------------------------------------------------------*/
639 
ColorGC_GetGC(ColorGC color_gc)640 GC ColorGC_GetGC(ColorGC color_gc)
641 {
642   return (color_gc->instance->gc);
643 }
644 
645 /*---------------------------------------------------------------------------*/
646 /* �������뤵�μ���                                                          */
647 /*---------------------------------------------------------------------------*/
648 
GetBrightness(XColor color)649 int GetBrightness(XColor color)
650 {
651   long int br;
652 
653 #if 0
654   br = color.red > color.green ? color.red : color.green;
655   br = br > color.blue ? br : color.blue;
656   br = br * 100 / RGB_MAX_VALUE;
657 #else
658   br = color.red + color.green + color.blue;
659   br = br * 100 / RGB_MAX_VALUE;
660 #endif
661 
662   if (br > 100) br = 100;
663 
664   return ((int)br);
665 }
666 
667 /*===========================================================================*/
668 /* GC �Υꥹ�Ȥκ���                                                         */
669 /*===========================================================================*/
670 
671 /*---------------------------------------------------------------------------*/
672 /* ñ����ɤ߹����ѡ�(Stream �饤�֥�����)                                 */
673 /*---------------------------------------------------------------------------*/
674 
GetWord(Stream stream)675 static char * GetWord(Stream stream)
676 {
677   char * word;
678   word = Stream_GetWord(stream, NULL, 0,
679 			"",     /* ����ʸ�����ڤ�ʬ���� */
680 			" \t",  /* ����ʸ���Ǥ��ڤ�ʬ���� */
681 			"",     /* �����ȹԤ���Ƭʸ�� '#' �ʤ� */
682 			"\n",   /* ����ʸ�� '\n' �ʤ� */
683 			"",     /* ������ʸ�� '\"' �ʤ� */
684 			"",     /* ʸ������Ƭ���ɤߤȤФ�ʸ�� */
685 			""      /* ʸ�����������ɤߤȤФ�ʸ�� */
686 			);
687   return (word);
688 }
689 
690 /*---------------------------------------------------------------------------*/
691 /* color1 �� color2 ��Ϳ����줿������ֿ���׻�����                         */
692 /* per �ǥѡ�����ơ�����Ϳ���롥                                            */
693 /* 0% �ΤȤ���color1�ˤʤ롥100%�ΤȤ���color2 �ˤʤ�                        */
694 /* 0% ̤������100%����礭�� per �ΤȤ��ˤϡ�flags ���Ф�0�����ꤷ��       */
695 /* �֤�������ʳ��ΤȤ��ϡ�flags ���Ф� DoRed | DoGreen | DoBlue �ˤʤ롥  */
696 /*---------------------------------------------------------------------------*/
697 
CalMiddleColor(XColor color1,XColor color2,int per)698 static XColor CalMiddleColor(XColor color1, XColor color2, int per)
699 {
700   XColor color;
701 
702   color.pixel = 0;
703 
704   if ((per < 0) || (per > 100)) {
705     color.flags = 0;
706     color.red   = 0;
707     color.green = 0;
708     color.blue  = 0;
709     return (color);
710   }
711 
712   /* ��ֿ��η׻� */
713   color.flags = DoRed | DoGreen | DoBlue;
714   color.red   =
715     color1.red   + (int)(((color2.red   - color1.red  ) * per + 50) / 100);
716   color.green =
717     color1.green + (int)(((color2.green - color1.green) * per + 50) / 100);
718   color.blue  =
719     color1.blue  + (int)(((color2.blue  - color1.blue ) * per + 50) / 100);
720 
721   return (color);
722 }
723 
724 /*---------------------------------------------------------------------------*/
725 /* GC �Υꥹ�Ȥκ���                                                         */
726 /* "red" "black" 10                                                          */
727 /* �Τ褦�ʰ������顤GC�Υꥹ�Ȥ����������֤���                              */
728 /*---------------------------------------------------------------------------*/
729 
CreateGCList(ColorGCDatabase database,XColor start_color,XColor end_color,int length)730 static ObjList CreateGCList(ColorGCDatabase database,
731 			    XColor start_color, XColor end_color, int length)
732 {
733   ColorGC color_gc;
734   ObjList gc_list;
735   XColor middle_color;
736   int i, per;
737 
738   gc_list = ObjList_Create();
739 
740   for (i = 0; i < length; i++) {
741 
742     if (length == 1) per = 100;
743     else per = i * 100 / (length - 1) ;
744 
745     middle_color = CalMiddleColor(start_color, end_color, per);
746     /* ��������Τ��ᡤ�������� */
747     middle_color = DecreaseColor(middle_color, database->gradation);
748 
749     color_gc = ColorGC_Create(database, middle_color);
750 
751     ObjList_InsertObjToEnd(gc_list, color_gc, (ObjDestructor)ColorGC_Destroy);
752   }
753 
754   return (gc_list);
755 }
756 
757 /*---------------------------------------------------------------------------*/
758 /* GC �Υꥹ�Ȥκ���                                                         */
759 /* �ǡ���ʸ������ ColorGC �Υꥹ�Ȥ���������֤���                         */
760 /* �ǡ���ʸ����Υե����ޥåȤϰʲ��ΤȤ��ꡥ                                */
761 /* "[�������ȥ��顼1] [����ɥ��顼1] [Ĺ��1] [�������ȥ��顼2] ...\0"       */
762 /* ��) "red green 10 green blue 20 blue none 10\0"                           */
763 /*---------------------------------------------------------------------------*/
764 
CreateColorGCListFromCharacters(ColorGCDatabase database,char * data,int after_image_length,int fine,int color_length_mag)765 ObjList CreateColorGCListFromCharacters(ColorGCDatabase database,
766 					char * data,
767 					int after_image_length,
768 					int fine,
769 					int color_length_mag)
770 {
771   Stream stream;
772   char * start;
773   char * end;
774   char * len;
775   int length;
776   int length2;
777   ObjList gc_list;
778   ObjList list;
779   ColorGC start_color_gc;
780   ColorGC end_color_gc;
781   XColor middle_color;
782   int i, per;
783   int br;
784 
785   list = ObjList_Create();
786 
787   if (!data) return (list);
788 
789   stream = Stream_CreateFromCharacters(data);
790   if (!stream) return (list);
791 
792   while ((start = GetWord(stream)) != NULL) {
793     end = GetWord(stream); if (end == NULL) end = "none";
794     len = GetWord(stream); if (len == NULL) len = "1";
795 
796     start_color_gc = ColorGC_CreateFromCharacters(database, start);
797     end_color_gc   = ColorGC_CreateFromCharacters(database, end  );
798     length = (atoi(len) * color_length_mag + 50) / 100;
799     if (length > 0) {
800       length = (length * fine + 50) / 100;
801 #if 0
802       if (length < 1) length = 1;
803 #endif
804     }
805 
806     for (i = 0; i < length; i++) {
807 
808       if (length == 1) per = 100;
809       else per = i * 100 / (length - 1) ;
810 
811       middle_color = CalMiddleColor(start_color_gc->instance->color,
812 				    end_color_gc->instance->color, per);
813 #if 0 /* ������ɬ�פʤ� */
814       /* ��������Τ��ᡤ�������� */
815       middle_color = DecreaseColor(middle_color, database->gradation);
816 #endif
817 
818       br = GetBrightness(middle_color);
819 
820       length2 = after_image_length;
821       if (length2 > 0) {
822 	length2 = (length2 * fine + 50) / 100;
823 #if 0
824 	if (length2 < 1) length2 = 1;
825 #endif
826       }
827       length2 = (length2 * br + 50) / 100;
828 
829       gc_list = CreateGCList(database, middle_color,
830 			     database->background_color_gc->instance->color,
831 			     length2);
832 
833       ObjList_InsertObjToEnd(list, gc_list, (ObjDestructor)ObjList_Destroy);
834     }
835 
836     ColorGC_Destroy(start_color_gc);
837     ColorGC_Destroy(end_color_gc);
838 
839     if (start) free(start);
840     if (end)   free(end);
841     if (len)   free(len);
842   }
843 
844   Stream_Destroy(stream);
845 
846   return (list);
847 }
848 
849 /*===========================================================================*/
850 /* GC �Υǡ����١���                                                         */
851 /*===========================================================================*/
852 
ColorGCDatabase_Create(Disp disp,int studying_flag,int cache_flag,int cache_size,int hash_number,char * background,int gradation)853 ColorGCDatabase ColorGCDatabase_Create(Disp disp,
854 				       int studying_flag,
855 				       int cache_flag,
856 				       int cache_size,
857 				       int hash_number,
858 				       char * background,
859 				       int gradation)
860 {
861   ColorGCDatabase database;
862 
863   database = (ColorGCDatabase)malloc(sizeof(_ColorGCDatabase));
864   if (database == NULL) Error("ColorGCDatabase_Create",
865 			      "Cannot allocate memory.");
866 
867   database->disp = disp;
868   database->gradation = gradation;
869 
870   database->hash = ColorGCHash_Create(database->disp,
871 				      studying_flag,
872 				      cache_flag,
873 				      cache_size,
874 				      hash_number);
875   database->color_name_list = ColorNameList_Create(database->disp);
876 
877   /* background �� "none" �ξ��ˤ�����ư���褦�ˡ�               */
878   /* ColorGC_CreateFromCharacters()��ƤӽФ����ˡ�NULL �ǽ�������롥 */
879   database->background_color_gc = NULL;
880 
881   /* ������ database ������ƸƤӽФ��Τǡ�ɬ���Ǹ���֤����� */
882   database->background_color_gc =
883     ColorGC_CreateFromCharacters(database, background);
884   /* ����ľ��� return() �����褦�ˤ��뤳�� */
885 
886   return (database);
887 }
888 
ColorGCDatabase_Destroy(ColorGCDatabase database)889 ColorGCDatabase ColorGCDatabase_Destroy(ColorGCDatabase database)
890 {
891   if (database == NULL) return (NULL);
892 
893   if (database->background_color_gc)
894     ColorGC_Destroy(database->background_color_gc);
895 
896   if (database->color_name_list)
897     ColorNameList_Destroy(database->color_name_list);
898   if (database->hash) ColorGCHash_Destroy(database->hash);
899   free(database);
900 
901   return (NULL);
902 }
903 
ColorGCDatabase_GetBackgroundColorGC(ColorGCDatabase database)904 ColorGC ColorGCDatabase_GetBackgroundColorGC(ColorGCDatabase database)
905 {
906   return (database->background_color_gc);
907 }
908 
909 /*---------------------------------------------------------------------------*/
910 /* ���塼�˥���                                                            */
911 /*---------------------------------------------------------------------------*/
912 
ColorGCDatabase_OutputHashStatus(ColorGCDatabase database)913 void ColorGCDatabase_OutputHashStatus(ColorGCDatabase database)
914 {
915   ColorGCHash_OutputHashStatus(database->hash);
916 }
917 
918 /*****************************************************************************/
919 /* End of File                                                               */
920 /*****************************************************************************/
921