├── examples
├── nounfont.eot
├── nounfont
│ ├── plant-tree.svg
│ ├── happines.svg
│ ├── riots.svg
│ ├── energy.svg
│ ├── trade.svg
│ ├── rockets.svg
│ ├── economics.svg
│ ├── survalance.svg
│ ├── soft-tree.svg
│ ├── spy.svg
│ ├── aircaft.svg
│ ├── energy2.svg
│ ├── applied-science.svg
│ ├── peace.svg
│ ├── factory.svg
│ ├── old-library.svg
│ ├── wind-energy.svg
│ ├── diomand-science.svg
│ ├── global-map.svg
│ ├── city-planning.svg
│ ├── monument.svg
│ ├── code-of-laws.svg
│ ├── radiation.svg
│ ├── economics2.svg
│ ├── police.svg
│ ├── scientific-method.svg
│ ├── naval-tech.svg
│ ├── electro-fuels.svg
│ ├── gps.svg
│ ├── child-care.svg
│ ├── ecology.svg
│ ├── fossle-fuel.svg
│ ├── engenearing.svg
│ ├── nuclear.svg
│ ├── monetary.svg
│ ├── bio-fuels.svg
│ ├── idea.svg
│ ├── monetary-ethics.svg
│ ├── holo-theater.svg
│ ├── fingerprint.svg
│ ├── resycle.svg
│ ├── basic-mecanics.svg
│ ├── bio-mecanics.svg
│ ├── mine.svg
│ ├── advanced-mecanics.svg
│ ├── communication-tower.svg
│ ├── comunity.svg
│ ├── solar-energy.svg
│ ├── bio-tree.svg
│ ├── brain-agumentation.svg
│ ├── social-services.svg
│ ├── rail-building.svg
│ ├── protest.svg
│ ├── genetics.svg
│ └── human-brain.svg
├── nounfont.html
├── nounfont.css
└── nounfont.svg
├── .gitignore
├── README.md
└── icons2font.py
/examples/nounfont.eot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[co]
2 |
3 | # Packages
4 | *.egg
5 | *.egg-info
6 | dist
7 | build
8 | eggs
9 | parts
10 | bin
11 | var
12 | sdist
13 | develop-eggs
14 | .installed.cfg
15 |
16 | # Installer logs
17 | pip-log.txt
18 |
19 | # Unit test / coverage reports
20 | .coverage
21 | .tox
22 |
23 | #Translations
24 | *.mo
25 |
26 | #Mr Developer
27 | .mr.developer.cfg
28 |
--------------------------------------------------------------------------------
/examples/nounfont/plant-tree.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/happines.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/riots.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/energy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/trade.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/rockets.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/examples/nounfont/economics.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/survalance.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/soft-tree.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/spy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/aircaft.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
--------------------------------------------------------------------------------
/examples/nounfont/energy2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | icons2font
2 | ==========
3 |
4 | This utility takes vector icons in svg format and convert them to icon fonts (svg,ttf,waff,eot) to be display in all browsers.
5 |
6 |
7 | Usage
8 | =====
9 |
10 |
11 | icons2font.py [-h] [--baseline BASELINE] name src [dest]
12 |
13 | This utility takes vector icons in svg format and converts them to icon fonts
14 | (svg,ttf,waff,eot) to be display in all browsers.
15 |
16 | positional arguments:
17 | name name of the icon font you want
18 | src folder wher the svg glyphs are
19 | dest folder to output the stuff
20 |
21 | optional arguments:
22 | -h, --help show this help message and exit
23 | --baseline BASELINE adjust generated chars up or down
24 |
25 | example
26 | -------
27 | python icons2font.py my_awesome_font ~/some_svgs ~/i2f_output --baseline 2
28 |
29 |
30 |
31 | Requirements
32 | ============
33 |
34 | * fontforge (with python library)
35 | * ttf2eot
36 |
37 |
38 | Mac installation
39 | ----------------
40 | brew install fontforge ttf2eot
41 |
--------------------------------------------------------------------------------
/examples/nounfont/applied-science.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
--------------------------------------------------------------------------------
/examples/nounfont/peace.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
--------------------------------------------------------------------------------
/examples/nounfont/factory.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
--------------------------------------------------------------------------------
/examples/nounfont/old-library.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/wind-energy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
--------------------------------------------------------------------------------
/examples/nounfont/diomand-science.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/global-map.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
--------------------------------------------------------------------------------
/examples/nounfont/city-planning.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/monument.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/code-of-laws.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/radiation.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
--------------------------------------------------------------------------------
/examples/nounfont/economics2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/police.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/scientific-method.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
--------------------------------------------------------------------------------
/examples/nounfont/naval-tech.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
--------------------------------------------------------------------------------
/examples/nounfont/electro-fuels.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
--------------------------------------------------------------------------------
/examples/nounfont/gps.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
--------------------------------------------------------------------------------
/examples/nounfont/child-care.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
--------------------------------------------------------------------------------
/examples/nounfont/ecology.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/fossle-fuel.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
--------------------------------------------------------------------------------
/examples/nounfont/engenearing.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/nuclear.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
22 |
--------------------------------------------------------------------------------
/examples/nounfont/monetary.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
--------------------------------------------------------------------------------
/examples/nounfont/bio-fuels.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
--------------------------------------------------------------------------------
/examples/nounfont/idea.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/monetary-ethics.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
20 |
--------------------------------------------------------------------------------
/examples/nounfont/holo-theater.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/fingerprint.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/resycle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
--------------------------------------------------------------------------------
/examples/nounfont/basic-mecanics.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
26 |
--------------------------------------------------------------------------------
/examples/nounfont/bio-mecanics.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/mine.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
27 |
--------------------------------------------------------------------------------
/examples/nounfont/advanced-mecanics.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/communication-tower.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/comunity.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/solar-energy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
34 |
--------------------------------------------------------------------------------
/examples/nounfont/bio-tree.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/examples/nounfont.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
18 | Font: nounfont
19 |
20 | icon-advanced-mecanics
21 | icon-aircaft
22 | icon-applied-science
23 | icon-basic-mecanics
24 | icon-bio-fuels
25 | icon-bio-mecanics
26 | icon-bio-tree
27 | icon-brain-agumentation
28 | icon-child-care
29 | icon-city-planning
30 | icon-code-of-laws
31 | icon-communication-tower
32 | icon-comunity
33 | icon-diomand-science
34 | icon-ecology
35 | icon-economics
36 | icon-economics2
37 | icon-electro-fuels
38 | icon-energy
39 | icon-energy2
40 | icon-engenearing
41 | icon-factory
42 | icon-fingerprint
43 | icon-fossle-fuel
44 | icon-genetics
45 | icon-global-map
46 | icon-gps
47 | icon-happines
48 | icon-holo-theater
49 | icon-human-brain
50 | icon-idea
51 | icon-mine
52 | icon-monetary-ethics
53 | icon-monetary
54 | icon-monument
55 | icon-naval-tech
56 | icon-nuclear
57 | icon-old-library
58 | icon-peace
59 | icon-plant-tree
60 | icon-police
61 | icon-protest
62 | icon-radiation
63 | icon-rail-building
64 | icon-resycle
65 | icon-riots
66 | icon-rockets
67 | icon-scientific-method
68 | icon-social-services
69 | icon-soft-tree
70 | icon-solar-energy
71 | icon-spy
72 | icon-survalance
73 | icon-trade
74 | icon-wind-energy
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/examples/nounfont/brain-agumentation.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
36 |
--------------------------------------------------------------------------------
/examples/nounfont/social-services.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
47 |
--------------------------------------------------------------------------------
/examples/nounfont.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face {
3 | font-family: "nounfont";
4 | src: url('nounfont.svg') format('svg');
5 | font-weight: normal;
6 | font-style: normal;
7 | }
8 |
9 |
10 | [class^="icon-"]:before, [class*=" icon-"]:before {
11 | font-family: nounfont;
12 | font-weight: normal;
13 | font-style: normal;
14 | display: inline-block;
15 | text-decoration: inherit;
16 | }
17 | .icon-advanced-mecanics::before {
18 | content: "\f000";
19 | }
20 | .icon-aircaft::before {
21 | content: "\f001";
22 | }
23 | .icon-applied-science::before {
24 | content: "\f002";
25 | }
26 | .icon-basic-mecanics::before {
27 | content: "\f003";
28 | }
29 | .icon-bio-fuels::before {
30 | content: "\f004";
31 | }
32 | .icon-bio-mecanics::before {
33 | content: "\f005";
34 | }
35 | .icon-bio-tree::before {
36 | content: "\f006";
37 | }
38 | .icon-brain-agumentation::before {
39 | content: "\f007";
40 | }
41 | .icon-child-care::before {
42 | content: "\f008";
43 | }
44 | .icon-city-planning::before {
45 | content: "\f009";
46 | }
47 | .icon-code-of-laws::before {
48 | content: "\f00a";
49 | }
50 | .icon-communication-tower::before {
51 | content: "\f00b";
52 | }
53 | .icon-comunity::before {
54 | content: "\f00c";
55 | }
56 | .icon-diomand-science::before {
57 | content: "\f00d";
58 | }
59 | .icon-ecology::before {
60 | content: "\f00e";
61 | }
62 | .icon-economics::before {
63 | content: "\f00f";
64 | }
65 | .icon-economics2::before {
66 | content: "\f010";
67 | }
68 | .icon-electro-fuels::before {
69 | content: "\f011";
70 | }
71 | .icon-energy::before {
72 | content: "\f012";
73 | }
74 | .icon-energy2::before {
75 | content: "\f013";
76 | }
77 | .icon-engenearing::before {
78 | content: "\f014";
79 | }
80 | .icon-factory::before {
81 | content: "\f015";
82 | }
83 | .icon-fingerprint::before {
84 | content: "\f016";
85 | }
86 | .icon-fossle-fuel::before {
87 | content: "\f017";
88 | }
89 | .icon-genetics::before {
90 | content: "\f018";
91 | }
92 | .icon-global-map::before {
93 | content: "\f019";
94 | }
95 | .icon-gps::before {
96 | content: "\f01a";
97 | }
98 | .icon-happines::before {
99 | content: "\f01b";
100 | }
101 | .icon-holo-theater::before {
102 | content: "\f01c";
103 | }
104 | .icon-human-brain::before {
105 | content: "\f01d";
106 | }
107 | .icon-idea::before {
108 | content: "\f01e";
109 | }
110 | .icon-mine::before {
111 | content: "\f01f";
112 | }
113 | .icon-monetary-ethics::before {
114 | content: "\f020";
115 | }
116 | .icon-monetary::before {
117 | content: "\f021";
118 | }
119 | .icon-monument::before {
120 | content: "\f022";
121 | }
122 | .icon-naval-tech::before {
123 | content: "\f023";
124 | }
125 | .icon-nuclear::before {
126 | content: "\f024";
127 | }
128 | .icon-old-library::before {
129 | content: "\f025";
130 | }
131 | .icon-peace::before {
132 | content: "\f026";
133 | }
134 | .icon-plant-tree::before {
135 | content: "\f027";
136 | }
137 | .icon-police::before {
138 | content: "\f028";
139 | }
140 | .icon-protest::before {
141 | content: "\f029";
142 | }
143 | .icon-radiation::before {
144 | content: "\f02a";
145 | }
146 | .icon-rail-building::before {
147 | content: "\f02b";
148 | }
149 | .icon-resycle::before {
150 | content: "\f02c";
151 | }
152 | .icon-riots::before {
153 | content: "\f02d";
154 | }
155 | .icon-rockets::before {
156 | content: "\f02e";
157 | }
158 | .icon-scientific-method::before {
159 | content: "\f02f";
160 | }
161 | .icon-social-services::before {
162 | content: "\f030";
163 | }
164 | .icon-soft-tree::before {
165 | content: "\f031";
166 | }
167 | .icon-solar-energy::before {
168 | content: "\f032";
169 | }
170 | .icon-spy::before {
171 | content: "\f033";
172 | }
173 | .icon-survalance::before {
174 | content: "\f034";
175 | }
176 | .icon-trade::before {
177 | content: "\f035";
178 | }
179 | .icon-wind-energy::before {
180 | content: "\f036";
181 | }
182 |
--------------------------------------------------------------------------------
/examples/nounfont/rail-building.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/nounfont/protest.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
42 |
--------------------------------------------------------------------------------
/examples/nounfont/genetics.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
47 |
--------------------------------------------------------------------------------
/examples/nounfont/human-brain.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
--------------------------------------------------------------------------------
/icons2font.py:
--------------------------------------------------------------------------------
1 | """
2 | This utility takes vector icons in svg format and converts
3 | them to icon fonts (svg,ttf,waff,eot) to be display in all browsers.
4 |
5 | requires python-fontforge
6 | """
7 | import sys
8 | import os
9 | import argparse
10 | from xml.dom import minidom
11 | import md5
12 |
13 | DESIGNER_FONT_START_CHAR = "A"
14 | GSIZE = 1400
15 |
16 |
17 | HEADER = """
18 |
19 |
35 | """
36 |
37 | DOC_HEADER = """
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
67 |
68 |
69 | Font: {0}
70 | """
71 | DOC_FOOTER = """
72 |
73 | try out and download desinger font
74 |
75 |
76 |
77 | """
78 |
79 | # src: url('{0}.eot');
80 | # src: url('{0}.eot#iefix') format('embedded-opentype'),
81 | # url('{0}.ttf') format('truetype'),
82 | # url('{0}.woff') format('woff'),
83 | # url('{0}.svg') format('svg'),
84 | # url('{0}.otf') format("opentype");
85 |
86 |
87 | CSS_HEADER = """@font-face {{
88 | font-family: "{0}";
89 | src: url('{0}.eot?h={2}');
90 | src: url('{0}.eot?h={2}#iefix') format('embedded-opentype'),
91 | url('{0}.ttf?h={2}') format('truetype'),
92 | url('{0}.woff?h={2}') format('woff'),
93 | url('{0}.svg?h={2}') format('svg'),
94 | url('{0}.otf?h={2}') format("opentype");
95 | font-weight: normal;
96 | font-style: normal;
97 | font-feature-settings: "calt=0,liga=0"
98 | }}
99 | [class^="{1}-"], [class*=" {1}-"] {{
100 | font-family: {0};
101 | font-weight: normal;
102 | font-style: normal;
103 | display: inline-block;
104 | text-decoration: inherit;
105 | vertical-align: baseline;
106 | -webkit-font-smoothing: antialiased;
107 | }}
108 | """
109 |
110 | USER_AREA = 0xf000
111 |
112 | COMMANDS_ABS = "MZLHVCSQTA"
113 | COMMANDS_REL = COMMANDS_ABS.lower()
114 | COMMANDS = COMMANDS_ABS + COMMANDS_REL
115 |
116 | def between(a, b, s):
117 | first = s.find(a)
118 | first += len(a)
119 | last = s.find(b, first)
120 | return s[first:last]
121 |
122 | def htmlhex(n):
123 | return hex(n).replace("0x","") + ";"
124 |
125 | def svg_paths(svg):
126 | xmldoc = minidom.parseString(svg)
127 | paths = []
128 |
129 | # view box
130 | for s in xmldoc.getElementsByTagName('svg'):
131 | try:
132 | viewBox = map(float, s.attributes['viewBox'].value.split())
133 | except:
134 |
135 | viewBox = [0,0,
136 | float(s.attributes['width'].value),
137 | float(s.attributes['height'].value)]
138 | # width="100" height="100"
139 |
140 | for s in xmldoc.getElementsByTagName('path'):
141 | d = s.attributes['d'].value
142 | paths.append(d)
143 |
144 |
145 | for s in xmldoc.getElementsByTagName('polygon'):
146 | d = s.attributes['points'].value
147 | paths.append("M"+d)
148 |
149 | for s in xmldoc.getElementsByTagName('rect'):
150 | try: x = float(s.attributes['x'].value)
151 | except: x = 0
152 | try: y = float(s.attributes['y'].value)
153 | except: y = 0
154 |
155 | w = float(s.attributes['width'].value)
156 | h = float(s.attributes['height'].value)
157 | p = ["M",x,y, x+w,y, x+w,y+h, x,y+h, x,y, "Z"]
158 | paths.append(" ".join(map(str,p)))
159 |
160 | for s in xmldoc.getElementsByTagName('circle'):
161 | cx = float(s.attributes['cx'].value)
162 | cy = float(s.attributes['cy'].value)
163 | r = float(s.attributes['r'].value)
164 | p =["M", cx-r, cy,
165 | "a", r,r, 0, 1,0, (r*2),0,
166 | "a", r,r, 0, 1,0, -(r*2),0,
167 | "Z"]
168 | paths.append(" ".join(map(str,p)))
169 |
170 | x = cx-r
171 | y = cy-r
172 | w = 2*r
173 | h = 2*r
174 |
175 | p = ["M",x,y, x+w,y, x+w,y+h, x,y+h, x,y, "Z"]
176 | #paths.append(" ".join(map(str,p)))
177 |
178 |
179 | return viewBox, paths
180 |
181 | def parse_path(path):
182 | commands = []
183 | command = []
184 | word = []
185 | for c in path:
186 | if c in COMMANDS:
187 | if word:
188 | command.append(float("".join(word)))
189 | word = []
190 | if command:
191 | commands.append(command)
192 | command = [c]
193 | elif c in " ,":
194 | if word:
195 | command.append(float("".join(word)))
196 | word = []
197 | elif c in "+-":
198 | if word:
199 | command.append(float("".join(word)))
200 | word = []
201 | word.append(c)
202 | else:
203 | word.append(c)
204 | if word:
205 | command.append(float("".join(word)))
206 | word = []
207 | if command:
208 | commands.append(command)
209 | return commands
210 |
211 | def compile_path(commands):
212 | buf = []
213 | for command in commands:
214 | buf.append(command[0])
215 | for n in command[1:]:
216 | buf.append(str(n))
217 | return " ".join(buf)
218 |
219 | def compute_minrec():
220 | minx, miny, maxx, maxy = None, None, None, None
221 | pen = [0,0]
222 | rec = [None, None, None, None]
223 | def min_rec():
224 | # min rec calculate
225 | if rec[0] is None or rec[0] > pen[0]: rec[0] = pen[0]
226 | if rec[1] is None or rec[1] > pen[1]: rec[1] = pen[1]
227 | if rec[2] is None or rec[2] < pen[0]: rec[2] = pen[0]
228 | if rec[3] is None or rec[3] < pen[1]: rec[3] = pen[1]
229 |
230 | for command in commands:
231 | op = command[0]
232 | print command
233 | if op in "VvHhAa":
234 | # account for the stupid direction commands
235 | for n in command[1:]:
236 | if op == "V":
237 | pen[0] = n
238 | elif op == "v":
239 | pen[0] += n
240 | if op == "H":
241 | pen[1] = n
242 | elif op == "h":
243 | pen[1] += n
244 | if op == "A":
245 | # arc command is insane
246 | pass
247 | elif op == "a":
248 | # arc command is insane
249 | pass
250 |
251 | min_rec()
252 | else:
253 | # all other commands
254 | for p in range((len(command)-1)/2):
255 | x = command[1+p*2]
256 | y = command[2+p*2]
257 | # move the pen
258 | if op in COMMANDS_REL:
259 | pen[0] += x
260 | pen[1] += y
261 | else:
262 | pen[0] = x
263 | pen[1] = y
264 |
265 | min_rec()
266 | print "min rectangle", rec
267 | minx, miny, maxx, maxy = rec
268 | tranx = -minx
269 | trany = -miny
270 | sizex = maxx - minx
271 | sizey = maxy - miny
272 |
273 |
274 | def do_glyph(data, glyphname, svg, baseline):
275 | """ converts a file into a svg glyph """
276 |
277 |
278 | viewBox, paths = svg_paths(data)
279 | # font needs to be of one path
280 | path = " ".join(paths)
281 | commands = parse_path(path)
282 |
283 | tranx, trany, sizex, sizey = viewBox
284 | tranx = -tranx
285 | trany = -trany
286 |
287 | trany -= baseline
288 |
289 | size = max(sizex, sizey)
290 | scale = GSIZE/size
291 |
292 | if size - sizey > 0:
293 | trany += (size - sizey)/2
294 | if size - sizex > 0:
295 | tranx += (size - sizex)/2
296 |
297 | #print "translate", tranx, trany, "scale", scale
298 |
299 | prev_op = None
300 | for command in commands:
301 | op = command[0]
302 |
303 | if op in "Aa":
304 | # arcs require special fancy scaling
305 | command[1] *= scale
306 | command[2] *= scale
307 | # presurve flags
308 | command[4] = int(command[4])
309 | command[5] = int(command[5])
310 | # scale the radii
311 | command[6] *= scale
312 | command[7] *= scale
313 | else:
314 | for i,num in enumerate(command):
315 | if num == op: continue
316 | if op in COMMANDS_ABS:
317 | if op == "H":
318 | command[i] *= scale
319 | command[i] += tranx * scale
320 | elif op == "V":
321 | command[i] *= -scale
322 | command[i] += -trany * scale + GSIZE
323 | else:
324 | if i % 2 == 1:
325 | command[i] *= scale
326 | command[i] += tranx * scale
327 | else:
328 | command[i] *= -scale
329 | command[i] += -trany * scale + GSIZE
330 | else:
331 | if op in "h":
332 | command[i] *= scale
333 | elif op in "v":
334 | command[i] *= -scale
335 | else:
336 | if i % 2 == 1:
337 | command[i] *= scale
338 | else:
339 | command[i] *= -scale
340 | # special case for first relative m (its just like abs M)
341 | if op == "m" and prev_op == None:
342 | command[1] += tranx * scale
343 | command[2] += -trany * scale + GSIZE
344 | prev_op = op
345 |
346 | #commands.insert(0, ['M', tranx*scale, -trany*scale])
347 |
348 | path = compile_path(commands)
349 | #print "final path", path
350 | svg.write(GLYPH.format(glyphname, path))
351 |
352 |
353 | #svg.write(GLYPH.format(glyphname, path))
354 |
355 | def gen_svg_font(glyph_files, output_dir, font_name, glyph_name, args):
356 |
357 | svg = open(output_dir + font_name + ".svg",'w')
358 | svg.write(HEADER.format(font_name, args.scale, args.ascent, args.descent))
359 |
360 | # use the special unicode user area for char encoding
361 | index = 0
362 | #current = ord("a")
363 | for f in glyph_files:
364 | #glyphname = font_name + "-" + f.replace(".svg","").replace("_","-").replace(" ","-").lower()
365 | glyphname = htmlhex(index)
366 |
367 | data = open(f).read()
368 | #artname = chr(current)
369 | do_glyph(data, glyph_name(index), svg, args.baseline)
370 |
371 | index += 1
372 |
373 | svg.write(FOOTER)
374 | svg.flush()
375 | svg.close()
376 |
377 |
378 | def gen_css_for_font(glyph_files, output_dir, font_name, prefix, hash):
379 | css = open(output_dir + font_name + ".css",'w')
380 | css.write(CSS_HEADER.format(font_name, prefix, hash))
381 |
382 | for index, f in enumerate(glyph_files):
383 | glyph_name = prefix + "-" + f.split("/")[-1].replace(".svg", "")
384 | css.write(
385 | '.{0}:before {{\n content: "\{1:04x}";\n}}\n'.format(
386 | glyph_name,
387 | USER_AREA + index))
388 |
389 |
390 | def gen_html_for_font(glyph_files, output_dir, font_name, prefix):
391 | doc = open(output_dir + font_name + ".html",'w')
392 | doc.write(DOC_HEADER.format(font_name))
393 |
394 | art_names = []
395 | for index, f in enumerate(glyph_files):
396 | glyph_name = prefix + "-" + f.split("/")[-1].replace(".svg", "")
397 | art_name = chr(ord(DESIGNER_FONT_START_CHAR) + index)
398 | art_names.append(art_name)
399 | doc.write(" {0} ({1})
\n".format(
400 | glyph_name, art_name))
401 |
402 |
403 | doc.write(DOC_FOOTER.format(font_name, " ".join(art_names)))
404 |
405 |
406 | def main():
407 | parser = argparse.ArgumentParser(description=__doc__)
408 |
409 | parser.add_argument('name', type=str, help="name of the icon font you want")
410 | parser.add_argument('src', type=str, help="folder wher the svg glyphs are")
411 | parser.add_argument('dest', type=str, help="folder to output the stuff", nargs="?")
412 | parser.add_argument('--prefix', type=str, help="prefix for the css class names")
413 |
414 | parser.add_argument('--scale', type=int, help="size of chars", default=2048)
415 | parser.add_argument('--ascent', type=int, help="ascent", default=1536)
416 | parser.add_argument('--descent', type=int, help="descent", default=512)
417 | parser.add_argument('--baseline', type=int, help="adjust chars up or down", default=512)
418 |
419 |
420 |
421 | args = parser.parse_args()
422 |
423 |
424 | font_name = args.name
425 | input_dir = args.src
426 | output_dir = args.dest
427 | if not output_dir:
428 | output_dir = font_name + "/"
429 | prefix = args.prefix
430 | if not prefix:
431 | prefix = font_name
432 |
433 | # make sure output dir exists
434 | try:
435 | os.makedirs(output_dir)
436 | except:
437 | pass
438 |
439 | glyph_files = []
440 | for f in sorted(os.listdir(input_dir)):
441 | if not f.endswith(".svg"):
442 | continue
443 | glyph_files.append(input_dir+"/"+f)
444 |
445 | # generate browser svg font
446 | gen_svg_font(
447 | glyph_files,
448 | output_dir,
449 | font_name,
450 | glyph_name=lambda i:htmlhex(i + USER_AREA),
451 | args=args,
452 | )
453 |
454 | # generate designer svg font
455 | gen_svg_font(
456 | glyph_files,
457 | output_dir,
458 | font_name+"-designer",
459 | glyph_name=lambda i:chr(i+ord(DESIGNER_FONT_START_CHAR)),
460 | args=args
461 | )
462 |
463 | # get file hash
464 | hash = md5.new(open(output_dir+font_name+".svg").read()).hexdigest()[:5]
465 |
466 | # generate css
467 | gen_css_for_font(
468 | glyph_files,
469 | output_dir,
470 | font_name,
471 | prefix,
472 | hash
473 | )
474 |
475 | # generate sample html
476 | gen_html_for_font(
477 | glyph_files,
478 | output_dir,
479 | font_name,
480 | prefix
481 | )
482 |
483 | # make ttf, woff, off, and eot browser fonts
484 | import fontforge
485 | font = fontforge.open(output_dir + font_name + ".svg")
486 | font.generate(output_dir + font_name + ".ttf")
487 | font.generate(output_dir + font_name + ".woff")
488 | font.generate(output_dir + font_name + ".otf")
489 | os.system("ttf2eot {0}.ttf > {0}.eot".format(output_dir + font_name))
490 |
491 | # make designer ttf
492 | font = fontforge.open(output_dir + font_name + "-designer.svg")
493 | font.generate(output_dir + font_name + "-designer.ttf")
494 |
495 |
496 | if __name__ == "__main__":
497 | main()
498 |
--------------------------------------------------------------------------------
/examples/nounfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
126 |
--------------------------------------------------------------------------------