src/Pure/Admin/build_fonts.scala
changeset 70072 54dc58086351
parent 70071 9a03e9d5f336
child 70084 f9d8f78ef687
     1.1 --- a/src/Pure/Admin/build_fonts.scala	Fri Apr 05 23:45:35 2019 +0200
     1.2 +++ b/src/Pure/Admin/build_fonts.scala	Sat Apr 06 22:05:25 2019 +0200
     1.3 @@ -174,15 +174,19 @@
     1.4    }
     1.5  
     1.6  
     1.7 -  /* auto-hinting */
     1.8 +  /* hinting */
     1.9 +
    1.10    // see https://www.freetype.org/ttfautohint/doc/ttfautohint.html
    1.11 -
    1.12 -  def auto_hint(source: Path, target: Path)
    1.13 +  private def auto_hint(source: Path, target: Path)
    1.14    {
    1.15      Isabelle_System.bash("ttfautohint -i " +
    1.16        File.bash_path(source) + " " + File.bash_path(target)).check
    1.17    }
    1.18  
    1.19 +  private def hinted_path(hinted: Boolean): Path =
    1.20 +    if (hinted) Path.basic("ttf-hinted") else Path.basic("ttf")
    1.21 +
    1.22 +  private val hinting = List(false, true)
    1.23  
    1.24  
    1.25    /* build fonts */
    1.26 @@ -210,11 +214,10 @@
    1.27      target_prefix: String = "Isabelle",
    1.28      target_version: String = "",
    1.29      target_dir: Path = default_target_dir,
    1.30 -    unhinted: Boolean = false,
    1.31      progress: Progress = No_Progress)
    1.32    {
    1.33      progress.echo("Directory " + target_dir)
    1.34 -    Isabelle_System.mkdirs(target_dir)
    1.35 +    hinting.foreach(hinted => Isabelle_System.mkdirs(target_dir + hinted_path(hinted)))
    1.36  
    1.37      val font_dirs = source_dirs ::: List(Path.explode("~~/Admin/isabelle_fonts"))
    1.38      for (dir <- font_dirs if !dir.is_dir) error("Bad source directory: " + dir)
    1.39 @@ -231,35 +234,38 @@
    1.40          val source_names = Fontforge.font_names(source_file)
    1.41  
    1.42          val target_names = source_names.update(prefix = target_prefix, version = target_version)
    1.43 -        val target_file = target_dir + target_names.ttf
    1.44  
    1.45 -        progress.echo("Font " + target_file.toString + " ...")
    1.46          Isabelle_System.with_tmp_file("font", "ttf")(tmp_file =>
    1.47          {
    1.48 -          if (unhinted) File.copy(source_file, tmp_file)
    1.49 -          else auto_hint(source_file, tmp_file)
    1.50 +          for (hinted <- hinting) {
    1.51 +            val target_file = target_dir + hinted_path(hinted) + target_names.ttf
    1.52 +            progress.echo("Font " + target_file.toString + " ...")
    1.53  
    1.54 -          Fontforge.execute(
    1.55 -            Fontforge.commands(
    1.56 -              Fontforge.open(isabelle_file),
    1.57 -              Fontforge.select(Range.isabelle_font),
    1.58 -              Fontforge.copy,
    1.59 -              Fontforge.close,
    1.60 +            if (hinted) auto_hint(source_file, tmp_file)
    1.61 +            else File.copy(source_file, tmp_file)
    1.62  
    1.63 -              Fontforge.open(tmp_file),
    1.64 -              Fontforge.select(Range.base_font),
    1.65 -              Fontforge.select_invert,
    1.66 -              Fontforge.clear,
    1.67 -              Fontforge.select(Range.isabelle_font),
    1.68 -              Fontforge.paste,
    1.69 +            Fontforge.execute(
    1.70 +              Fontforge.commands(
    1.71 +                Fontforge.open(isabelle_file),
    1.72 +                Fontforge.select(Range.isabelle_font),
    1.73 +                Fontforge.copy,
    1.74 +                Fontforge.close,
    1.75  
    1.76 -              target_names.set,
    1.77 -              Fontforge.generate(target_file),
    1.78 -              Fontforge.close)
    1.79 -          ).check
    1.80 +                Fontforge.open(tmp_file),
    1.81 +                Fontforge.select(Range.base_font),
    1.82 +                Fontforge.select_invert,
    1.83 +                Fontforge.clear,
    1.84 +                Fontforge.select(Range.isabelle_font),
    1.85 +                Fontforge.paste,
    1.86 +
    1.87 +                target_names.set,
    1.88 +                Fontforge.generate(target_file),
    1.89 +                Fontforge.close)
    1.90 +            ).check
    1.91 +          }
    1.92          })
    1.93  
    1.94 -        (target_file, index)
    1.95 +        (target_names.ttf, index)
    1.96        }
    1.97  
    1.98  
    1.99 @@ -269,13 +275,14 @@
   1.100        val vacuous_file = find_file(font_dirs, Family.vacuous.get(0))
   1.101  
   1.102        val target_names = Fontforge.font_names(vacuous_file)
   1.103 -      val target_file = target_dir + target_names.ttf
   1.104 +      val target_file = target_dir + hinted_path(false) + target_names.ttf
   1.105  
   1.106        progress.echo("Font " + target_file.toString + " ...")
   1.107  
   1.108        val domain =
   1.109 -        (for ((target_file, index) <- targets if index == 0)
   1.110 -          yield Fontforge.font_domain(target_file)).flatten.toSet.toList.sorted
   1.111 +        (for ((name, index) <- targets if index == 0)
   1.112 +          yield Fontforge.font_domain(target_dir + hinted_path(false) + name))
   1.113 +        .flatten.toSet.toList.sorted
   1.114  
   1.115        Fontforge.execute(
   1.116          Fontforge.commands(
   1.117 @@ -300,13 +307,22 @@
   1.118  
   1.119      val settings_path = Components.settings(target_dir)
   1.120      Isabelle_System.mkdirs(settings_path.dir)
   1.121 +
   1.122 +    def fonts_settings(hinted: Boolean): String =
   1.123 +      "\n  isabelle_fonts \\\n" +
   1.124 +      (for ((target, _) <- targets) yield
   1.125 +        """    "$COMPONENT/""" + hinted_path(hinted).file_name + "/" + target.file_name + "\"")
   1.126 +      .mkString(" \\\n")
   1.127 +
   1.128      File.write(settings_path,
   1.129 -      "# -*- shell-script -*- :mode=shellscript:\n\nisabelle_fonts \\\n" +
   1.130 -      (for ((path, _) <- targets)
   1.131 -        yield """  "$COMPONENT/""" + path.file_name + "\"").mkString(" \\\n") +
   1.132 -      """
   1.133 +      """# -*- shell-script -*- :mode=shellscript:
   1.134  
   1.135 -isabelle_fonts_hidden "$COMPONENT/Vacuous.ttf"
   1.136 +if grep "isabelle_fonts_hinted.*=.*true" "$ISABELLE_HOME_USER/etc/preferences" >/dev/null 2>/dev/null
   1.137 +then""" + fonts_settings(true) + """
   1.138 +else""" + fonts_settings(false) + """
   1.139 +fi
   1.140 +
   1.141 +isabelle_fonts_hidden "$COMPONENT/""" + hinted_path(false).file_name + """/Vacuous.ttf"
   1.142  """)
   1.143  
   1.144  
   1.145 @@ -321,19 +337,16 @@
   1.146      Isabelle_Tool("build_fonts", "construct Isabelle fonts", args =>
   1.147      {
   1.148        var source_dirs: List[Path] = Nil
   1.149 -      var unhinted = false
   1.150  
   1.151        val getopts = Getopts("""
   1.152  Usage: isabelle build_fonts [OPTIONS]
   1.153  
   1.154    Options are:
   1.155      -d DIR       additional source directory
   1.156 -    -u           unhinted font (bypass ttfautohint)
   1.157  
   1.158    Construct Isabelle fonts from DejaVu font families and Isabelle symbols.
   1.159  """,
   1.160 -        "d:" -> (arg => source_dirs = source_dirs ::: List(Path.explode(arg))),
   1.161 -        "u" -> (_ => unhinted = true))
   1.162 +        "d:" -> (arg => source_dirs = source_dirs ::: List(Path.explode(arg))))
   1.163  
   1.164        val more_args = getopts(args)
   1.165        if (more_args.nonEmpty) getopts.usage()
   1.166 @@ -344,6 +357,6 @@
   1.167        val progress = new Console_Progress
   1.168  
   1.169        build_fonts(source_dirs = source_dirs, target_dir = target_dir,
   1.170 -        target_version = target_version, unhinted = unhinted, progress = progress)
   1.171 +        target_version = target_version, progress = progress)
   1.172      })
   1.173  }