OLD | NEW |
| (Empty) |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import fileinput | |
6 import glob | |
7 import optparse | |
8 import os | |
9 import shlex | |
10 import sys | |
11 import textwrap | |
12 | |
13 def AggregateVectorIconsLegacy(working_directory, file_list, output_cc, | |
14 output_h): | |
15 icon_list = [] | |
16 if file_list is None: | |
17 # TODO(GYP_GONE): |file_list| is only None for GYP builds (where response | |
18 # files are not supported), in which case we process all .icon files | |
19 # contained within |working_directory| and all of its descendant | |
20 # directories. This logic can be removed when GN is used everywhere. | |
21 # See crbug.com/535386. | |
22 for dirpath, dirnames, filenames in os.walk(working_directory): | |
23 icon_list.extend(glob.glob(os.path.join(dirpath, "*.icon"))) | |
24 else: | |
25 with open(file_list, 'r') as f: | |
26 file_list_contents = f.read() | |
27 icon_list = shlex.split(file_list_contents) | |
28 | |
29 input_header_template = open(os.path.join(working_directory, | |
30 "vector_icons.h.template")) | |
31 header_template_contents = input_header_template.readlines() | |
32 input_header_template.close() | |
33 output_header = open(output_h, "w") | |
34 for line in header_template_contents: | |
35 if not "TEMPLATE_PLACEHOLDER" in line: | |
36 output_header.write(line) | |
37 continue | |
38 | |
39 for icon_path in icon_list: | |
40 # The icon name should be of the format "foo.icon" or "foo.1x.icon". | |
41 (icon_name, extension) = os.path.splitext(os.path.basename(icon_path)) | |
42 (icon_name, scale_factor) = os.path.splitext(icon_name) | |
43 if not scale_factor: | |
44 output_header.write(" {},\n".format(icon_name.upper())) | |
45 output_header.close() | |
46 | |
47 input_cc_template = open( | |
48 os.path.join(working_directory, "vector_icons.cc.template")) | |
49 cc_template_contents = input_cc_template.readlines() | |
50 input_cc_template.close() | |
51 output_cc = open(output_cc, "w") | |
52 for line in cc_template_contents: | |
53 if not "TEMPLATE_PLACEHOLDER" in line: | |
54 output_cc.write(line) | |
55 continue; | |
56 | |
57 for icon_path in icon_list: | |
58 (icon_name, extension) = os.path.splitext(os.path.basename(icon_path)) | |
59 (icon_name, scale_factor) = os.path.splitext(icon_name) | |
60 assert not scale_factor or scale_factor == ".1x" | |
61 if (("1X" in line and scale_factor != ".1x") or | |
62 (not "1X" in line and scale_factor == ".1x")): | |
63 continue | |
64 | |
65 icon_file = open(icon_path) | |
66 vector_commands = "".join(icon_file.readlines()) | |
67 icon_file.close() | |
68 output_cc.write("ICON_TEMPLATE({}, {})\n".format(icon_name.upper(), | |
69 vector_commands)) | |
70 output_cc.close() | |
71 | |
72 | |
73 def Error(msg): | |
74 print >> sys.stderr, msg | |
75 sys.exit(1) | |
76 | |
77 | |
78 def CamelCase(name, suffix): | |
79 words = name.split('_') | |
80 words = [w.capitalize() for w in words] | |
81 return 'k' + ''.join(words) + suffix | |
82 | |
83 | |
84 def AggregateVectorIcons(working_directory, file_list, output_cc, output_h, | |
85 use_legacy_template): | |
86 """Compiles all .icon files in a directory into two C++ files. | |
87 | |
88 Args: | |
89 working_directory: The path to the directory that holds the .icon files | |
90 and C++ templates. | |
91 file_list: A file containing the list of vector icon files to process. | |
92 Used for GN only (this argument defaults to None for GYP). | |
93 output_cc: The path that should be used to write the .cc file. | |
94 output_h: The path that should be used to write the .h file. | |
95 use_legacy_template: If True, |output_cc| and |output_h| are generated | |
96 using .template files which make use of the VectorIconId enum. | |
97 """ | |
98 | |
99 # TODO(tdanderson): Remove this code once all vector icons map to VectorIcon | |
100 # constants rather than VectorIconId values. | |
101 if use_legacy_template: | |
102 AggregateVectorIconsLegacy(working_directory, file_list, output_cc, | |
103 output_h) | |
104 return | |
105 | |
106 # For each file in |file_list|, place it in |path_map| if its extension is | |
107 # .icon or place it in |path_map_1x| if its extension is .1x.icon. The | |
108 # two dictionaries map the icon's name to its path, e.g., | |
109 # path_map['cat'] = 'foo/bar/cat.icon'. | |
110 icon_list = [] | |
111 with open(file_list, 'r') as f: | |
112 file_list_contents = f.read() | |
113 icon_list = shlex.split(file_list_contents) | |
114 | |
115 path_map = {} | |
116 path_map_1x = {} | |
117 | |
118 for icon_path in icon_list: | |
119 (icon_name, extension) = os.path.splitext(os.path.basename(icon_path)) | |
120 (icon_name, scale_factor) = os.path.splitext(icon_name) | |
121 | |
122 if (scale_factor and scale_factor != ".1x") or (extension != ".icon"): | |
123 Error("Only filenames " + icon_name + ".icon or " + icon_name + | |
124 ".1x.icon are allowed.") | |
125 | |
126 if not scale_factor and icon_name not in path_map: | |
127 path_map[icon_name] = icon_path | |
128 elif scale_factor and icon_name not in path_map_1x: | |
129 path_map_1x[icon_name] = icon_path | |
130 else: | |
131 Error("A vector icon with name '" + icon_name + "' already exists.") | |
132 | |
133 for icon_1x in path_map_1x: | |
134 if icon_1x not in path_map: | |
135 Error("The file " + icon_1x + ".icon must be provided.") | |
136 | |
137 # Generate the file vector_icons.h which declares a variable for each | |
138 # icon in |path_map|. The variable name is derived from the icon name by | |
139 # converting to camel case, prepending 'k', and appending 'Icon'. For | |
140 # example, the icon 'foo_bar' will have the variable name kFooBarIcon. | |
141 input_header_template = open(os.path.join(working_directory, | |
142 "vector_icons.h.template")) | |
143 header_template_contents = input_header_template.readlines() | |
144 input_header_template.close() | |
145 | |
146 output_header = open(output_h, "w") | |
147 for line in header_template_contents: | |
148 if not "TEMPLATE_PLACEHOLDER" in line: | |
149 output_header.write(line) | |
150 continue | |
151 | |
152 for icon in path_map: | |
153 (icon_name, extension) = os.path.splitext( | |
154 os.path.basename(path_map[icon])) | |
155 (icon_name, scale_factor) = os.path.splitext(icon_name) | |
156 output_header.write( | |
157 "VECTOR_ICON_TEMPLATE_H({})\n".format(CamelCase(icon_name, "Icon"))) | |
158 output_header.close() | |
159 | |
160 # Copy the vector icon drawing commands from the .icon and .1x.icon files | |
161 # and use them to generate vector_icons.cc, which defines the variables | |
162 # declared in vector_icons.h. | |
163 input_cc_template = open( | |
164 os.path.join(working_directory, "vector_icons.cc.template")) | |
165 cc_template_contents = input_cc_template.readlines() | |
166 input_cc_template.close() | |
167 | |
168 output_cc = open(output_cc, "w") | |
169 for line in cc_template_contents: | |
170 if not "TEMPLATE_PLACEHOLDER" in line: | |
171 output_cc.write(line) | |
172 continue; | |
173 | |
174 for icon in path_map: | |
175 (icon_name, extension) = os.path.splitext( | |
176 os.path.basename(path_map[icon])) | |
177 (icon_name, scale_factor) = os.path.splitext(icon_name) | |
178 | |
179 # Store the vector-drawing commands for foo_bar.icon in the temporary | |
180 # variable kFooBarPath. | |
181 icon_file = open(path_map[icon]) | |
182 vector_commands = "".join(icon_file.readlines()) | |
183 icon_file.close() | |
184 output_cc.write("PATH_ELEMENT_TEMPLATE({}, {})\n".format( | |
185 CamelCase(icon_name, "Path"), vector_commands)) | |
186 | |
187 # Store the vector-drawing commands for foo_bar.1x.icon in the temporary | |
188 # variable kFooBarPath1x, if the file exists. | |
189 vector_commands_1x = None | |
190 if (icon in path_map_1x): | |
191 icon_file = open(path_map_1x[icon]) | |
192 vector_commands_1x = "".join(icon_file.readlines()) | |
193 icon_file.close() | |
194 output_cc.write("PATH_ELEMENT_TEMPLATE({}, {})\n".format( | |
195 CamelCase(icon_name, "Path1x"), vector_commands_1x)) | |
196 | |
197 # Define the value of kFooBarIcon. | |
198 third_arg = "nullptr" if vector_commands_1x is None else CamelCase( | |
199 icon_name, "Path1x") | |
200 output_cc.write("VECTOR_ICON_TEMPLATE({}, {}, {})\n".format(CamelCase( | |
201 icon_name, "Icon"), CamelCase(icon_name, "Path"), third_arg)) | |
202 | |
203 output_cc.close() | |
204 | |
205 | |
206 def main(): | |
207 parser = optparse.OptionParser() | |
208 parser.add_option("--working_directory", | |
209 help="The directory to look for template C++ as well as " | |
210 "icon files.") | |
211 parser.add_option("--file_list", | |
212 help="A response file containing the list of icon files " | |
213 "to be processed (GN only). Defaults to None.", | |
214 default=None) | |
215 parser.add_option("--output_cc", | |
216 help="The path to output the CC file to.") | |
217 parser.add_option("--output_h", | |
218 help="The path to output the header file to.") | |
219 parser.add_option("--use_legacy_template", | |
220 action="store_true", | |
221 help="When set, the VectorIconId enum is populated " | |
222 "with values corresponding to .icon files in " | |
223 "the current working directory.", | |
224 default=False) | |
225 | |
226 (options, args) = parser.parse_args() | |
227 | |
228 AggregateVectorIcons(options.working_directory, | |
229 options.file_list, | |
230 options.output_cc, | |
231 options.output_h, | |
232 options.use_legacy_template) | |
233 | |
234 | |
235 if __name__ == "__main__": | |
236 main() | |
OLD | NEW |