summaryrefslogtreecommitdiff
path: root/Tools/pynche/ColorDB.py
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>1999-04-26 23:17:16 +0000
committerBarry Warsaw <barry@python.org>1999-04-26 23:17:16 +0000
commit0604d723183bee9ca18920708ec7fd44fbc4c63b (patch)
treefdffddafc755782e374fe2b7a2efb0ea6443547f /Tools/pynche/ColorDB.py
parent0ec1493d0b0bdbef561c819c560a6703256c88a1 (diff)
downloadcpython-git-0604d723183bee9ca18920708ec7fd44fbc4c63b.tar.gz
Lots of changes to support loading alternative color name database.
You can switch database by just loading the new one; the list window and nearest colors adapt to the new database. Some reorganizing of code. Also, the name of the database file is stored in the ~/.pynche pickle. If it can't be loaded, fallbacks are used.
Diffstat (limited to 'Tools/pynche/ColorDB.py')
-rw-r--r--Tools/pynche/ColorDB.py101
1 files changed, 74 insertions, 27 deletions
diff --git a/Tools/pynche/ColorDB.py b/Tools/pynche/ColorDB.py
index 863688a5c7..87c4406086 100644
--- a/Tools/pynche/ColorDB.py
+++ b/Tools/pynche/ColorDB.py
@@ -35,7 +35,9 @@ DEFAULT_DB = None
# generic class
class ColorDB:
- def __init__(self, fp, lineno):
+ def __init__(self, fp):
+ lineno = 2
+ self.__name = fp.name
# Maintain several dictionaries for indexing into the color database.
# Note that while Tk supports RGB intensities of 4, 8, 12, or 16 bits,
# for now we only support 8 bit intensities. At least on OpenWindows,
@@ -54,6 +56,7 @@ class ColorDB:
if not line:
break
# get this compiled regular expression from derived class
+## print '%3d: %s' % (lineno, line[:-1])
mo = self._re.match(line)
if not mo:
sys.stderr.write('Error in %s, line %d\n' % (fp.name, lineno))
@@ -62,9 +65,10 @@ class ColorDB:
#
# extract the red, green, blue, and name
#
- red, green, blue = map(int, mo.group('red', 'green', 'blue'))
- name = mo.group('name')
+ red, green, blue = self._extractrgb(mo)
+ name = self._extractname(mo)
keyname = string.lower(name)
+## print keyname, '(%d, %d, %d)' % (red, green, blue)
#
# TBD: for now the `name' is just the first named color with the
# rgb values we find. Later, we might want to make the two word
@@ -81,13 +85,25 @@ class ColorDB:
self.__byname[keyname] = key
lineno = lineno + 1
+ # override in derived classes
+ def _extractrgb(self, mo):
+ return map(int, mo.group('red', 'green', 'blue'))
+
+ def _extractname(self, mo):
+ return mo.group('name')
+
+ def filename(self):
+ return self.__name
+
def find_byrgb(self, rgbtuple):
+ """Return name for rgbtuple"""
try:
return self.__byrgb[rgbtuple]
except KeyError:
raise BadColor(rgbtuple)
def find_byname(self, name):
+ """Return (red, green, blue) for name"""
name = string.lower(name)
try:
return self.__byname[name]
@@ -95,9 +111,10 @@ class ColorDB:
raise BadColor(name)
def nearest(self, red, green, blue):
- # TBD: use Voronoi diagrams, Delaunay triangulation, or octree for
- # speeding up the locating of nearest point. Exhaustive search is
- # inefficient, but may be fast enough.
+ """Return the name of color nearest (red, green, blue)"""
+ # TBD: should we use Voronoi diagrams, Delaunay triangulation, or
+ # octree for speeding up the locating of nearest point? Exhaustive
+ # search is inefficient, but seems fast enough.
nearest = -1
nearest_name = ''
for name, aliases in self.__byrgb.values():
@@ -133,7 +150,29 @@ class ColorDB:
class RGBColorDB(ColorDB):
_re = re.compile(
- '\s*(?P<red>\d+)\s+(?P<green>\d+)\s+(?P<blue>\d+)\s+(?P<name>.*)')
+ '\s*(?P<red>\d+)\s+(?P<green>\d+)\s+(?P<blue>\d+)\s+(?P<name>.*)')
+
+
+class HTML40DB(ColorDB):
+ _re = re.compile('(?P<name>\S+)\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
+
+ def _extractrgb(self, mo):
+ return rrggbb_to_triplet(mo.group('hexrgb'))
+
+class LightlinkDB(HTML40DB):
+ _re = re.compile('(?P<name>(.+))\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
+
+ def _extractname(self, mo):
+ return string.strip(mo.group('name'))
+
+class WebsafeDB(ColorDB):
+ _re = re.compile('(?P<hexrgb>#[0-9a-fA-F]{6})')
+
+ def _extractrgb(self, mo):
+ return rrggbb_to_triplet(mo.group('hexrgb'))
+
+ def _extractname(self, mo):
+ return string.upper(mo.group('hexrgb'))
@@ -141,30 +180,36 @@ class RGBColorDB(ColorDB):
# expression, SCANLINES is the number of header lines to scan, and CLASS is
# the class to instantiate if a match is found
-X_RGB_TXT = re.compile('XConsortium'), 1, RGBColorDB
+FILETYPES = [
+ (re.compile('XConsortium'), RGBColorDB),
+ (re.compile('HTML'), HTML40DB),
+ (re.compile('lightlink'), LightlinkDB),
+ (re.compile('Websafe'), WebsafeDB),
+ ]
-def get_colordb(file, filetype=X_RGB_TXT):
+def get_colordb(file, filetype=None):
colordb = None
- fp = None
- typere, scanlines, class_ = filetype
+ fp = open(file)
try:
- try:
- lineno = 0
- fp = open(file)
- while lineno < scanlines:
- line = fp.readline()
- if not line:
- break
- mo = typere.search(line)
- if mo:
- colordb = class_(fp, lineno)
- break
- lineno = lineno + 1
- except IOError:
- pass
+ line = fp.readline()
+ if not line:
+ return None
+ # try to determine the type of RGB file it is
+ if filetype is None:
+ filetypes = FILETYPES
+ else:
+ filetypes = [filetype]
+ for typere, class_ in filetypes:
+ mo = typere.search(line)
+ if mo:
+ break
+ else:
+ # no matching type
+ return None
+ # we know the type and the class to grok the type, so suck it in
+ colordb = class_(fp)
finally:
- if fp:
- fp.close()
+ fp.close()
# save a global copy
global DEFAULT_DB
DEFAULT_DB = colordb
@@ -175,6 +220,7 @@ def get_colordb(file, filetype=X_RGB_TXT):
_namedict = {}
def rrggbb_to_triplet(color, atoi=string.atoi):
"""Converts a #rrggbb color to the tuple (red, green, blue)."""
+ global _namedict
rgbtuple = _namedict.get(color)
if rgbtuple is None:
if color[0] <> '#':
@@ -190,6 +236,7 @@ def rrggbb_to_triplet(color, atoi=string.atoi):
_tripdict = {}
def triplet_to_rrggbb(rgbtuple):
"""Converts a (red, green, blue) tuple to #rrggbb."""
+ global _tripdict
hexname = _tripdict.get(rgbtuple)
if hexname is None:
hexname = '#%02x%02x%02x' % rgbtuple