Last active
August 19, 2017 14:46
-
-
Save gferreira/248d4cfce311c688bad29b11786781b6 to your computer and use it in GitHub Desktop.
fontParts object map
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# fontParts object map | |
from grapefruit import Color | |
from collections import OrderedDict | |
class FontPartsMap(object): | |
colors = OrderedDict([ | |
('font' , (80, 0.50, 0.49)), | |
('font_lib' , (136, 0.42, 0.55)), | |
('info' , (176, 0.9, 0.36)), | |
('kerning' , (183, 0.9, 0.44)), | |
('features' , (203, 0.7, 0.57)), | |
('layer' , (417, 0.5, 0.49)), | |
('glyph' , (38, 0.91, 0.69)), | |
('glyph_lib' , (22, 0.85, 0.59)), | |
('anchor' , (21, 0.68, 0.50)), | |
('component' , (25, 0.69, 0.51)), | |
('image' , (20, 0.59, 0.51)), | |
('guideline' , (11, 0.65, 0.52)), | |
('contour' , (4, 0.55, 0.52)), | |
('point' , (347, 0.66, 0.52)), | |
('bPoint' , (333, 0.67, 0.48)), | |
('segment' , (324, 0.67, 0.42)), | |
]) | |
lines = [ | |
('font', 'info'), | |
('font', 'font_lib'), | |
('font', 'kerning'), | |
('font', 'features'), | |
('font', 'layer'), | |
('layer', 'glyph'), | |
('glyph', 'glyph_lib'), | |
('glyph', 'anchor'), | |
('glyph', 'component'), | |
('glyph', 'image'), | |
('glyph', 'guideline'), | |
('glyph', 'contour'), | |
('contour', 'point'), | |
('contour', 'bPoint'), | |
('contour', 'segment') | |
] | |
positions = {} | |
radius_1 = 50 | |
radius_2 = 70 | |
length_1 = 160 | |
length_2 = 200 | |
length_3 = 170 | |
font = 'Menlo-Bold' | |
font_size_1 = 18 | |
font_size_2 = 32 | |
lines_stroke_color = 0.6, | |
lines_stroke_width = 4 | |
lines_dash = 3, 7 | |
circles_stroke_color = 0, | |
circles_stroke_width = 3 | |
rand_range = 0 | |
landscape = True | |
def make_positions(self, (x, y)): | |
x0, y0 = x, y | |
a1 = 180/3 # font | |
a2 = 180/4 # glyph | |
a3 = 180/3.5 # contour | |
# font | |
self.positions['font'] = x0, y0 | |
# font lib | |
x1 = x0 + self.length_1 | |
y1 = y0 | |
self.positions['font_lib'] = x1, y1 | |
# info | |
x2 = x0 + cos(radians(a1)) * self.length_1 | |
y2 = y0 + sin(radians(a1)) * self.length_1 | |
self.positions['info'] = x2, y2 | |
# kerning | |
i = 2 | |
x3 = x0 + cos(radians(a1*i)) * self.length_1 | |
y3 = y0 + sin(radians(a1*i)) * self.length_1 | |
self.positions['kerning'] = x3, y3 | |
# features | |
i = 3 | |
x4 = x0 + cos(radians(a1*i)) * self.length_1 | |
y4 = y0 + sin(radians(a1*i)) * self.length_1 | |
self.positions['features'] = x4, y4 | |
# layer | |
x5 = x0 | |
y5 = y0 - self.length_2 | |
self.positions['layer'] = x5, y5 | |
# glyph | |
x6 = x0 | |
y6 = y5 - self.length_2 | |
self.positions['glyph'] = x6, y6 | |
# glyph_lib | |
i = -5 | |
x7 = x6 + cos(radians(a2*i)) * self.length_2 | |
y7 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['glyph_lib'] = x7, y7 | |
# anchor | |
i = -4 | |
x8 = x6 + cos(radians(a2*i)) * self.length_2 | |
y8 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['anchor'] = x8, y8 | |
# component | |
i = -3 | |
x9 = x6 + cos(radians(a2*i)) * self.length_2 | |
y9 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['component'] = x9, y9 | |
# image | |
i = -2 | |
x10 = x6 + cos(radians(a2*i)) * self.length_2 | |
y10 = y6 + sin(radians(a2*i)) * self.length_2 | |
line((x6, y6), (x10, y10)) | |
self.positions['image'] = x10, y10 | |
# guideline | |
i = -1 | |
x11 = x6 + cos(radians(a2*i)) * self.length_2 | |
y11 = y6 + sin(radians(a2*i)) * self.length_2 | |
line((x6, y6), (x11, y11)) | |
self.positions['guideline'] = x11, y11 | |
# contour | |
i = 0 | |
x12 = x6 + cos(radians(a2*i)) * self.length_2 | |
y12 = y6 + sin(radians(a2*i)) * self.length_1 | |
self.positions['contour'] = x12, y12 | |
# point | |
a3_ = 0 | |
i = 2 | |
x13 = x12 + cos(radians(a3_+a3*i)) * self.length_3 | |
y13 = y12 + sin(radians(a3_+a3*i)) * self.length_3 | |
self.positions['point'] = x13, y13 | |
# bPoint | |
i = 1 | |
x14 = x12 + cos(radians(a3_+a3*i)) * self.length_3 | |
y14 = y12 + sin(radians(a3_+a3*i)) * self.length_3 | |
self.positions['bPoint'] = x14, y14 | |
# segment | |
i = 0 | |
x15 = x12 + cos(radians(a3_+a3*i)) * self.length_3 | |
y15 = y12 + sin(radians(a3_+a3*i)) * self.length_3 | |
self.positions['segment'] = x15, y15 | |
# randomize positions | |
if self.rand_range != 0: | |
for obj, (x, y) in self.positions.items(): | |
x += randint(-self.rand_range, self.rand_range) | |
y += randint(-self.rand_range, self.rand_range) | |
self.positions[obj] = x, y | |
def make_positions_landscape(self, (x, y)): | |
x0, y0 = x, y | |
a1 = 180/4 # font | |
a2 = 180/4 # glyph | |
a3 = 180/3.5 # contour | |
# font | |
self.positions['font'] = x0, y0 | |
# font lib | |
i = 2.0 | |
x1 = x0 + cos(radians(a1*i)) * self.length_2 | |
y1 = y0 + sin(radians(a1*i)) * self.length_2 | |
self.positions['font_lib'] = x1, y1 | |
# info | |
i += 1 | |
x2 = x0 + cos(radians(a1*i)) * self.length_2 | |
y2 = y0 + sin(radians(a1*i)) * self.length_2 | |
self.positions['info'] = x2, y2 | |
# kerning | |
i += 1 | |
x3 = x0 + cos(radians(a1*i)) * self.length_2 | |
y3 = y0 + sin(radians(a1*i)) * self.length_2 | |
self.positions['kerning'] = x3, y3 | |
# features | |
i += 1 | |
x4 = x0 + cos(radians(a1*i)) * self.length_2 | |
y4 = y0 + sin(radians(a1*i)) * self.length_2 | |
self.positions['features'] = x4, y4 | |
# layer | |
x5 = x0 + self.length_1 | |
y5 = y0 | |
self.positions['layer'] = x5, y5 | |
# glyph | |
x6 = x5 + self.length_1 | |
y6 = y5 #- self.length_2 | |
self.positions['glyph'] = x6, y6 | |
# glyph_lib | |
i = 2.5 | |
x7 = x6 + cos(radians(a2*i)) * self.length_2 | |
y7 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['glyph_lib'] = x7, y7 | |
# anchor | |
i = 1.5 | |
x8 = x6 + cos(radians(a2*i)) * self.length_2 | |
y8 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['anchor'] = x8, y8 | |
# component | |
i = 0.5 | |
x9 = x6 + cos(radians(a2*i)) * self.length_2 | |
y9 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['component'] = x9, y9 | |
# image | |
i = -0.5 | |
x10 = x6 + cos(radians(a2*i)) * self.length_2 | |
y10 = y6 + sin(radians(a2*i)) * self.length_2 | |
line((x6, y6), (x10, y10)) | |
self.positions['image'] = x10, y10 | |
# guideline | |
i = -1.5 | |
x11 = x6 + cos(radians(a2*i)) * self.length_2 | |
y11 = y6 + sin(radians(a2*i)) * self.length_2 | |
line((x6, y6), (x11, y11)) | |
self.positions['guideline'] = x11, y11 | |
# contour | |
i = -2.5 | |
x12 = x6 + cos(radians(a2*i)) * self.length_2 | |
y12 = y6 + sin(radians(a2*i)) * self.length_2 | |
self.positions['contour'] = x12, y12 | |
# point | |
a3_ = -77 | |
i = -2 | |
x13 = x12 + cos(radians(a3_+a3*i)) * self.length_3 | |
y13 = y12 + sin(radians(a3_+a3*i)) * self.length_3 | |
self.positions['point'] = x13, y13 | |
# bPoint | |
i += 1 | |
x14 = x12 + cos(radians(a3_+a3*i)) * self.length_3 | |
y14 = y12 + sin(radians(a3_+a3*i)) * self.length_3 | |
self.positions['bPoint'] = x14, y14 | |
# segment | |
i += 1 | |
x15 = x12 + cos(radians(a3_+a3*i)) * self.length_3 | |
y15 = y12 + sin(radians(a3_+a3*i)) * self.length_3 | |
self.positions['segment'] = x15, y15 | |
# randomize positions | |
if self.rand_range != 0: | |
for obj, (x, y) in self.positions.items(): | |
x += randint(-self.rand_range, self.rand_range) | |
y += randint(-self.rand_range, self.rand_range) | |
self.positions[obj] = x, y | |
def draw_lines(self): | |
save() | |
stroke(*self.lines_stroke_color) | |
strokeWidth(self.lines_stroke_width) | |
lineDash(self.lines_dash) | |
lineCap('round') | |
for obj_1, obj_2 in self.lines: | |
line(self.positions[obj_1], self.positions[obj_2]) | |
restore() | |
def draw_circles(self): | |
save() | |
stroke(*self.circles_stroke_color) | |
strokeWidth(self.circles_stroke_width) | |
shadow((2, -5), blur=15, color=(0, 0.25)) | |
for obj, pos in self.positions.items(): | |
if obj not in ['font', 'glyph']: | |
r = self.radius_1 | |
else: | |
r = self.radius_2 | |
x = pos[0] - r | |
y = pos[1] - r | |
# c = Color.NewFromHsl(*self.colors[obj]) | |
c = self.colors[obj] | |
fill(*c.rgb) | |
oval(x, y, r*2, r*2) | |
restore() | |
def draw_captions(self): | |
fill(1) | |
shadow((2, -2), blur=5, color=(0, 0.3)) | |
font(self.font) | |
for obj in self.positions.keys(): | |
x, y = self.positions[obj] | |
if obj not in ['font', 'glyph']: | |
r = self.radius_1 | |
fontSize(self.font_size_1) | |
h = r-self.font_size_1*-0.6 | |
else: | |
r = self.radius_2 | |
fontSize(self.font_size_2) | |
h = r-self.font_size_2*-0.65 | |
if len(obj.split('_')) > 1: | |
obj = obj.split('_')[-1] | |
textBox(obj, (x-r, y-r, r*2, h), align='center') | |
def draw(self, (x, y)): | |
if not self.landscape: | |
self.make_positions((x, y)) | |
else: | |
self.make_positions_landscape((x, y)) | |
self.draw_lines() | |
self.draw_circles() | |
self.draw_captions() | |
Variable([ | |
dict(name="radius_1", ui="Slider", args=dict(value=60, minValue=30, maxValue=100)), | |
dict(name="radius_2", ui="Slider", args=dict(value=120, minValue=50, maxValue=200)), | |
dict(name="length_1", ui="Slider", args=dict(value=190, minValue=80, maxValue=300)), | |
dict(name="length_2", ui="Slider", args=dict(value=210, minValue=80, maxValue=300)), | |
dict(name="length_3", ui="Slider", args=dict(value=190, minValue=80, maxValue=300)), | |
dict(name="randomness", ui="Slider", args=dict(value=0, minValue=0, maxValue=20)), | |
dict(name="landscape", ui="CheckBox", args=dict(value=False)), | |
dict(name="draw_swatches", ui="CheckBox", args=dict(value=False)), | |
], globals()) | |
M = FontPartsMap() | |
M.radius_1 = radius_1 | |
M.radius_2 = radius_2 | |
M.length_1 = length_1 | |
M.length_2 = length_2 | |
M.length_3 = length_3 | |
M.landscape = landscape | |
M.lines_stroke_color = 0.7, | |
M.lines_stroke_width = 4 | |
M.lines_dash = 2, 7 | |
M.circles_stroke_color = 0, | |
M.circles_stroke_width = 0 | |
M.rand_range = int(randomness) | |
if landscape: | |
newPage('A4Landscape') | |
else: | |
newPage('A4') | |
fill(1) | |
rect(0, 0, width(), height()) | |
#--------------- | |
# color palette | |
#--------------- | |
colors = [ | |
M.colors.keys()[:5], | |
M.colors.keys()[6:13], | |
M.colors.keys()[12:], | |
[M.colors.keys()[0], M.colors.keys()[5], M.colors.keys()[6]], | |
] | |
colors_new = OrderedDict() | |
colors_new['font'] = Color.NewFromHsl(*M.colors['font']) | |
colors_new['glyph'] = Color.NewFromHsl(*M.colors['glyph']) | |
c1 = colors_new['font'] | |
c2 = colors_new['glyph'] | |
for i, obj in enumerate(colors[0][1:]): | |
color = c1.ColorWithHue(c1.hue + (i+1)*25) | |
colors_new[obj] = color | |
for i, obj in enumerate(colors[1][1:]): | |
color = c2.ColorWithHue(c2.hue - (i+1)*15) | |
colors_new[obj] = color | |
c3 = colors_new['contour'] | |
for i, obj in enumerate(colors[2][1:]): | |
color = c3.ColorWithHue(c3.hue - (i+1)*20) | |
colors_new[obj] = color | |
colors_new['layer'] = c1.Blend(c2, percent=0.5) | |
if draw_swatches: | |
x, y = 20, 130 | |
s = 30 | |
m = 4 | |
shadow(None) | |
save() | |
translate(x, y) | |
for i, color_set in enumerate(colors): | |
save() | |
for obj in color_set: | |
c = colors_new[obj] | |
fill(*c.rgb) | |
rect(0, 0, s, s) | |
translate(s+m, 0) | |
restore() | |
translate(0, -s-m) | |
if i == len(colors)-2: | |
translate(0, -m*2) | |
restore() | |
M.colors = colors_new | |
if landscape: | |
scale(0.76) | |
x, y = 336, 470 | |
else: | |
scale(0.76) | |
x, y = 299, 800 | |
M.draw((x, y)) | |
# save image | |
import os | |
folder = os.getcwd() | |
img_paths = [ | |
os.path.join(folder, 'fontparts-map.svg'), | |
os.path.join(folder, 'fontparts-map.png'), | |
] | |
saveImage(img_paths) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment