pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/0604d723183bee9ca18920708ec7fd44fbc4c63b

ylesheet" href="https://github.githubassets.com/assets/global-d18f184ea1a06a2c.css" /> Lots of changes to support loading alternative color name database. · python/cpython@0604d72 · GitHub
Skip to content

Commit 0604d72

Browse files
committed
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.
1 parent 0ec1493 commit 0604d72

6 files changed

Lines changed: 180 additions & 78 deletions

File tree

Tools/pynche/ChipViewer.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ def __init__(self,
4949
if releasecmd:
5050
self.__chip.bind('<ButtonRelease-1>', releasecmd)
5151

52-
def set_color(self, color):
52+
def set_color(self, color, colorname=None):
5353
self.__chip.config(background=color)
54-
self.__name.config(text=color)
54+
self.__name.config(text=colorname or color)
5555

5656
def get_color(self):
5757
return self.__chip['background']
@@ -83,25 +83,27 @@ def __init__(self, switchboard, master=None):
8383
releasecmd = self.__buttonrelease)
8484

8585
def update_yourself(self, red, green, blue):
86-
# TBD: should exactname default to X11 color name if their is an exact
87-
# match for the rgb triplet? Part of me says it's nice to see both
88-
# names for the color, the other part says that it's better to
89-
# feedback the exact match.
86+
# Selected always shows the #rrggbb name of the color, nearest always
87+
# shows the name of the nearest color in the database. TBD: should
88+
# an exact match be indicated in some way?
89+
#
90+
# Always use the #rrggbb style to actually set the color, since we may
91+
# not be using X color names (e.g. "web-safe" names)
92+
colordb = self.__sb.colordb()
9093
rgbtuple = (red, green, blue)
91-
try:
92-
allcolors = self.__sb.colordb().find_byrgb(rgbtuple)
93-
exactname = allcolors[0]
94-
except ColorDB.BadColor:
95-
exactname = ColorDB.triplet_to_rrggbb(rgbtuple)
96-
nearest = self.__sb.colordb().nearest(red, green, blue)
97-
self.__selected.set_color(exactname)
98-
self.__nearest.set_color(nearest)
94+
rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple)
95+
# find the nearest
96+
nearest = colordb.nearest(red, green, blue)
97+
nearest_tuple = colordb.find_byname(nearest)
98+
nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple)
99+
self.__selected.set_color(rrggbb)
100+
self.__nearest.set_color(nearest_rrggbb, nearest)
99101

100102
def __buttonpress(self, event=None):
101103
self.__nearest.press()
102104

103105
def __buttonrelease(self, event=None):
104106
self.__nearest.release()
105-
colorname = self.__nearest.get_color()
106-
red, green, blue = self.__sb.colordb().find_byname(colorname)
107+
rrggbb = self.__nearest.get_color()
108+
red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb)
107109
self.__sb.update_views(red, green, blue)

Tools/pynche/ColorDB.py

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ class BadColor(Exception):
3535

3636
# generic class
3737
class ColorDB:
38-
def __init__(self, fp, lineno):
38+
def __init__(self, fp):
39+
lineno = 2
40+
self.__name = fp.name
3941
# Maintain several dictionaries for indexing into the color database.
4042
# Note that while Tk supports RGB intensities of 4, 8, 12, or 16 bits,
4143
# for now we only support 8 bit intensities. At least on OpenWindows,
@@ -54,6 +56,7 @@ def __init__(self, fp, lineno):
5456
if not line:
5557
break
5658
# get this compiled regular expression from derived class
59+
## print '%3d: %s' % (lineno, line[:-1])
5760
mo = self._re.match(line)
5861
if not mo:
5962
sys.stderr.write('Error in %s, line %d\n' % (fp.name, lineno))
@@ -62,9 +65,10 @@ def __init__(self, fp, lineno):
6265
#
6366
# extract the red, green, blue, and name
6467
#
65-
red, green, blue = map(int, mo.group('red', 'green', 'blue'))
66-
name = mo.group('name')
68+
red, green, blue = self._extractrgb(mo)
69+
name = self._extractname(mo)
6770
keyname = string.lower(name)
71+
## print keyname, '(%d, %d, %d)' % (red, green, blue)
6872
#
6973
# TBD: for now the `name' is just the first named color with the
7074
# rgb values we find. Later, we might want to make the two word
@@ -81,23 +85,36 @@ def __init__(self, fp, lineno):
8185
self.__byname[keyname] = key
8286
lineno = lineno + 1
8387

88+
# override in derived classes
89+
def _extractrgb(self, mo):
90+
return map(int, mo.group('red', 'green', 'blue'))
91+
92+
def _extractname(self, mo):
93+
return mo.group('name')
94+
95+
def filename(self):
96+
return self.__name
97+
8498
def find_byrgb(self, rgbtuple):
99+
"""Return name for rgbtuple"""
85100
try:
86101
return self.__byrgb[rgbtuple]
87102
except KeyError:
88103
raise BadColor(rgbtuple)
89104

