forked from reticulatedpines/magiclantern_simplified
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmake-icons.py
223 lines (181 loc) · 6.19 KB
/
make-icons.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env python2
from PIL import Image
import os
import copy
W = 46
H = 42
# do not encode outer pixels, to save some RAM
Xpad = 3
Ypad = 4
Hpadded = H - Ypad*2
Wpadded = W - Xpad*2
icons = [
'audio.png',
'expo.png',
'overlay.png',
'movie.png',
'shoot.png',
'focus.png',
'display.png',
'prefs.png',
'debug.png',
'info.png',
'mymenu.png',
'script.png',
'Q-forward.png',
'Q-back.png',
'forward.png',
'modules.png',
'modified.png',
'games.png',
]
# On low-res screens, the audio and focus icons are aliasing
icons_lowres = copy.deepcopy(icons)
# exchange only low resolution icons
for n,i in enumerate(icons):
if i=='audio.png':
icons_lowres[n]='audio-lowres.png'
if i=='focus.png':
icons_lowres[n]='focus-lowres.png'
# the 100D has no Q button, instead the Av button has the same functionality
icons_100D = copy.deepcopy(icons)
# exchange only 100D model specific icons
for n,i in enumerate(icons):
if i=='Q-forward.png':
icons_100D[n]='Av-forward.png'
if i=='Q-back.png':
icons_100D[n]='Av-back.png'
# the 500D has no Q button, instead the LiveView button has the same functionality
icons_500D = copy.deepcopy(icons)
# exchange only 500D model specific icons
for n,i in enumerate(icons):
if i=='Q-forward.png':
icons_500D[n]='LiveView-forward.png'
if i=='Q-back.png':
icons_500D[n]='LiveView-back.png'
# the 50D has no Q button, instead the FUNC button has the same functionality
icons_50D = copy.deepcopy(icons)
# exchange only 50D model specific icons
for n,i in enumerate(icons):
if i=='Q-forward.png':
icons_50D[n]='FUNC-forward.png'
if i=='Q-back.png':
icons_50D[n]='FUNC-back.png'
# the 5D Mark II has no Q button, instead the picture style button has the same functionality
icons_5D2 = copy.deepcopy(icons)
# exchange only 5D2 model specific icons
for n,i in enumerate(icons):
if i=='Q-forward.png':
icons_5D2[n]='picstyle-forward.png'
if i=='Q-back.png':
icons_5D2[n]='picstyle-back.png'
def process(icons, filename, labels):
# write icons in textual representation to *.in file
tmp = open(filename+".in", "w")
k = 0
for ico in icons:
print >> tmp, '%s = ' % chr(ord('a') + k)
k += 1
im = Image.open(ico).convert("1")
for y in range(Hpadded):
for x in range(Wpadded):
tmp.write("#" if im.getpixel((x+Xpad, y+Ypad)) else " ")
print >> tmp, ""
print >> tmp, ""
tmp.close()
# convert *.in files to *.c class files
os.system("perl mkfont-canon < %s.in > %s.c -width %d -height %d -labels %s" % (filename, filename, Wpadded, Hpadded, labels))
# given a list of matching text blocks and a list of ifdefs,
# return a compact representation of those lines
def ifdef(blocks, ifdefs):
uniq = list(set(blocks))
# all blocks identical? that's easy :)
if len(uniq) == 1:
return uniq[0]
assert len(blocks) == len(ifdefs)
N = len(blocks)
# there is one ifdef that is None - that one goes to the "else" branch
# assume it's the first one
assert ifdefs[0] == None
# print the different blocks with ifdefs
# todo: if things start growing, we may consider some boolean optimizations
out = ""
first = True
for i in range(N):
if blocks[i] != blocks[0]:
out += "#%sif defined(%s)\n" % ("" if first else "el", ifdefs[i])
first = False
out += blocks[i]
out += "#else\n"
out += blocks[0]
out += "#endif\n"
return out
# return a matrix D which summarizes the differences between lines
# D[i,j] means: lines[i] and lines[j] are identical
def diff_matrix(lines):
N = len(lines)
D = []
for i in range(N):
D.append([False] * N)
for i in range(N):
for j in range(N):
D[i][j] = (lines[i] == lines[j])
return D
def merge_ifdef(files, ifdefs, output):
# simplified merging of multiple files, similar to diff --ifdef
# assumption: all the input files have the same number of lines
# and they are already matched line-by-line
# some lines may differ between files, and those have to be merged with ifdefs
contents = []
lengths = []
for f in files:
lines = open(f).readlines()
contents.append(lines)
lengths.append(len(lines))
assert min(lengths) == max(lengths)
of = open(output, "w")
N = lengths[0]
i = 0
while i < N:
# extract just line i from all files
lines_i = [lines[i] for lines in contents]
# group lines that are different in the same way
# starting from line i
D = diff_matrix(lines_i)
j = i
while j < N and diff_matrix([lines[j] for lines in contents]) == D:
j += 1
# will group lines from i to j
lines_g = ["".join(lines[i:j]) for lines in contents]
# summarize the grouped lines with ifdefs
print >> of, ifdef(lines_g, ifdefs),
i = j
of.close()
def build_files(icon_lists):
# generate class files from the list of PNG icons
files = []
ifdefs = []
for icon_list, label, ifdef in icon_lists:
# use the new label only for those characters that were changed
# from the default list (unchanged characters will be labeled as "all")
labels = ",".join([label if icon_list[i] != icons[i] else "all" for i in range(len(icons))])
file_prefix = "ico-" + label
process(icon_list, file_prefix, labels)
# build a file list and an ifdef list with what we have processed
files.append(file_prefix + ".c")
ifdefs.append(ifdef)
return files, ifdefs
icon_lists = [
(icons, "all", None),
(icons_100D, "100D", "CONFIG_100D"),
(icons_500D, "500D", "CONFIG_500D"),
(icons_50D, "50D", "CONFIG_50D"),
(icons_5D2, "5D2", "CONFIG_5D2"),
(icons_lowres, "low", "CONFIG_LOW_RESOLUTION_DISPLAY"),
]
# process each icon set individually
files, ifdefs = build_files(icon_lists)
# make a merged #ifdef format output
merge_ifdef(files, ifdefs, "../src/ico.c")
# clean up, remove all generated class files
os.system("rm *.in *.c")