src/Pure/Tools/fontforge.scala
changeset 75393 87ebf5a50283
parent 71601 97ccf48c2f0c
child 75394 42267c650205
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
    10 
    10 
    11 import java.io.{File => JFile}
    11 import java.io.{File => JFile}
    12 import java.util.Locale
    12 import java.util.Locale
    13 
    13 
    14 
    14 
    15 object Fontforge
    15 object Fontforge {
    16 {
       
    17   /** scripting language **/
    16   /** scripting language **/
    18 
    17 
    19   type Script = String
    18   type Script = String
    20 
    19 
    21 
    20 
    22   /* concrete syntax */
    21   /* concrete syntax */
    23 
    22 
    24   def string(s: String): Script =
    23   def string(s: String): Script = {
    25   {
       
    26     def err(c: Char): Nothing =
    24     def err(c: Char): Nothing =
    27       error("Bad character \\u" + String.format(Locale.ROOT, "%04x", Integer.valueOf(c)) +
    25       error("Bad character \\u" + String.format(Locale.ROOT, "%04x", Integer.valueOf(c)) +
    28         " in fontforge string " + quote(s))
    26         " in fontforge string " + quote(s))
    29 
    27 
    30     val q = if (s.contains('"')) '\'' else '"'
    28     val q = if (s.contains('"')) '\'' else '"'
    31 
    29 
    32     def escape(c: Char): String =
    30     def escape(c: Char): String = {
    33     {
       
    34       if (c == '\u0000' || c == '\r' || c == q) err(c)
    31       if (c == '\u0000' || c == '\r' || c == q) err(c)
    35       else if (c == '\n') "\\n"
    32       else if (c == '\n') "\\n"
    36       else if (c == '\\') "\\\\"
    33       else if (c == '\\') "\\\\"
    37       else c.toString
    34       else c.toString
    38     }
    35     }
    68 
    65 
    69 
    66 
    70   /** execute fontforge program **/
    67   /** execute fontforge program **/
    71 
    68 
    72   def execute(script: Script, args: String = "", cwd: JFile = null): Process_Result =
    69   def execute(script: Script, args: String = "", cwd: JFile = null): Process_Result =
    73     Isabelle_System.with_tmp_file("fontforge")(script_file =>
    70     Isabelle_System.with_tmp_file("fontforge")(script_file => {
    74     {
       
    75       File.write(script_file, script)
    71       File.write(script_file, script)
    76       Isabelle_System.bash(File.bash_path(Path.explode("$ISABELLE_FONTFORGE")) +
    72       Isabelle_System.bash(File.bash_path(Path.explode("$ISABELLE_FONTFORGE")) +
    77         " -lang=ff -script " + File.bash_path(script_file) + " " + args)
    73         " -lang=ff -script " + File.bash_path(script_file) + " " + args)
    78     })
    74     })
    79 
    75 
    80   def font_domain(path: Path, strict: Boolean = false): List[Int] =
    76   def font_domain(path: Path, strict: Boolean = false): List[Int] = {
    81   {
       
    82     val script =
    77     val script =
    83       commands(
    78       commands(
    84         open(path),
    79         open(path),
    85         "i = 0",
    80         "i = 0",
    86         "while (i < CharCnt() && i < 0x110000)",
    81         "while (i < CharCnt() && i < 0x110000)",
    98     fontname: String = "",
    93     fontname: String = "",
    99     familyname: String = "",
    94     familyname: String = "",
   100     fullname: String = "",
    95     fullname: String = "",
   101     weight: String = "",
    96     weight: String = "",
   102     copyright: String = "",
    97     copyright: String = "",
   103     fontversion: String = "")
    98     fontversion: String = ""
   104   {
    99   ) {
   105     override def toString: String = fontname
   100     override def toString: String = fontname
   106 
   101 
   107     def ttf: Path = Path.explode(fontname).ext("ttf")
   102     def ttf: Path = Path.explode(fontname).ext("ttf")
   108 
   103 
   109     def update(prefix: String = "", version: String = ""): Font_Names =
   104     def update(prefix: String = "", version: String = ""): Font_Names = {
   110     {
       
   111       val fontversion1 = proper_string(version) getOrElse fontversion
   105       val fontversion1 = proper_string(version) getOrElse fontversion
   112       if (prefix == "") copy(fontversion = fontversion1)
   106       if (prefix == "") copy(fontversion = fontversion1)
   113       else {
   107       else {
   114         copy(fontname = prefix + fontname,
   108         copy(fontname = prefix + fontname,
   115           familyname = prefix + " " + familyname,
   109           familyname = prefix + " " + familyname,
   123     def set: Script =
   117     def set: Script =
   124       List(fontname, familyname, fullname, weight, copyright, fontversion).map(string).
   118       List(fontname, familyname, fullname, weight, copyright, fontversion).map(string).
   125         mkString("SetFontNames(", ",", ")")
   119         mkString("SetFontNames(", ",", ")")
   126   }
   120   }
   127 
   121 
   128   def font_names(path: Path): Font_Names =
   122   def font_names(path: Path): Font_Names = {
   129   {
       
   130     val script =
   123     val script =
   131       commands(
   124       commands(
   132         open(path),
   125         open(path),
   133         "Print($fontname)",
   126         "Print($fontname)",
   134         "Print($familyname)",
   127         "Print($familyname)",