source: trunk/gui/scripts/color.tcl @ 856

Last change on this file since 856 was 115, checked in by mmc, 19 years ago

Updated all copyright notices.

File size: 5.2 KB
Line 
1# ----------------------------------------------------------------------
2#  UTILITY: color
3#
4#  This file contains various utility functions for manipulating
5#  color values.
6# ======================================================================
7#  AUTHOR:  Michael McLennan, Purdue University
8#  Copyright (c) 2004-2005  Purdue Research Foundation
9#
10#  See the file "license.terms" for information on usage and
11#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12# ======================================================================
13
14namespace eval Rappture::color { # forward declaration }
15
16# ---------------------------------------------------------------------
17# USAGE: brightness <color> <fraction>
18#
19# Used to brighten or dim a Tk <color> value by some +/- <fraction> in
20# the range 0-1.  Returns another color in the same hue, but with
21# different brighness.
22# ----------------------------------------------------------------------
23proc Rappture::color::brightness {color frac} {
24    foreach {h s v} [Rappture::color::RGBtoHSV $color] { break }
25    set v [expr {$v+$frac}]
26
27    # if frac overflows the value, pass changes along to saturation
28    if {$v < 0} {
29        set s [expr {$s+$v}]
30        if {$s < 0} { set s 0 }
31        set v 0
32    }
33    if {$v > 1} {
34        set s [expr {$s-($v-1)}]
35        if {$s < 0} { set s 0 }
36        set v 1
37    }
38
39    return [Rappture::color::HSVtoRGB $h $s $v]
40}
41
42# ---------------------------------------------------------------------
43# USAGE: brightness_min <color> <min>
44#
45# Used to make sure a color is not too dim.  If the value is less
46# than the <min>, then it is capped at that value.  That way, the
47# return color shows up against black.
48# ----------------------------------------------------------------------
49proc Rappture::color::brightness_min {color min} {
50    foreach {h s v} [Rappture::color::RGBtoHSV $color] { break }
51    if {$v < $min} {
52        set v $min
53    }
54    return [Rappture::color::HSVtoRGB $h $s $v]
55}
56
57# ---------------------------------------------------------------------
58# USAGE: brightness_max <color> <max>
59#
60# Used to make sure a color is not too dim.  If the value is less
61# than the <min>, then it is capped at that value.  That way, the
62# return color shows up against black.
63# ----------------------------------------------------------------------
64proc Rappture::color::brightness_max {color max} {
65    foreach {h s v} [Rappture::color::RGBtoHSV $color] { break }
66    if {$v > $max} {
67        set v $max
68    }
69    return [Rappture::color::HSVtoRGB $h $s $v]
70}
71
72# ---------------------------------------------------------------------
73# USAGE: RGBtoHSV <color>
74#
75# Used to convert a Tk <color> value to hue, saturation, value
76# components.  Returns a list of the form {h s v}.
77# ----------------------------------------------------------------------
78proc Rappture::color::RGBtoHSV {color} {
79    #
80    # If the colors are exhausted sometimes winfo can fail with a
81    # division by zero.  Catch it to avoid problems.
82    #
83    if { [catch {winfo rgb . $color} status] != 0 } {
84        set s 0
85        set v 0
86        set h 0
87        return [list $h $s $v]
88    }
89    foreach {r g b} $status {}
90    set min [expr {($r < $g) ? $r : $g}]
91    set min [expr {($b < $min) ? $b : $min}]
92    set max [expr {($r > $g) ? $r : $g}]
93    set max [expr {($b > $max) ? $b : $max}]
94
95    set v [expr {$max/65535.0}]
96
97    set delta [expr {$max-$min}]
98
99    if { $delta == 0 } {
100        # delta=0 => gray color
101        set s 0
102        set v [expr {$r/65535.0}]
103        set h 0
104        return [list $h $s $v]
105    }
106 
107    if {$max > 0} {
108        set s [expr {$delta/double($max)}]
109    } else {
110        # r=g=b=0  =>  s=0, v undefined
111        set s 0
112        set v 0
113        set h 0
114        return [list $h $s $v]
115    }
116
117    if {$r == $max} {
118        set h [expr {($g - $b)/double($delta)}]
119    } elseif {$g == $max} {
120        set h [expr {2 + ($b - $r)/double($delta)}]
121    } else {
122        set h [expr {4 + ($r - $g)/double($delta)}]
123    }
124    set h [expr {$h*1.04719756667}] ;# *60 degrees
125    if {$h < 0} {
126        set h [expr {$h+6.2831854}]
127    }
128    return [list $h $s $v]
129}
130
131# ---------------------------------------------------------------------
132# USAGE: HSVtoRGB <color>
133#
134# Used to convert hue, saturation, value for a color to its
135# equivalent RGB form.  Returns a prompt Tk color of the form
136# #RRGGBB.
137# ----------------------------------------------------------------------
138proc Rappture::color::HSVtoRGB {h s v} {
139    if {$s == 0} {
140        set v [expr round(255*$v)]
141        set r $v
142        set g $v
143        set b $v
144    } else {
145        if {$h >= 6.28318} {set h [expr $h-6.28318]}
146        set h [expr $h/1.0472]
147        set f [expr $h-floor($h)]
148        set p [expr round(255*$v*(1.0-$s))]
149        set q [expr round(255*$v*(1.0-$s*$f))]
150        set t [expr round(255*$v*(1.0-$s*(1.0-$f)))]
151        set v [expr round(255*$v)]
152
153        switch [expr int($h)] {
154            0 {set r $v; set g $t; set b $p}
155            1 {set r $q; set g $v; set b $p}
156            2 {set r $p; set g $v; set b $t}
157            3 {set r $p; set g $q; set b $v}
158            4 {set r $t; set g $p; set b $v}
159            5 {set r $v; set g $p; set b $q}
160        }
161    }
162    return [format "#%.2x%.2x%.2x" $r $g $b]
163}
Note: See TracBrowser for help on using the repository browser.