homepage/tartans/tartan.py

118 lines
3.2 KiB
Python
Executable File

#! /usr/bin/python
import sys
import Image
import re
import array
colors = {'R': '\x88\x00\x00', # Red
'G': '\x00\x44\x00', # Green
'B': '\x00\x00\x44', # Blue
'C': '\x00\x44\x44', # Cyan
'Y': '\x99\x99\x00', # Yellow
'P': '\x99\x00\x99', # Purple (?!)
'W': '\x99\x99\x99', # White
'K': '\x00\x00\x00', # Black
'BK': '\x00\x00\x00', # Black
'GR': '\x44\x44\x44', # Gray
'DB': '\x00\x00\x55', # Dark Blue
'LB': '\x00\x44\x99', # Light Blue
'LR': '\x99\x00\x00', # Light Red
'LG': '\x00\x99\x00', # Light Green
'LV': '\x88\x44\x99', # Lavender
'BR': '\x55\x44\x00', # Brown
'LGR': '\x99\x99\x99', # Light Gray
'LBR': '\x66\x66\x00', # Light Brown
}
sett_re = re.compile('([A-Za-z]{1,3}|\([A-Fa-f0-9]{3}\))(\d{1,3})')
def str_to_sett(s):
"""Convert an xtartan sett string into a sett tuple."""
sett = []
while s:
m = sett_re.search(s)
if not m:
break
cs = m.group(1)
if cs[0] == '(' and cs[-1] == ')':
ca = array.array('B')
for a in cs[1:-1]:
ca.append(int(a+a, 16))
c = ca.tostring()
else:
c = colors[cs]
n = int(m.group(2))
sett.append((c, n))
s = s[m.end():]
if not s.endswith('.'):
o = sett[:]
o.reverse()
sett += o
return sett
class Loom:
"""Simulates a simple loom with only one weft color per row.
This probably does a simplistic weave too, I don't know enough about
weaving to say for sure. But I can imagine more complicated ways of
doing it.
"""
def __init__(self, warp):
self.warp = warp
self.cloth = []
self.row = 0
def weave(self, weft):
out = []
for i in range(len(self.warp)):
if (i + self.row) % 2 == 0:
out.append(weft)
else:
out.append(self.warp[i])
self.cloth.append(out)
self.row += 1
class Tartan:
def __init__(self, sett):
# Weave a whole pattern suitable for tiling. In other words, it
# does the mirroring for you.
if type(sett) == type(''):
sett = str_to_sett(sett)
warp = []
for c,n in sett:
warp += [c]*n
if False:
# Offset it to the center of the first dealie
o = sett[0][1] / 2
warp += warp[:o]
del warp[:o]
self.loom = Loom(warp)
for w in warp:
self.loom.weave(w)
rgbs = [''.join(x) for x in self.loom.cloth]
imgstr = ''.join(rgbs)
self.img = Image.fromstring('RGB',
(len(self.loom.cloth[1]),
len(self.loom.cloth)),
imgstr)
def png(self, fd):
self.img.save(fd, 'PNG')
if __name__ == '__main__':
sett = sys.argv[1]
t = Tartan(sett)
t.png(sys.stdout)