Skip to content

Commit 93f90ae

Browse files
authored
Merge pull request #8 from creativecommons/genicons
Genicons
2 parents bfe25d3 + f4a305c commit 93f90ae

File tree

5 files changed

+235
-0
lines changed

5 files changed

+235
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Vim
2+
*.swp

README.md

+35
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,38 @@ Creative Commons badges, license Buttons, etc. (<https://licensebuttons.net/>).
55

66
:warning: **Consolidation/Update in progress. This repository is in a state of
77
flux.**
8+
9+
10+
## genicons.py
11+
12+
This is a script to generate Creative Commons icon badges in png format in a
13+
variety of color schemes. These icons can then be served by a web server. It is
14+
located at [`scripts/genicons.py`](scripts/genicons.py).
15+
16+
17+
### Install
18+
19+
1. Assuming the repository is on Debian
20+
2. Install required Python 2 packages:
21+
22+
```shell
23+
sudo apt-get install python-cairo python-gtk2
24+
```
25+
26+
3. Install CC Icons font
27+
28+
```shell
29+
mkdir -p ~/.fonts
30+
ln -sf ${PWD}/www/cc-icons.ttf ~/.fonts/
31+
```
32+
33+
34+
### Usage
35+
36+
Execute with Python 2:
37+
38+
```shell
39+
python genicons.py
40+
```
41+
42+
This will generate the icons in the directory `www/i` directory.

scripts/genicons.py

+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# genicons.py - generate all the icons.
2+
# Copyright 2016 Creative Commons Corporation.
3+
4+
# Standard library
5+
import errno
6+
import math
7+
import os
8+
import os.path
9+
10+
# Third-party
11+
import cairo
12+
import pangocairo
13+
14+
15+
SUITES = {
16+
"l": {
17+
"by": ["b"],
18+
"by-nc": ["bn", "be", "by"],
19+
"by-nd": ["bd"],
20+
"by-sa": ["ba"],
21+
"by-nc-nd": ["bnd", "bed", "byd"],
22+
"by-nc-sa": ["bna", "bea", "bya"],
23+
},
24+
"p": {"cc-zero": ["0"], "public-domain-mark": ["p"]},
25+
}
26+
27+
DIMENSIONS = ((88, 31, 31, 1), (80, 15, 15, 4), (76, 22, 22, 1))
28+
29+
BACKGROUNDS = (
30+
"transparent",
31+
"000000",
32+
# Bootstrap well grey
33+
"eeeeee",
34+
"ffffff",
35+
)
36+
37+
STEPS = ["00", "11", "22", "33", "66", "99", "ff"]
38+
39+
FOREGROUNDS = [
40+
"%s%s%s" % (r, g, b) for r in STEPS for g in STEPS for b in STEPS
41+
]
42+
43+
HEX_TO_FLOAT = 1.0 / 255.0
44+
45+
46+
def hexToFloat(digits):
47+
return HEX_TO_FLOAT * int(digits, 16)
48+
49+
50+
def setColor(ctx, color_string):
51+
if color_string == "transparent":
52+
ctx.set_source_rgba(0.0, 0.0, 0.0, 0.0)
53+
else:
54+
ctx.set_source_rgb(
55+
hexToFloat(color_string[0:2]),
56+
hexToFloat(color_string[2:4]),
57+
hexToFloat(color_string[4:6]),
58+
)
59+
60+
61+
def sizeChars(ctx, chars):
62+
# x, y, width, height, dx, dy
63+
return [ctx.text_extents(char) for char in chars]
64+
65+
66+
def showChars(ctx, chars, foreground, padding, width, height):
67+
sizes = sizeChars(ctx, chars)
68+
total_padding = padding * (len(chars) - 1)
69+
total_width = reduce(lambda x, y: y[3] + x, sizes, 0.0)
70+
x = 0.5 + math.ceil((width / 2) - ((total_width + total_padding) / 2))
71+
y = math.ceil(height / 2) + math.floor(sizes[0][3] / 2)
72+
setColor(ctx, foreground)
73+
for char, size in zip(chars, sizes):
74+
ctx.move_to(math.ceil(x), math.ceil(y))
75+
ctx.show_text(char)
76+
x += size[2] + padding
77+
ctx.stroke()
78+
79+
80+
def createContext(width, height):
81+
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
82+
context = cairo.Context(surface)
83+
ctx = pangocairo.CairoContext(context)
84+
return ctx
85+
86+
87+
def setBackground(ctx, background, width, height):
88+
setColor(ctx, background)
89+
ctx.rectangle(0, 0, width, height)
90+
ctx.fill()
91+
92+
93+
def configureFont(ctx, size):
94+
ctx.select_font_face("CC Icons")
95+
ctx.set_font_size(size)
96+
97+
98+
def iconFilename(dimensions, characters):
99+
filename = "%ix%i" % (dimensions[0], dimensions[1])
100+
if "y" in characters:
101+
filename += "-y"
102+
elif "e" in characters:
103+
filename += "-e"
104+
return filename + ".png"
105+
106+
107+
def iconPath(suite, descriptor, background, foreground):
108+
foreground_path = os.path.join(
109+
foreground[0:2], foreground[2:4], foreground[4:6]
110+
)
111+
return os.path.join(suite, descriptor, background, foreground_path)
112+
113+
114+
def genicon(
115+
suite,
116+
characters,
117+
font_size,
118+
padding,
119+
width,
120+
height,
121+
background,
122+
foreground,
123+
):
124+
ctx = createContext(width, height)
125+
setBackground(ctx, background, width, height)
126+
configureFont(ctx, font_size)
127+
showChars(ctx, characters, foreground, padding, width, height)
128+
return ctx
129+
130+
131+
font_map = pangocairo.cairo_font_map_get_default()
132+
font_families = [family.get_name() for family in font_map.list_families()]
133+
if "CC Icons" not in font_families:
134+
raise Exception(
135+
"CC Icons font not installed. See" " <https://wiki.debian.org/Fonts>."
136+
)
137+
138+
script_dir = os.path.dirname(__file__)
139+
basedir = os.path.realpath(
140+
os.path.abspath(os.path.join(script_dir, "..", "www", "i"))
141+
)
142+
print "# basedir:", basedir
143+
144+
for suite, licenses in SUITES.iteritems():
145+
for lic, module_chars in licenses.iteritems():
146+
for chars in module_chars:
147+
for dimensions in DIMENSIONS:
148+
for background in BACKGROUNDS:
149+
for foreground in FOREGROUNDS:
150+
# e.g. white on white
151+
if foreground == background:
152+
continue
153+
path = os.path.realpath(
154+
os.path.abspath(
155+
os.path.join(
156+
basedir,
157+
iconPath(
158+
suite, lic, background, foreground
159+
),
160+
)
161+
)
162+
)
163+
filepath = os.path.realpath(
164+
os.path.abspath(
165+
os.path.join(
166+
path, iconFilename(dimensions, chars)
167+
)
168+
)
169+
)
170+
if os.path.exists(filepath):
171+
continue
172+
width = dimensions[0]
173+
height = dimensions[1]
174+
font_size = dimensions[2]
175+
padding = dimensions[3]
176+
ctx = genicon(
177+
suite,
178+
chars,
179+
font_size,
180+
padding,
181+
width,
182+
height,
183+
background,
184+
foreground,
185+
)
186+
try:
187+
os.makedirs(path)
188+
except OSError as e:
189+
if e.errno != errno.EEXIST:
190+
raise
191+
# Will raise and exception on error
192+
ctx.get_target().write_to_png(filepath)

www/cc-icons.ttf

6.76 KB
Binary file not shown.

www/i/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The contents of this directory are generated by genicons.py
2+
#
3+
# Ignore everything in this directory
4+
*
5+
# Except this file
6+
!.gitignore

0 commit comments

Comments
 (0)