Add tartans
This commit is contained in:
parent
d4ac728d0f
commit
ec72794f6e
1
Jamfile
1
Jamfile
|
@ -6,4 +6,5 @@ SubInclude TOP papers ;
|
||||||
SubInclude TOP projects ;
|
SubInclude TOP projects ;
|
||||||
SubInclude TOP poems ;
|
SubInclude TOP poems ;
|
||||||
SubInclude TOP src ;
|
SubInclude TOP src ;
|
||||||
|
SubInclude TOP tartans ;
|
||||||
SubInclude TOP toys ;
|
SubInclude TOP toys ;
|
||||||
|
|
|
@ -19,3 +19,9 @@ pre {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
border: solid black 1px;
|
border: solid black 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.figure {
|
||||||
|
float: right;
|
||||||
|
padding: 0.5em;
|
||||||
|
font-size: small;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
SubDir TOP tartans ;
|
||||||
|
|
||||||
|
TARTAN_TMPL = $(SUBDIR)/tartan.m4 ;
|
||||||
|
TARTANTOMDWN = $(SUBDIR)/tartantomdwn ;
|
||||||
|
LOOM = $(SUBDIR)/loom.py ;
|
||||||
|
|
||||||
|
rule Tartan {
|
||||||
|
local tartans = [ FGristFiles $(1:S=.tartan) ] ;
|
||||||
|
|
||||||
|
for t in $(tartans) {
|
||||||
|
local png = $(t:S=.png:D=img:G=) ;
|
||||||
|
local mdwn = $(t:S=.mdwn) ;
|
||||||
|
|
||||||
|
TartanToMdwn $(mdwn) : $(t) ;
|
||||||
|
TartanToPng $(png) : $(t) ;
|
||||||
|
Webify $(mdwn) ;
|
||||||
|
Depends $(mdwn:S=.html) : $(png) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rule TartanToMdwn {
|
||||||
|
Depends $(1) : $(2) $(TARTAN_TMPL) $(TARTANTOMDWN) ;
|
||||||
|
Clean clean : $(1) ;
|
||||||
|
MakeLocate $(1) : $(LOCATE_TARGET) ;
|
||||||
|
SEARCH on $(2) = $(SEARCH_SOURCE) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
rule TartanToPng {
|
||||||
|
Depends $(1) : $(2) $(LOOM) ;
|
||||||
|
Clean clean : $(1) ;
|
||||||
|
MakeLocate $(1) : $(LOCATE_TARGET) ;
|
||||||
|
SEARCH on $(2) = $(SEARCH_SOURCE) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions TartanToMdwn {
|
||||||
|
$(TARTANTOMDWN) $(1:S=) < $(2) > $(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
actions TartanToPng {
|
||||||
|
$(LOOM) < $(2) > $(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
Webify index.mdwn ;
|
||||||
|
Tartan albuquerque armstrong az blackwatch buchanan co nm nmloe nv ok pjs pjs2 shrek tx ut wa ;
|
|
@ -0,0 +1,9 @@
|
||||||
|
Name: Albuquerque
|
||||||
|
Sett: R4 G24 B4 G10 B36 W6 R4 W4
|
||||||
|
|
||||||
|
Created by Ralph Stevenson Jr and Charles Hargis in 2005 for the city's
|
||||||
|
tricentennial anniversary (1706-2006). It is similar in design to the
|
||||||
|
[New Mexico tartan](nm), with a little less green, and white instead of
|
||||||
|
yellow, with a thicker center band.
|
||||||
|
|
||||||
|
[Bally Dun Celtic Treasures](http://www.ballydun.com/) sells this tartan.
|
|
@ -0,0 +1,2 @@
|
||||||
|
Name: Armstrong
|
||||||
|
Sett: G4 BK2 G60 BK24 B4 BK2 B2 BK2 B24 R6
|
|
@ -0,0 +1,6 @@
|
||||||
|
Name: Arizona
|
||||||
|
Sett: W2 G3 R4 G28 B3 (963)8
|
||||||
|
|
||||||
|
Based on a jpeg I found on a geocities homepage. Surprisingly,
|
||||||
|
that jpeg was the only mention I could find on the net of what
|
||||||
|
the actual sett was for Arizona.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Name: Black Watch
|
||||||
|
Sett: B22 BK2 B2 BK2 B2 BK16 G16 BK2 G16 BK16 B16 BK2 B2BK2 G10 BK8 DB9 BK1 DB1
|
||||||
|
|
||||||
|
A standard.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Name: Buchanan
|
||||||
|
Sett: Y8 BK2 Y8 BK2 B6 BK2 G8 B4 G8 BK2 B6 BK2 LR10 W2 LR10 BK2 B6 BK2 .
|
||||||
|
|
||||||
|
I typed in this one as an example of an asymmetric sett.
|
|
@ -0,0 +1,13 @@
|
||||||
|
Name: Colorado
|
||||||
|
Sett: Y4 R6 (669)34 K40 G4 W6 LV6 W6 G22
|
||||||
|
|
||||||
|
Wikipedia lists the sett as `[Y/6] R4 MB26 K32 G4 W4 Lv4 W4 [G/44]`. I'm
|
||||||
|
not familiar with the [Color/Count] notation, the count appears to be
|
||||||
|
doubled, possibly to indicate the total count of that thread in the
|
||||||
|
mirror section.
|
||||||
|
|
||||||
|
[Colorado house joint resolution
|
||||||
|
97-1016](http://www.state.co.us/gov_dir/leg_dir/res/HJR1016.htm) makes
|
||||||
|
this official but doesn't provide a thread count. It speaks of
|
||||||
|
"cerulean blue" which I approximate with the unique (669) color.
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#! /usr/bin/python
|
||||||
|
|
||||||
|
import cgitb; cgitb.enable()
|
||||||
|
import htmltmpl
|
||||||
|
import loom
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import cgi
|
||||||
|
import os
|
||||||
|
import rfc822
|
||||||
|
import urllib
|
||||||
|
import cStringIO as StringIO
|
||||||
|
|
||||||
|
var_re = re.compile('\$(\w+|{\w+})')
|
||||||
|
def fill_template(tmpl, **keywds):
|
||||||
|
def repl(match):
|
||||||
|
var = match.group(0)[1:]
|
||||||
|
var = var.strip('{}')
|
||||||
|
return keywds[var]
|
||||||
|
return var_re.sub(repl, tmpl)
|
||||||
|
|
||||||
|
|
||||||
|
def serve(s, c_t):
|
||||||
|
o = ('Content-type: %s\r\nContent-length: %d\r\n\r\n%s' %
|
||||||
|
(c_t, len(s), s))
|
||||||
|
sys.stdout.write(o)
|
||||||
|
|
||||||
|
f = cgi.FieldStorage()
|
||||||
|
|
||||||
|
s = f.getfirst('sett')
|
||||||
|
if s:
|
||||||
|
sett = loom.str_to_sett(s)
|
||||||
|
l = loom.tartan(sett)
|
||||||
|
p = StringIO.StringIO()
|
||||||
|
l.png(p)
|
||||||
|
|
||||||
|
serve(p.getvalue(), 'image/png')
|
||||||
|
else:
|
||||||
|
manager = htmltmpl.TemplateManager(precompile=0)
|
||||||
|
tmpl = manager.prepare('/home/neale/lib/wiki/templates/page.tmpl')
|
||||||
|
processor = htmltmpl.TemplateProcessor(html_escape=False)
|
||||||
|
|
||||||
|
t = os.environ.get('PATH_INFO', '').strip('/')
|
||||||
|
if not t:
|
||||||
|
t = f.getfirst('t', 'Unknown')
|
||||||
|
s = f.getfirst('s')
|
||||||
|
if t and not s:
|
||||||
|
try:
|
||||||
|
m = rfc822.Message(file('%s.tartan' % t))
|
||||||
|
t = m.get('Title', t)
|
||||||
|
s = m.get('Sett')
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not t or not s:
|
||||||
|
# Default to Black Watch
|
||||||
|
t = 'Black Watch'
|
||||||
|
s = ('B22 BK2 B2 BK2 B2 BK16 G16 BK2 G16 BK16 B16 BK2 B2'
|
||||||
|
'BK2 G10 BK8 DB9 BK1 DB1')
|
||||||
|
s_st = s.replace(' ', '')
|
||||||
|
s_st = s_st.replace('\n' ,'')
|
||||||
|
|
||||||
|
content = '''
|
||||||
|
<ul style="background: white; float: right;">
|
||||||
|
<li><a href="design.cgi?sett=%(sett_compressed)s">image only</a></li>
|
||||||
|
<li><a href="/~neale/tartans">More tartans</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>woozle.org tartan designer</h2>
|
||||||
|
<form action="design" style="padding: 10px;">
|
||||||
|
<input name="t" value="%(tartan)s" />
|
||||||
|
<textarea name="s" rows="3" cols="40">%(sett)s</textarea> <br />
|
||||||
|
<input type="submit" value="Generate" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div style="background: url(design.cgi?sett=%(sett_compressed)s);
|
||||||
|
height: 400px;
|
||||||
|
border: solid black 40px;">
|
||||||
|
</div>
|
||||||
|
''' % {'tartan': t,
|
||||||
|
'sett': s,
|
||||||
|
'sett_compressed': urllib.quote(s_st)}
|
||||||
|
|
||||||
|
processor.set('title', t)
|
||||||
|
processor.set('content', content)
|
||||||
|
page = processor.process(tmpl)
|
||||||
|
|
||||||
|
serve(page, 'text/html')
|
|
@ -0,0 +1,22 @@
|
||||||
|
Title: Tartans
|
||||||
|
|
||||||
|
I like tartans, they appeal to my geeky need for symmetry and elegant
|
||||||
|
description.
|
||||||
|
|
||||||
|
<div class="figure">
|
||||||
|
<img src="img/nmloe.png" alt="tartan image" />
|
||||||
|
<br />
|
||||||
|
<a href="nmloe">
|
||||||
|
New Mexico Land Of Enchantment
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
LG8 LV32 R4 G32 LG32 Y4 LG4
|
||||||
|
</div>
|
||||||
|
|
||||||
|
I've written a [tartan designer](design) that will take a sett pattern
|
||||||
|
in modified xtartan format, and output a PNG image of said tartan. Below
|
||||||
|
are some tartans I've made with it.
|
||||||
|
|
||||||
|
If you have one you'd like to contribute to my database, or would like
|
||||||
|
the code that generates this stuff, feel free to [email
|
||||||
|
me](mailto:neale-tartan@woozle.org).
|
|
@ -0,0 +1,181 @@
|
||||||
|
#! /usr/bin/python
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Yarn:
|
||||||
|
"""A spool of yarn.
|
||||||
|
|
||||||
|
Color is specified as a 3-tuple (red, green, blue) of
|
||||||
|
saturation values ranging from 0.0 (no saturation) to
|
||||||
|
1.0 (full saturation).
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, r, g, b):
|
||||||
|
self.rgb = (r, g, b)
|
||||||
|
self.color = (int(r * 256), int(g * 256), int(b * 256))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<Yarn %r>' % (self.rgb)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Loom:
|
||||||
|
def __init__(self, warp):
|
||||||
|
self.warp = warp
|
||||||
|
self.fabric = []
|
||||||
|
|
||||||
|
def weave(self, yarn, up=1, down=1, skip=0, repeat=0):
|
||||||
|
offset = (len(self.fabric) / (repeat + 1)) * (skip + 1)
|
||||||
|
harnesses = up + down
|
||||||
|
row = []
|
||||||
|
for i in range(len(self.warp)):
|
||||||
|
j = (i + offset) % harnesses
|
||||||
|
if j < down:
|
||||||
|
row.append(self.warp[i])
|
||||||
|
else:
|
||||||
|
row.append(yarn)
|
||||||
|
self.fabric.append(row)
|
||||||
|
|
||||||
|
def plain_weave(self, yarn):
|
||||||
|
# AKA tabby weave, taffeta weave
|
||||||
|
self.weave(yarn)
|
||||||
|
|
||||||
|
def twill(self, yarn, up=2, down=2):
|
||||||
|
self.weave(yarn, up, down)
|
||||||
|
|
||||||
|
def satin_weave(self, yarn):
|
||||||
|
# 1/16, skip 4
|
||||||
|
self.weave(yarn, 1, 16, 4)
|
||||||
|
|
||||||
|
def basket_weave(self, yarn):
|
||||||
|
# 2/2, skip 1, repeat 1
|
||||||
|
self.weave(yarn, 2, 2, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class PNGLoom(Loom):
|
||||||
|
def png(self, outf, scale=1):
|
||||||
|
import Image
|
||||||
|
import array
|
||||||
|
|
||||||
|
imgstr = array.array('B')
|
||||||
|
for fr in self.fabric:
|
||||||
|
row = []
|
||||||
|
for c in fr:
|
||||||
|
for i in range(scale):
|
||||||
|
row.extend(c.color)
|
||||||
|
for i in range(scale):
|
||||||
|
imgstr.fromlist(row)
|
||||||
|
x = len(fr * scale)
|
||||||
|
y = len(self.fabric * scale)
|
||||||
|
img = Image.fromstring('RGB', (x, y), imgstr.tostring())
|
||||||
|
img.save(outf, 'PNG')
|
||||||
|
|
||||||
|
|
||||||
|
def ascii_test():
|
||||||
|
print 'Plain weave'
|
||||||
|
l = Loom('||||||||||||||||||||||||||||||||')
|
||||||
|
for i in range(16):
|
||||||
|
l.plain_weave('-')
|
||||||
|
for row in l.fabric:
|
||||||
|
print ' ', ''.join(row)
|
||||||
|
|
||||||
|
print 'Twill'
|
||||||
|
l = Loom('||||||||||||||||||||||||||||||||')
|
||||||
|
for i in range(16):
|
||||||
|
l.twill('-')
|
||||||
|
for row in l.fabric:
|
||||||
|
print ' ', ''.join(row)
|
||||||
|
|
||||||
|
print '2/1 twill'
|
||||||
|
l = Loom('||||||||||||||||||||||||||||||||')
|
||||||
|
for i in range(16):
|
||||||
|
l.twill('-', 2, 1)
|
||||||
|
for row in l.fabric:
|
||||||
|
print ' ', ''.join(row)
|
||||||
|
|
||||||
|
print 'Satin weave'
|
||||||
|
l = Loom('||||||||||||||||||||||||||||||||')
|
||||||
|
for i in range(16):
|
||||||
|
l.satin_weave('-')
|
||||||
|
for row in l.fabric:
|
||||||
|
print ' ', ''.join(row)
|
||||||
|
|
||||||
|
print 'Basketweave'
|
||||||
|
l = Loom('||||||||||||||||||||||||||||||||')
|
||||||
|
for i in range(16):
|
||||||
|
l.basket_weave('-')
|
||||||
|
for row in l.fabric:
|
||||||
|
print ' ', ''.join(row)
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Tartan junk
|
||||||
|
##
|
||||||
|
|
||||||
|
colors = {'R': Yarn(0.50, 0.00, 0.00), # Red
|
||||||
|
'G': Yarn(0.00, 0.30, 0.00), # Green
|
||||||
|
'B': Yarn(0.00, 0.00, 0.50), # Blue
|
||||||
|
'C': Yarn(0.00, 0.25, 0.25), # Cyan
|
||||||
|
'Y': Yarn(0.80, 0.80, 0.00), # Yellow
|
||||||
|
'P': Yarn(0.60, 0.00, 0.60), # Purple (?!)
|
||||||
|
'W': Yarn(0.60, 0.60, 0.60), # White
|
||||||
|
'K': Yarn(0.00, 0.00, 0.00), # Black
|
||||||
|
'BK': Yarn(0.00, 0.00, 0.00), # Black
|
||||||
|
'GR': Yarn(0.25, 0.25, 0.25), # Gray
|
||||||
|
'DB': Yarn(0.00, 0.00, 0.30), # Dark Blue
|
||||||
|
'LB': Yarn(0.00, 0.25, 0.60), # Light Blue
|
||||||
|
'LR': Yarn(0.60, 0.00, 0.00), # Light Red
|
||||||
|
'LG': Yarn(0.00, 0.60, 0.00), # Light Green
|
||||||
|
'LV': Yarn(0.50, 0.25, 0.60), # Lavender
|
||||||
|
'BR': Yarn(0.30, 0.25, 0.00), # Brown
|
||||||
|
'LGR': Yarn(0.60, 0.60, 0.60), # Light Gray
|
||||||
|
'LBR': Yarn(0.40, 0.40, 0.00), # 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 = []
|
||||||
|
for a in cs[1:-1]:
|
||||||
|
ca.append(int(a+a, 16) / 256.0)
|
||||||
|
y = Yarn(*ca)
|
||||||
|
else:
|
||||||
|
y = colors[cs]
|
||||||
|
|
||||||
|
for i in range(int(m.group(2))):
|
||||||
|
sett.append(y)
|
||||||
|
s = s[m.end():]
|
||||||
|
if not s.endswith('.'):
|
||||||
|
o = sett[:]
|
||||||
|
o.reverse()
|
||||||
|
sett += o
|
||||||
|
return sett
|
||||||
|
|
||||||
|
def tartan(sett):
|
||||||
|
l = PNGLoom(sett)
|
||||||
|
for y in sett:
|
||||||
|
l.twill(y)
|
||||||
|
return l
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
if line.startswith('Sett:'):
|
||||||
|
_, s = line.split(':', 1)
|
||||||
|
s = s.strip()
|
||||||
|
break
|
||||||
|
sett = str_to_sett(s)
|
||||||
|
l = tartan(sett)
|
||||||
|
l.png(sys.stdout, 1)
|
|
@ -0,0 +1,7 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
for i in "$@"; do
|
||||||
|
base=$(basename $i .tartan)
|
||||||
|
name=$(awk -F': ' '(/^Name:/) {print $2; exit;}' $i)
|
||||||
|
echo "* [$name]($base.html)"
|
||||||
|
done
|
|
@ -0,0 +1,10 @@
|
||||||
|
Name: New Mexico
|
||||||
|
Sett: R4 G24 B4 G16 B36 Y8 R4 Y4
|
||||||
|
|
||||||
|
Designed by Ralph Stevenson Jr, [officially recognized in 2003](nm-proc)
|
||||||
|
by the Secretary of State. It is similar in design to the [Albuquerque
|
||||||
|
tartan](albuquerque). I bought a scarf of this plaid from
|
||||||
|
Mr. Stevenson; it came with a photocopy of the tartan registration and a
|
||||||
|
few other documents.
|
||||||
|
|
||||||
|
[Bally Dun Celtic Treasures](http://www.ballydun.com/) sells this tartan.
|
|
@ -0,0 +1,7 @@
|
||||||
|
Name: New Mexico Land Of Enchantment
|
||||||
|
Sett: LG8 LV32 R4 G32 LG32 Y4 LG4
|
||||||
|
|
||||||
|
This isn't official but I think it's pretty. I just guessed at the
|
||||||
|
sett pattern but I think I got pretty close.
|
||||||
|
[Kathy Lare](http://www.kathyskilts.com/) is the sole source for this
|
||||||
|
fabric.
|
|
@ -0,0 +1,6 @@
|
||||||
|
Name: Nevada
|
||||||
|
Sett: W4 LGR16 B4 LGR8 B8 Y4 B4 R4 B20
|
||||||
|
|
||||||
|
Based on a terrible gif that is apparently a part of [Nevada Revised
|
||||||
|
Statute 235.130](http://leg.state.nv.us/NRS/NRS-235.html#NRS235Sec130).
|
||||||
|
Designed by Richard Zygmunt Pawlowski, approved May 8, 2001.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Name: Oklahoma
|
||||||
|
Sett: R4 W8 LB64 Y6 BK16
|
||||||
|
|
||||||
|
Based on a photo on a web page.
|
|
@ -0,0 +1,7 @@
|
||||||
|
Name: Neale's PJs
|
||||||
|
Sett: W7 C3 GR5 BK3 C5 BK3 C6 GR3 C5
|
||||||
|
|
||||||
|
This is an approximation of the pajamas I was wearing when I wrote the
|
||||||
|
tartan designer. They weren't actually a tartan. I guess modern
|
||||||
|
weavers feel they ought to show off the fact that they can do fancy
|
||||||
|
tricks with their looms.
|
|
@ -0,0 +1,5 @@
|
||||||
|
Name: Neale's PJs II
|
||||||
|
Sett: W3 G24 Y2 W2 G2 W2 G2 W1
|
||||||
|
|
||||||
|
More of my PJs. This one is an exact copy, I can count the threads
|
||||||
|
in this fabric.
|
|
@ -0,0 +1,6 @@
|
||||||
|
Name: Shrek
|
||||||
|
Sett: LBR4 BR8 G16 R2 G16 BR32
|
||||||
|
|
||||||
|
I (Neale) created this based on Shrek's pants in a couple of frame grabs
|
||||||
|
from the movie. It appears to be different from the recently-released
|
||||||
|
"Shrek's Tartan".
|
|
@ -0,0 +1,21 @@
|
||||||
|
Title: TARTAN Tartan
|
||||||
|
|
||||||
|
divert(1)
|
||||||
|
<div style="background: url(img/BASE.png);
|
||||||
|
height: 400px;
|
||||||
|
border: solid black 40px;
|
||||||
|
clear: both;">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
I place this image in the public domain, in the hope that it will
|
||||||
|
increase interest in tartans and tartan design.
|
||||||
|
|
||||||
|
<form action="design.cgi">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Tartan Designer</legend>
|
||||||
|
<label for="t">Name:</label> <input name="t" value="TARTAN" /> <br/>
|
||||||
|
<label for="s">Sett:</label> <input name="s" value="SETT" /> <br/>
|
||||||
|
<input type="submit" value="Design" />
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
divert(0)
|
|
@ -0,0 +1,117 @@
|
||||||
|
#! /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)
|
|
@ -0,0 +1,22 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
header () {
|
||||||
|
while IFS=: read key val; do
|
||||||
|
tval=$(echo $val | sed "s/'/\'/g")
|
||||||
|
case $key in
|
||||||
|
Name)
|
||||||
|
echo -n "TARTAN='$tval';"
|
||||||
|
;;
|
||||||
|
Sett)
|
||||||
|
echo -n "SETT='$tval'"
|
||||||
|
;;
|
||||||
|
"")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
eval $(header)
|
||||||
|
m4 -DTARTAN="$TARTAN" -DSETT="$SETT" -DBASE="$1" tartan.m4 -
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
Name: Texas Bluebonnet
|
||||||
|
Sett: G4 R2 B16 W2 R2 W2 LB16 W2 LB16 W2 Y1
|
||||||
|
|
||||||
|
Based off a jpeg at the [Texas Scottish Heritage
|
||||||
|
Society](http://www.txscot.com/BB_tartan.htm#bluebonnet). (Why did they
|
||||||
|
save it as a jpeg?) The first blue in their image was only 15 threads
|
||||||
|
wide, I figured that was a typographical mistake given every subsequent
|
||||||
|
blue was 16, even in the repeats.
|
||||||
|
|
||||||
|
According to the aforementioned web page, it was designed by June
|
||||||
|
Prescott McRoberts, and adopted as the official state tartan on May 25,
|
||||||
|
1989.
|
|
@ -0,0 +1,7 @@
|
||||||
|
Name: Utah
|
||||||
|
Sett: W1 B6 R6 B4 R6 G18 R6 W4
|
||||||
|
|
||||||
|
Kudos to Utah for putting the sett right into 1996's SB-13. This is the
|
||||||
|
tartan as specified by law. The [photograph on Utah's Online
|
||||||
|
Library](http://pioneer.utah.gov/utah_on_the_web/utah_symbols/tartan.html)
|
||||||
|
seems to have a final white threadcount of 3.
|
|
@ -0,0 +1,5 @@
|
||||||
|
Name: Washington State
|
||||||
|
Sett: W3 R6 B36 G72 LB6 BK6 Y2
|
||||||
|
|
||||||
|
Adopted 1991 by the spartan [RCW
|
||||||
|
1.20.110](http://apps.leg.wa.gov/rcw/default.aspx?cite=1.20.110).
|
Loading…
Reference in New Issue