This method reads and processes one line from the rgb.txt file. For a description of the format, see
Section 14.7, “PickList.__readColorsFile(): Process the
rgb.txt file”.
# - - - P i c k L i s t . _ _ r e a d C o l o r L i n e
def __readColorLine ( self, index, rawLine ):
"""Process one line from the rgb.txt file.
[ (index is a nonnegative integer) and
(rawLine is a string) ->
if rawLine is a comment -> I
else if rawLine is valid ->
self.__colorMap +:= an entry mapping the
uppercased color name |-> a tuple (index,
the color from that line as a Color instance),
the name from that line)
else -> raise IOError ]
"""
First we remove any trailing whitespace. This will take care of any newline character.
#-- 1 --
# [ line := rawLine with trailing whitespace removed ]
line = rawLine.rstrip()
If the line is a comment, return.
#-- 2 --
if line.startswith('!'):
return
Python's string .split() method does a nice job
of breaking the line into fields. In this call, there are two
arguments. The first argument is the delimiter; passing None to this argument has the effect of using any
contiguous string of whitespace characters as a delimiter. The
second argument specifies an upper limit to the number of fields
removed from the front of the string. By passing a value of 3
to this argument, we never get more than four fields; this will
avoid splitting up color names that contain embedded spaces.
#-- 3 --
# [ fieldList := line split on whitespace regions, but never
# more than the first four ]
fieldList = line.split ( None, 3 )
Now for some validity tests. There should be exactly
four fields. Also, the first three must contain strings
that can be converted to integers. For conversion of the
integer values, see Section 14.9, “PickList.__convert8(): Convert an 8-bit
number”.
#-- 4 --
if len(fieldList) < 4:
raise IOError, "rgb.txt lines must have four fields"
else:
colorName = fieldList[-1]
#-- 5 --
# [ if the first three elements of fieldList can be
# converted to integers in [0,255] ->
# red8 := int(fieldList[0])
# green8 := int(fieldList[1])
# blue8 := int(fieldList[2])
# else -> raise IOError ]
red8 = self.__convert8 ( fieldList[0] )
green8 = self.__convert8 ( fieldList[1] )
blue8 = self.__convert8 ( fieldList[2] )
The Color class constructor expects values in the
range [0,MAX_PARAM]. One possibility is just to multiply the
values by 256, and that's probably sufficiently accurate. A
rejected possibility was to duplicate the value, e.g., 0x80 becomes 0x8080, and 0xff becomes 0xffff. If anyone ever
convinces me that it makes a difference, I'll change it.
#-- 6 --
# [ color := a new Color instance made from red8, green8,
# and blue8, each shifted left 8 bits ]
color = Color ( red8<<8, green8<<8,
blue8<<8 )
Finally, add a new entry to self.__colorMap for
this color.
#-- 7 --
colorKey = colorName.upper()
colorTuple = (index, color, colorName)
self.__colorMap [ colorKey ] = colorTuple