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