equal
deleted
inserted
replaced
5 */ |
5 */ |
6 |
6 |
7 package isabelle |
7 package isabelle |
8 |
8 |
9 |
9 |
10 object Build_Fonts |
10 object Build_Fonts { |
11 { |
|
12 /* relevant codepoint ranges */ |
11 /* relevant codepoint ranges */ |
13 |
12 |
14 object Range |
13 object Range { |
15 { |
|
16 def base_font: Seq[Int] = |
14 def base_font: Seq[Int] = |
17 (0x0020 to 0x007e) ++ // ASCII |
15 (0x0020 to 0x007e) ++ // ASCII |
18 (0x00a0 to 0x024f) ++ // Latin Extended-A/B |
16 (0x00a0 to 0x024f) ++ // Latin Extended-A/B |
19 (0x0400 to 0x04ff) ++ // Cyrillic |
17 (0x0400 to 0x04ff) ++ // Cyrillic |
20 (0x0600 to 0x06ff) ++ // Arabic |
18 (0x0600 to 0x06ff) ++ // Arabic |
135 |
133 |
136 sealed case class Family( |
134 sealed case class Family( |
137 plain: String = "", |
135 plain: String = "", |
138 bold: String = "", |
136 bold: String = "", |
139 italic: String = "", |
137 italic: String = "", |
140 bold_italic: String = "") |
138 bold_italic: String = "" |
141 { |
139 ) { |
142 val fonts: List[String] = |
140 val fonts: List[String] = |
143 proper_string(plain).toList ::: |
141 proper_string(plain).toList ::: |
144 proper_string(bold).toList ::: |
142 proper_string(bold).toList ::: |
145 proper_string(italic).toList ::: |
143 proper_string(italic).toList ::: |
146 proper_string(bold_italic).toList |
144 proper_string(bold_italic).toList |
147 |
145 |
148 def get(index: Int): String = fonts(index % fonts.length) |
146 def get(index: Int): String = fonts(index % fonts.length) |
149 } |
147 } |
150 |
148 |
151 object Family |
149 object Family { |
152 { |
|
153 def isabelle_symbols: Family = |
150 def isabelle_symbols: Family = |
154 Family( |
151 Family( |
155 plain = "IsabelleSymbols.sfd", |
152 plain = "IsabelleSymbols.sfd", |
156 bold = "IsabelleSymbolsBold.sfd") |
153 bold = "IsabelleSymbolsBold.sfd") |
157 |
154 |
181 |
178 |
182 |
179 |
183 /* hinting */ |
180 /* hinting */ |
184 |
181 |
185 // see https://www.freetype.org/ttfautohint/doc/ttfautohint.html |
182 // see https://www.freetype.org/ttfautohint/doc/ttfautohint.html |
186 private def auto_hint(source: Path, target: Path): Unit = |
183 private def auto_hint(source: Path, target: Path): Unit = { |
187 { |
|
188 Isabelle_System.bash("ttfautohint -i " + |
184 Isabelle_System.bash("ttfautohint -i " + |
189 File.bash_path(source) + " " + File.bash_path(target)).check |
185 File.bash_path(source) + " " + File.bash_path(target)).check |
190 } |
186 } |
191 |
187 |
192 private def hinted_path(hinted: Boolean): Path = |
188 private def hinted_path(hinted: Boolean): Path = |
195 private val hinting = List(false, true) |
191 private val hinting = List(false, true) |
196 |
192 |
197 |
193 |
198 /* build fonts */ |
194 /* build fonts */ |
199 |
195 |
200 private def find_file(dirs: List[Path], name: String): Path = |
196 private def find_file(dirs: List[Path], name: String): Path = { |
201 { |
|
202 val path = Path.explode(name) |
197 val path = Path.explode(name) |
203 dirs.collectFirst({ case dir if (dir + path).is_file => dir + path }) match { |
198 dirs.collectFirst({ case dir if (dir + path).is_file => dir + path }) match { |
204 case Some(file) => file |
199 case Some(file) => file |
205 case None => |
200 case None => |
206 error(cat_lines( |
201 error(cat_lines( |
218 sources: List[Family] = default_sources, |
213 sources: List[Family] = default_sources, |
219 source_dirs: List[Path] = Nil, |
214 source_dirs: List[Path] = Nil, |
220 target_prefix: String = "Isabelle", |
215 target_prefix: String = "Isabelle", |
221 target_version: String = "", |
216 target_version: String = "", |
222 target_dir: Path = default_target_dir, |
217 target_dir: Path = default_target_dir, |
223 progress: Progress = new Progress): Unit = |
218 progress: Progress = new Progress |
224 { |
219 ): Unit = { |
225 Isabelle_System.require_command("ttfautohint") |
220 Isabelle_System.require_command("ttfautohint") |
226 |
221 |
227 progress.echo("Directory " + target_dir) |
222 progress.echo("Directory " + target_dir) |
228 hinting.foreach(hinted => Isabelle_System.make_directory(target_dir + hinted_path(hinted))) |
223 hinting.foreach(hinted => Isabelle_System.make_directory(target_dir + hinted_path(hinted))) |
229 |
224 |
241 val source_file = find_file(font_dirs, source_font) |
236 val source_file = find_file(font_dirs, source_font) |
242 val source_names = Fontforge.font_names(source_file) |
237 val source_names = Fontforge.font_names(source_file) |
243 |
238 |
244 val target_names = source_names.update(prefix = target_prefix, version = target_version) |
239 val target_names = source_names.update(prefix = target_prefix, version = target_version) |
245 |
240 |
246 Isabelle_System.with_tmp_file("font", "ttf")(tmp_file => |
241 Isabelle_System.with_tmp_file("font", "ttf")(tmp_file => { |
247 { |
|
248 for (hinted <- hinting) { |
242 for (hinted <- hinting) { |
249 val target_file = target_dir + hinted_path(hinted) + target_names.ttf |
243 val target_file = target_dir + hinted_path(hinted) + target_names.ttf |
250 progress.echo("Font " + target_file.toString + " ...") |
244 progress.echo("Font " + target_file.toString + " ...") |
251 |
245 |
252 if (hinted) auto_hint(source_file, tmp_file) |
246 if (hinted) auto_hint(source_file, tmp_file) |
340 |
334 |
341 |
335 |
342 /* Isabelle tool wrapper */ |
336 /* Isabelle tool wrapper */ |
343 |
337 |
344 val isabelle_tool = |
338 val isabelle_tool = |
345 Isabelle_Tool("build_fonts", "construct Isabelle fonts", Scala_Project.here, args => |
339 Isabelle_Tool("build_fonts", "construct Isabelle fonts", Scala_Project.here, args => { |
346 { |
|
347 var source_dirs: List[Path] = Nil |
340 var source_dirs: List[Path] = Nil |
348 |
341 |
349 val getopts = Getopts(""" |
342 val getopts = Getopts(""" |
350 Usage: isabelle build_fonts [OPTIONS] |
343 Usage: isabelle build_fonts [OPTIONS] |
351 |
344 |