90105
def find_byname(self, name):
106+
"""Return (red, green, blue) for name"""
91107
name = string.lower(name)
92108
try:
93109
return self.__byname[name]
94110
except KeyError:
95111
raise BadColor(name)
96112

97113
def nearest(self, red, green, blue):
98-
# TBD: use Voronoi diagrams, Delaunay triangulation, or octree for
99-
# speeding up the locating of nearest point. Exhaustive search is
100-
# inefficient, but may be fast enough.
114+
"""Return the name of color nearest (red, green, blue)"""
115+
# TBD: should we use Voronoi diagrams, Delaunay triangulation, or
116+
# octree for speeding up the locating of nearest point? Exhaustive
117+
# search is inefficient, but seems fast enough.
101118
nearest = -1
102119
nearest_name = ''
103120
for name, aliases in self.__byrgb.values():
@@ -133,38 +150,66 @@ def aliases_of(self, red, green, blue):
133150

134151
class RGBColorDB(ColorDB):
135152
_re = re.compile(
136-
'\s*(?P<red>\d+)\s+(?P<green>\d+)\s+(?P<blue>\d+)\s+(?P<name>.*)')
153+
'\s*(?P<red>\d+)\s+(?P<green>\d+)\s+(?P<blue>\d+)\s+(?P<name>.*)')
154+
155+
156+
class HTML40DB(ColorDB):
157+
_re = re.compile('(?P<name>\S+)\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
158+
159+
def _extractrgb(self, mo):
160+
return rrggbb_to_triplet(mo.group('hexrgb'))
161+
162+
class LightlinkDB(HTML40DB):
163+
_re = re.compile('(?P<name>(.+))\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
164+
165+
def _extractname(self, mo):
166+
return string.strip(mo.group('name'))
167+
168+
class WebsafeDB(ColorDB):
169+
_re = re.compile('(?P<hexrgb>#[0-9a-fA-F]{6})')
170+
171+
def _extractrgb(self, mo):
172+
return rrggbb_to_triplet(mo.group('hexrgb'))
173+
174+
def _extractname(self, mo):
175+
return string.upper(mo.group('hexrgb'))
137176

138177

139178

140179
# format is a tuple (RE, SCANLINES, CLASS) where RE is a compiled regular
141180
# expression, SCANLINES is the number of header lines to scan, and CLASS is
142181
# the class to instantiate if a match is found
143182

144-
X_RGB_TXT = re.compile('XConsortium'), 1, RGBColorDB
183+
FILETYPES = [
184+
(re.compile('XConsortium'), RGBColorDB),
185+
(re.compile('HTML'), HTML40DB),
186+
(re.compile('lightlink'), LightlinkDB),
187+
(re.compile('Websafe'), WebsafeDB),
188+
]
145189

146-
def get_colordb(file, filetype=X_RGB_TXT):
190+
def get_colordb(file, filetype=None):
147191
colordb = None
148-
fp = None
149-
typere, scanlines, class_ = filetype
192+
fp = open(file)
150193
try:
151-
try:
152-
lineno = 0
153-
fp = open(file)
154-
while lineno < scanlines:
155-
line = fp.readline()
156-
if not line:
157-
break
158-
mo = typere.search(line)
159-
if mo:
160-
colordb = class_(fp, lineno)
161-
break
162-
lineno = lineno + 1
163-
except IOError:
164-
pass
194+
line = fp.readline()
195+
if not line:
196+
return None
197+
# try to determine the type of RGB file it is
198+
if filetype is None:
199+
filetypes = FILETYPES
200+
else:
201+
filetypes = [filetype]
202+
for typere, class_ in filetypes:
203+
mo = typere.search(line)
204+
if mo:
205+
break
206+
else:
207+
# no matching type
208+
return None
209+
# we know the type and the class to grok the type, so suck it in
210+
colordb = class_(fp)
165211
finally:
166-
if fp:
167-
fp.close()
212+
fp.close()
168213
# save a global copy
169214
global DEFAULT_DB
170215
DEFAULT_DB = colordb
@@ -175,6 +220,7 @@ def get_colordb(file, filetype=X_RGB_TXT):
175220
_namedict = {}
176221
def rrggbb_to_triplet(color, atoi=string.atoi):
177222
"""Converts a #rrggbb color to the tuple (red, green, blue)."""
223+
global _namedict
178224
rgbtuple = _namedict.get(color)
179225
if rgbtuple is None:
180226
if color[0] <> '#':
@@ -190,6 +236,7 @@ def rrggbb_to_triplet(color, atoi=string.atoi):
190236
_tripdict = {}
191237
def triplet_to_rrggbb(rgbtuple):
192238
"""Converts a (red, green, blue) tuple to #rrggbb."""
239+
global _tripdict
193240
hexname = _tripdict.get(rgbtuple)
194241
if hexname is None:
195242
hexname = '#%02x%02x%02x' % rgbtuple

Tools/pynche/ListViewer.py

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,29 @@ def __init__(self, switchboard, master=None):
4545
canvas.pack(fill=BOTH, expand=1)
4646
canvas.configure(yscrollcommand=(self.__scrollbar, 'set'))
4747
self.__scrollbar.configure(command=(canvas, 'yview'))
48+
self.__populate()
49+
#
50+
# Update on click
51+
self.__uoc = BooleanVar()
52+
self.__uoc.set(optiondb.get('UPONCLICK', 1))
53+
self.__uocbtn = Checkbutton(root,
54+
text='Update on Click',
55+
variable=self.__uoc,
56+
command=self.__toggleupdate)
57+
self.__uocbtn.pack(expand=1, fill=BOTH)
58+
#
59+
# alias list
60+
self.__alabel = Label(root, text='Aliases:')
61+
self.__alabel.pack()
62+
self.__aliases = Listbox(root, height=5,
63+
selectmode=BROWSE)
64+
self.__aliases.pack(expand=1, fill=BOTH)
65+
66+
def __populate(self):
4867
#
4968
# create all the buttons
50-
colordb = switchboard.colordb()
69+
colordb = self.__sb.colordb()
70+
canvas = self.__canvas
5171
row = 0
5272
widest = 0
5373
bboxes = self.__bboxes = []
@@ -63,7 +83,7 @@ def __init__(self, switchboard, master=None):
6383
boxid = canvas.create_rectangle(3, row*20+3,
6484
textend+3, row*20 + 23,
6585
outline='',
66-
tags=(exactcolor,))
86+
tags=(exactcolor, 'all'))
6787
canvas.bind('<ButtonRelease>', self.__onrelease)
6888
bboxes.append(boxid)
6989
if textend+3 > widest:
@@ -74,22 +94,6 @@ def __init__(self, switchboard, master=None):
7494
for box in bboxes:
7595
x1, y1, x2, y2 = canvas.coords(box)
7696
canvas.coords(box, x1, y1, widest, y2)
77-
#
78-
# Update on click
79-
self.__uoc = BooleanVar()
80-
self.__uoc.set(optiondb.get('UPONCLICK', 1))
81-
self.__uocbtn = Checkbutton(root,
82-
text='Update on Click',
83-
variable=self.__uoc,
84-
command=self.__toggleupdate)
85-
self.__uocbtn.pack(expand=1, fill=BOTH)
86-
#
87-
# alias list
88-
self.__alabel = Label(root, text='Aliases:')
89-
self.__alabel.pack()
90-
self.__aliases = Listbox(root, height=5,
91-
selectmode=BROWSE)
92-
self.__aliases.pack(expand=1, fill=BOTH)
9397

9498
def __onrelease(self, event=None):
9599
canvas = self.__canvas
@@ -164,3 +168,7 @@ def update_yourself(self, red, green, blue):
164168

165169
def save_options(self, optiondb):
166170
optiondb['UPONCLICK'] = self.__uoc.get()
171+
172+
def flush(self):
173+
self.__canvas.delete('all')
174+
self.__populate()

Tools/pynche/Main.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
5050
"""
5151

52-
__version__ = '0.1'
52+
__version__ = '0.2'
5353

5454
import sys
5555
import os
@@ -120,19 +120,27 @@ def scan_color(s, colordb=colordb):
120120

121121

122122
def build(master=None, initialcolor=None, initfile=None, ignore=None):
123-
# create the windows and go
124-
for f in RGB_TXT:
125-
try:
126-
colordb = ColorDB.get_colordb(f)
127-
if colordb:
128-
break
129-
except IOError:
130-
pass
131-
else:
132-
usage(1, 'No color database file found, see the -d option.')
133-
134123
# create all output widgets
135-
s = Switchboard(colordb, not ignore and initfile)
124+
s = Switchboard(not ignore and initfile)
125+
126+
# load the color database
127+
colordb = None
128+
try:
129+
dbfile = s.optiondb()['DBFILE']
130+
colordb = ColorDB.get_colordb(dbfile)
131+
except (KeyError, IOError):
132+
# scoot through the files listed above to try to find a usable color
133+
# database file
134+
for f in RGB_TXT:
135+
try:
136+
colordb = ColorDB.get_colordb(f)
137+
if colordb:
138+
break
139+
except IOError:
140+
pass
141+
if not colordb:
142+
usage(1, 'No color database file found, see the -d option.')
143+
s.set_colordb(colordb)
136144

137145
# create the application window decorations
138146
app = PyncheWidget(__version__, s, master=master)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy