| author | wenzelm | 
| Thu, 29 Dec 2022 12:27:55 +0100 | |
| changeset 76811 | 56d76e8cecf4 | 
| parent 76548 | 0af64cc2eee9 | 
| permissions | -rw-r--r-- | 
| 69339 | 1 | /* Title: Pure/Admin/build_fonts.scala | 
| 69330 | 2 | Author: Makarius | 
| 3 | ||
| 69354 | 4 | Build standard Isabelle fonts: DejaVu base + Isabelle symbols. | 
| 69330 | 5 | */ | 
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | ||
| 75393 | 10 | object Build_Fonts {
 | 
| 69330 | 11 | /* relevant codepoint ranges */ | 
| 12 | ||
| 75393 | 13 |   object Range {
 | 
| 69336 | 14 | def base_font: Seq[Int] = | 
| 69330 | 15 | (0x0020 to 0x007e) ++ // ASCII | 
| 16 | (0x00a0 to 0x024f) ++ // Latin Extended-A/B | |
| 17 | (0x0400 to 0x04ff) ++ // Cyrillic | |
| 18 | (0x0600 to 0x06ff) ++ // Arabic | |
| 19 | Seq( | |
| 69796 | 20 | 0x02dd, // hungarumlaut | 
| 69330 | 21 | 0x2018, // single quote | 
| 22 | 0x2019, // single quote | |
| 23 | 0x201a, // single quote | |
| 24 | 0x201c, // double quote | |
| 25 | 0x201d, // double quote | |
| 26 | 0x201e, // double quote | |
| 27 | 0x2039, // single guillemet | |
| 28 | 0x203a, // single guillemet | |
| 69331 | 29 | 0x204b, // FOOTNOTE | 
| 69330 | 30 | 0x20ac, // Euro | 
| 69885 | 31 | 0x2710, // pencil | 
| 69330 | 32 | 0xfb01, // ligature fi | 
| 33 | 0xfb02, // ligature fl | |
| 34 | 0xfffd, // replacement character | |
| 35 | ) | |
| 36 | ||
| 69336 | 37 | def isabelle_font: Seq[Int] = | 
| 69330 | 38 | Seq( | 
| 39 | 0x05, // X | |
| 40 | 0x06, // Y | |
| 41 | 0x07, // EOF | |
| 42 | 0x7f, // DEL | |
| 69341 
6aa24ccd8049
proper superscript "-1", based on "Deja Vu Sans Condensed" U+207b/U+00b9, with bold version via "Change Weight / Embolden by 80 em units";
 wenzelm parents: 
69339diff
changeset | 43 | 0xaf, // INVERSE | 
| 69330 | 44 | 0xac, // logicalnot | 
| 45 | 0xb0, // degree | |
| 46 | 0xb1, // plusminus | |
| 47 | 0xb7, // periodcentered | |
| 48 | 0xd7, // multiply | |
| 49 | 0xf7, // divide | |
| 50 | ) ++ | |
| 51 | (0x0370 to 0x03ff) ++ // Greek (pseudo math) | |
| 69336 | 52 | (0x0590 to 0x05ff) ++ // Hebrew (non-mono) | 
| 69330 | 53 | Seq( | 
| 54 | 0x2010, // hyphen | |
| 55 | 0x2013, // dash | |
| 56 | 0x2014, // dash | |
| 57 | 0x2015, // dash | |
| 74433 
ec1774613824
support symbol \<Parallel>, based on \bigparallel from stdmaryd (stmary10.pfb: move y=1100, scale 222%, embolden by 40 units, adjust spacing);
 wenzelm parents: 
73649diff
changeset | 58 | 0x2016, // big parallel | 
| 69330 | 59 | 0x2020, // dagger | 
| 60 | 0x2021, // double dagger | |
| 61 | 0x2022, // bullet | |
| 62 | 0x2026, // ellipsis | |
| 63 | 0x2030, // perthousand | |
| 64 | 0x2032, // minute | |
| 65 | 0x2033, // second | |
| 66 | 0x2038, // caret | |
| 73446 
d1c4c2395650
more Isabelle symbol definitions for Z Notation, based on https://github.com/isabelle-utp/Z_Toolkit 998c9f7880d3 by Simon Foster;
 wenzelm parents: 
73444diff
changeset | 67 | 0x2040, // sequence concatenation | 
| 69330 | 68 | 0x20cd, // currency symbol | 
| 69 | ) ++ | |
| 70 | (0x2100 to 0x214f) ++ // Letterlike Symbols | |
| 71 | (0x2190 to 0x21ff) ++ // Arrows | |
| 72 | (0x2200 to 0x22ff) ++ // Mathematical Operators | |
| 73 | (0x2300 to 0x23ff) ++ // Miscellaneous Technical | |
| 74 | Seq( | |
| 75 | 0x2423, // graphic for space | |
| 76 | 0x2500, // box drawing | |
| 77 | 0x2501, // box drawing | |
| 78 | 0x2508, // box drawing | |
| 79 | 0x2509, // box drawing | |
| 80 | 0x2550, // box drawing | |
| 81 | ) ++ | |
| 82 | (0x25a0 to 0x25ff) ++ // Geometric Shapes | |
| 83 | Seq( | |
| 69331 | 84 | 0x261b, // ACTION | 
| 69330 | 85 | 0x2660, // spade suit | 
| 86 | 0x2661, // heart suit | |
| 87 | 0x2662, // diamond suit | |
| 88 | 0x2663, // club suit | |
| 89 | 0x266d, // musical flat | |
| 90 | 0x266e, // musical natural | |
| 91 | 0x266f, // musical sharp | |
| 73467 
090add96f5f9
more glyphs proposed by Simon Foster: 0x002713, 0x002717, 0x002af4, 0x002afb, 0x002afd;
 wenzelm parents: 
73446diff
changeset | 92 | 0x2713, // check mark | 
| 
090add96f5f9
more glyphs proposed by Simon Foster: 0x002713, 0x002717, 0x002af4, 0x002afb, 0x002afd;
 wenzelm parents: 
73446diff
changeset | 93 | 0x2717, // ballot X | 
| 69330 | 94 | 0x2756, // UNDEFINED | 
| 95 | 0x2759, // BOLD | |
| 96 | 0x27a7, // DESCR | |
| 97 | 0x27e6, // left white square bracket | |
| 98 | 0x27e7, // right white square bracket | |
| 99 | 0x27e8, // left angle bracket | |
| 100 | 0x27e9, // right angle bracket | |
| 70371 | 101 | 0x27ea, // left double angle bracket | 
| 102 | 0x27eb, // right double angle bracket | |
| 69330 | 103 | ) ++ | 
| 104 | (0x27f0 to 0x27ff) ++ // Supplemental Arrows-A | |
| 105 | (0x2900 to 0x297f) ++ // Supplemental Arrows-B | |
| 106 | (0x2980 to 0x29ff) ++ // Miscellaneous Mathematical Symbols-B | |
| 107 | (0x2a00 to 0x2aff) ++ // Supplemental Mathematical Operators | |
| 108 | Seq(0x2b1a) ++ // VERBATIM | |
| 109 | (0x1d400 to 0x1d7ff) ++ // Mathematical Alphanumeric Symbols | |
| 110 | Seq( | |
| 69331 | 111 | 0x1f310, // globe with meridians (Symbola font) | 
| 112 | 0x1f4d3, // notebook (Symbola font) | |
| 113 | 0x1f5c0, // folder (Symbola font) | |
| 114 | 0x1f5cf, // page (Symbola font) | |
| 69330 | 115 | ) | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 116 | |
| 69437 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 117 | def isabelle_math_font: Seq[Int] = | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 118 | (0x21 to 0x2f) ++ // bang .. slash | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 119 | (0x3a to 0x40) ++ // colon .. atsign | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 120 | (0x5b to 0x5f) ++ // leftbracket .. underscore | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 121 | (0x7b to 0x7e) ++ // leftbrace .. tilde | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 122 | Seq( | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 123 | 0xa9, // copyright | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 124 | 0xae, // registered | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 125 | ) | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 126 | |
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 127 | val vacuous_font: Seq[Int] = | 
| 
1b64f82aaf76
more mathematical glyphs from Isabelle2009-1/lib/fonts/IsabelleMono.sfd (still unused);
 wenzelm parents: 
69436diff
changeset | 128 | Seq(0x3c) // "<" as template | 
| 69330 | 129 | } | 
| 130 | ||
| 131 | ||
| 132 | /* font families */ | |
| 133 | ||
| 69332 | 134 | sealed case class Family( | 
| 135 | plain: String = "", | |
| 136 | bold: String = "", | |
| 137 | italic: String = "", | |
| 75393 | 138 | bold_italic: String = "" | 
| 139 |   ) {
 | |
| 69336 | 140 | val fonts: List[String] = | 
| 141 | proper_string(plain).toList ::: | |
| 142 | proper_string(bold).toList ::: | |
| 143 | proper_string(italic).toList ::: | |
| 144 | proper_string(bold_italic).toList | |
| 145 | ||
| 146 | def get(index: Int): String = fonts(index % fonts.length) | |
| 147 | } | |
| 69330 | 148 | |
| 75393 | 149 |   object Family {
 | 
| 69436 | 150 | def isabelle_symbols: Family = | 
| 69336 | 151 | Family( | 
| 69436 | 152 | plain = "IsabelleSymbols.sfd", | 
| 153 | bold = "IsabelleSymbolsBold.sfd") | |
| 69336 | 154 | |
| 69332 | 155 | def deja_vu_sans_mono: Family = | 
| 69330 | 156 | Family( | 
| 69332 | 157 | plain = "DejaVuSansMono.ttf", | 
| 158 | bold = "DejaVuSansMono-Bold.ttf", | |
| 159 | italic = "DejaVuSansMono-Oblique.ttf", | |
| 69336 | 160 | bold_italic = "DejaVuSansMono-BoldOblique.ttf") | 
| 69330 | 161 | |
| 69332 | 162 | def deja_vu_sans: Family = | 
| 69330 | 163 | Family( | 
| 69332 | 164 | plain = "DejaVuSans.ttf", | 
| 165 | bold = "DejaVuSans-Bold.ttf", | |
| 166 | italic = "DejaVuSans-Oblique.ttf", | |
| 167 | bold_italic = "DejaVuSans-BoldOblique.ttf") | |
| 69330 | 168 | |
| 69332 | 169 | def deja_vu_serif: Family = | 
| 69330 | 170 | Family( | 
| 69332 | 171 | plain = "DejaVuSerif.ttf", | 
| 172 | bold = "DejaVuSerif-Bold.ttf", | |
| 173 | italic = "DejaVuSerif-Italic.ttf", | |
| 174 | bold_italic = "DejaVuSerif-BoldItalic.ttf") | |
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 175 | |
| 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 176 | def vacuous: Family = Family(plain = "Vacuous.sfd") | 
| 69330 | 177 | } | 
| 69336 | 178 | |
| 179 | ||
| 70072 | 180 | /* hinting */ | 
| 181 | ||
| 69795 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 182 | // see https://www.freetype.org/ttfautohint/doc/ttfautohint.html | 
| 75393 | 183 |   private def auto_hint(source: Path, target: Path): Unit = {
 | 
| 69795 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 184 |     Isabelle_System.bash("ttfautohint -i " +
 | 
| 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 185 | File.bash_path(source) + " " + File.bash_path(target)).check | 
| 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 186 | } | 
| 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 187 | |
| 76531 | 188 | private def make_path(hinted: Boolean = false): Path = | 
| 70072 | 189 |     if (hinted) Path.basic("ttf-hinted") else Path.basic("ttf")
 | 
| 190 | ||
| 191 | private val hinting = List(false, true) | |
| 69795 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 192 | |
| 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 193 | |
| 69336 | 194 | /* build fonts */ | 
| 195 | ||
| 75393 | 196 |   private def find_file(dirs: List[Path], name: String): Path = {
 | 
| 69336 | 197 | val path = Path.explode(name) | 
| 198 |     dirs.collectFirst({ case dir if (dir + path).is_file => dir + path }) match {
 | |
| 199 | case Some(file) => file | |
| 200 | case None => | |
| 201 | error(cat_lines( | |
| 202 |           ("Failed to find font file " + path + " in directories:") ::
 | |
| 203 | dirs.map(dir => " " + dir.toString))) | |
| 204 | } | |
| 205 | } | |
| 206 | ||
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 207 | val default_download_url = | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 208 | "https://github.com/dejavu-fonts/dejavu-fonts/releases/download/version_2_37/dejavu-fonts-ttf-2.37.zip" | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 209 | |
| 69336 | 210 | val default_sources: List[Family] = | 
| 211 | List(Family.deja_vu_sans_mono, Family.deja_vu_sans, Family.deja_vu_serif) | |
| 212 | ||
| 213 | def build_fonts( | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 214 | download_url: String = default_download_url, | 
| 76531 | 215 | target_dir: Path = Path.current, | 
| 216 | target_prefix: String = "Isabelle", | |
| 69336 | 217 | sources: List[Family] = default_sources, | 
| 75393 | 218 | progress: Progress = new Progress | 
| 219 |   ): Unit = {
 | |
| 73444 | 220 |     Isabelle_System.require_command("ttfautohint")
 | 
| 221 | ||
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 222 |     Isabelle_System.with_tmp_file("download", ext = "zip") { download_file =>
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 223 |       Isabelle_System.with_tmp_dir("download") { download_dir =>
 | 
| 76531 | 224 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 225 | |
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 226 | /* download */ | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 227 | |
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 228 | Isabelle_System.download_file(download_url, download_file, progress = progress) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 229 | Isabelle_System.extract(download_file, download_dir) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 230 | |
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 231 |         val dejavu_dir = File.get_dir(download_dir, title = download_url) + Path.basic("ttf")
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 232 | |
| 76531 | 233 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 234 | /* component */ | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 235 | |
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 236 | val component_date = Date.Format.alt_date(Date.now()) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 237 | val component_name = "isabelle_fonts-" + component_date | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 238 | val component_dir = | 
| 76547 | 239 | Components.Directory(target_dir + Path.basic(component_name)).create(progress = progress) | 
| 76531 | 240 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 241 |         for (hinted <- hinting) {
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 242 | Isabelle_System.make_directory(component_dir.path + make_path(hinted = hinted)) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 243 | } | 
| 69336 | 244 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 245 |         val font_dirs = List(dejavu_dir, Path.explode("~~/Admin/isabelle_fonts"))
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 246 |         for (dir <- font_dirs if !dir.is_dir) error("Bad source directory: " + dir)
 | 
| 69336 | 247 | |
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 248 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 249 | // Isabelle fonts | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 250 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 251 | val fonts = | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 252 |           for { source <- sources; (source_font, index) <- source.fonts.zipWithIndex }
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 253 |           yield {
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 254 | val isabelle_file = find_file(font_dirs, Family.isabelle_symbols.get(index)) | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 255 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 256 | val source_file = find_file(font_dirs, source_font) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 257 | val source_names = Fontforge.font_names(source_file) | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 258 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 259 | val font_names = source_names.update(prefix = target_prefix, version = component_date) | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 260 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 261 |             Isabelle_System.with_tmp_file("font", "ttf") { tmp_file =>
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 262 |               for (hinted <- hinting) {
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 263 | val font_file = component_dir.path + make_path(hinted = hinted) + font_names.ttf | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 264 |                 progress.echo("Font " + font_file + " ...")
 | 
| 69795 
4791988fcbc4
auto-hinting of original DejaVu fonts, but not Isabelle symbols;
 wenzelm parents: 
69437diff
changeset | 265 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 266 | if (hinted) auto_hint(source_file, tmp_file) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 267 | else Isabelle_System.copy_file(source_file, tmp_file) | 
| 69336 | 268 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 269 | Fontforge.execute( | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 270 | Fontforge.commands( | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 271 | Fontforge.open(isabelle_file), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 272 | Fontforge.select(Range.isabelle_font), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 273 | Fontforge.copy, | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 274 | Fontforge.close, | 
| 69336 | 275 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 276 | Fontforge.open(tmp_file), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 277 | Fontforge.select(Range.base_font), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 278 | Fontforge.select_invert, | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 279 | Fontforge.clear, | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 280 | Fontforge.select(Range.isabelle_font), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 281 | Fontforge.paste, | 
| 70072 | 282 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 283 | font_names.set, | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 284 | Fontforge.generate(font_file), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 285 | Fontforge.close) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 286 | ).check | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 287 | } | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 288 | } | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 289 | |
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 290 | (font_names.ttf, index) | 
| 70072 | 291 | } | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 292 | |
| 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 293 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 294 | // Vacuous font | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 295 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 296 |         {
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 297 | val vacuous_file = find_file(font_dirs, Family.vacuous.get(0)) | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 298 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 299 | val font_dir = component_dir.path + make_path() | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 300 | val font_names = Fontforge.font_names(vacuous_file) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 301 | val font_file = font_dir + font_names.ttf | 
| 69336 | 302 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 303 |           progress.echo("Font " + font_file + " ...")
 | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 304 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 305 | val domain = | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 306 | (for ((name, index) <- fonts if index == 0) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 307 | yield Fontforge.font_domain(font_dir + name)) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 308 | .flatten.distinct.sorted | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 309 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 310 | Fontforge.execute( | 
| 69371 
3539767d5c61
generate Vacuous font from domain of Isabelle fonts;
 wenzelm parents: 
69354diff
changeset | 311 | Fontforge.commands( | 
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 312 | Fontforge.open(vacuous_file), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 313 | Fontforge.select(Range.vacuous_font), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 314 | Fontforge.copy) + | 
| 69336 | 315 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 316 | domain.map(code => | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 317 | Fontforge.commands( | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 318 | Fontforge.select(Seq(code)), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 319 | Fontforge.paste)) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 320 |               .mkString("\n", "\n", "\n") +
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 321 | |
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 322 | Fontforge.commands( | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 323 | Fontforge.generate(font_file), | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 324 | Fontforge.close) | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 325 | ).check | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 326 | } | 
| 69373 | 327 | |
| 328 | ||
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 329 | /* settings */ | 
| 70072 | 330 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 331 | def make_settings(hinted: Boolean = false): String = | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 332 | "\n isabelle_fonts \\\n" + | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 333 | (for ((ttf, _) <- fonts) yield | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 334 | """ "$COMPONENT/""" + make_path(hinted = hinted).file_name + "/" + ttf.file_name + "\"") | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 335 |           .mkString(" \\\n")
 | 
| 70072 | 336 | |
| 76548 | 337 |         component_dir.write_settings("""
 | 
| 70084 
f9d8f78ef687
proper treatment of isabelle_fonts_hinted in etc/preferences (i.e. a change of the default option);
 wenzelm parents: 
70072diff
changeset | 338 | if grep "isabelle_fonts_hinted.*=.*false" "$ISABELLE_HOME_USER/etc/preferences" >/dev/null 2>/dev/null | 
| 76531 | 339 | then""" + make_settings() + """ | 
| 340 | else""" + make_settings(hinted = true) + """ | |
| 70072 | 341 | fi | 
| 342 | ||
| 76531 | 343 | isabelle_fonts_hidden "$COMPONENT/""" + make_path().file_name + """/Vacuous.ttf" | 
| 69373 | 344 | """) | 
| 345 | ||
| 346 | ||
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 347 | /* README */ | 
| 76531 | 348 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 349 | Isabelle_System.copy_file( | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 350 |           Path.explode("~~/Admin/isabelle_fonts/README"), component_dir.README)
 | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 351 | } | 
| 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 352 | } | 
| 69336 | 353 | } | 
| 69337 | 354 | |
| 355 | ||
| 356 | /* Isabelle tool wrapper */ | |
| 357 | ||
| 358 | val isabelle_tool = | |
| 75394 | 359 |     Isabelle_Tool("build_fonts", "construct Isabelle fonts", Scala_Project.here,
 | 
| 360 |       { args =>
 | |
| 76531 | 361 | var target_dir = Path.current | 
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 362 | var download_url = default_download_url | 
| 69337 | 363 | |
| 75394 | 364 |         val getopts = Getopts("""
 | 
| 69337 | 365 | Usage: isabelle build_fonts [OPTIONS] | 
| 366 | ||
| 367 | Options are: | |
| 76531 | 368 | -D DIR target directory (default ".") | 
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 369 | -U URL download URL (default: """" + default_download_url + """") | 
| 69337 | 370 | |
| 69343 
395c4fb15ea2
use "Isabelle DejaVu" fonts uniformly: Text Area, GUI elements, HTML output etc.;
 wenzelm parents: 
69341diff
changeset | 371 | Construct Isabelle fonts from DejaVu font families and Isabelle symbols. | 
| 69337 | 372 | """, | 
| 76531 | 373 | "D:" -> (arg => target_dir = Path.explode(arg)), | 
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 374 | "U:" -> (arg => download_url = arg)) | 
| 69337 | 375 | |
| 75394 | 376 | val more_args = getopts(args) | 
| 377 | if (more_args.nonEmpty) getopts.usage() | |
| 69337 | 378 | |
| 75394 | 379 | val progress = new Console_Progress | 
| 69337 | 380 | |
| 76532 
c9e1276f0268
proper download, instead of assuming local directory;
 wenzelm parents: 
76531diff
changeset | 381 | build_fonts(download_url = download_url, target_dir = target_dir, progress = progress) | 
| 75394 | 382 | }) | 
| 69330 | 383 | } |