src/Pure/Tools/fontforge.scala
author wenzelm
Fri, 23 Nov 2018 16:43:11 +0100
changeset 69334 6b49700da068
parent 69333 c889afca73a5
child 69335 76c8beaf3bab
permissions -rw-r--r--
clarified font_domain: strict excludes e.g. space character;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Tools/fontforge.scala
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     3
69333
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
     4
Support for fontforge and its scripting language: see
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
     5
/usr/share/doc/fontforge/scripting.html e.g. on Ubuntu Linux installation.
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     6
*/
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     7
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     8
package isabelle
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
     9
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    10
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    11
import java.io.{File => JFile}
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    12
import java.util.Locale
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    13
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    14
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    15
object Fontforge
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    16
{
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    17
  /** scripting language **/
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    18
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    19
  type Script = String
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    20
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    21
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    22
  /* concrete syntax */
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    23
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    24
  def string(s: String): Script =
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    25
  {
69329
8bbde4dba926 tuned error;
wenzelm
parents: 69328
diff changeset
    26
    def err(c: Char): Nothing =
8bbde4dba926 tuned error;
wenzelm
parents: 69328
diff changeset
    27
      error("Bad character \\u" + String.format(Locale.ROOT, "%04x", new Integer(c)) +
8bbde4dba926 tuned error;
wenzelm
parents: 69328
diff changeset
    28
        " in fontforge string " + quote(s))
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    29
69329
8bbde4dba926 tuned error;
wenzelm
parents: 69328
diff changeset
    30
    val q = if (s.contains('"')) '\'' else '"'
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    31
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    32
    def escape(c: Char): String =
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    33
    {
69329
8bbde4dba926 tuned error;
wenzelm
parents: 69328
diff changeset
    34
      if (c == '\u0000' || c == '\r' || c == q) err(c)
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    35
      else if (c == '\n') "\\n"
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    36
      else if (c == '\\') "\\\\"
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    37
      else c.toString
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    38
    }
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    39
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    40
    if (s.nonEmpty && s(0) == '\\') err('\\')
69329
8bbde4dba926 tuned error;
wenzelm
parents: 69328
diff changeset
    41
    s.iterator.map(escape(_)).mkString(q.toString, "", q.toString)
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    42
  }
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    43
69333
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    44
  def file_name(path: Path): Script = string(File.standard_path(path))
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    45
69333
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    46
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    47
  /* commands */
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    48
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    49
  // fonts
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    50
  def open(path: Path): Script = "Open(" + file_name(path) +")"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    51
  def generate(path: Path): Script = "Generate(" + file_name(path) +")"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    52
  def set_font_names(
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    53
    fontname: String = "",
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    54
    family: String = "",
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    55
    fullname: String = "",
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    56
    weight: String = "",
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    57
    copyright: String = "",
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    58
    fontversion: String = ""): Script =
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    59
  {
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    60
    List(fontname, family, fullname, weight, copyright, fontversion).map(string(_)).
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    61
      mkString("SetFontNames(", ",", ")")
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    62
  }
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    63
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    64
  // selection
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    65
  def select(args: Seq[Int]): Script = "SelectSingletons(" + args.mkString(",") + ")"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    66
  def select_all: Script = "SelectAll()"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    67
  def select_none: Script = "SelectNone()"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    68
  def select_invert: Script = "SelectInvert()"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    69
  def clear: Script = "Clear()"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    70
  def copy: Script = "Copy()"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    71
  def paste: Script = "Paste()"
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    72
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    73
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    74
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    75
  /** execute fontforge program **/
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    76
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    77
  def execute(script: Script, args: String = "", cwd: JFile = null): Process_Result =
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    78
    Isabelle_System.with_tmp_file("fontforge")(script_file =>
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    79
    {
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    80
      File.write(script_file, script)
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    81
      Isabelle_System.bash(File.bash_path(Path.explode("$ISABELLE_FONTFORGE")) +
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    82
        " -lang=ff -script " + File.bash_path(script_file) + " " + args)
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    83
    })
69333
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    84
69334
6b49700da068 clarified font_domain: strict excludes e.g. space character;
wenzelm
parents: 69333
diff changeset
    85
  def font_domain(path: Path, strict: Boolean = false): List[Int] =
69333
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    86
  {
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    87
    val script = """
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    88
i = 0
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    89
while (i < CharCnt())
69334
6b49700da068 clarified font_domain: strict excludes e.g. space character;
wenzelm
parents: 69333
diff changeset
    90
  if (""" + (if (strict) "DrawsSomething" else "WorthOutputting") + """(i)); Print(i); endif
6b49700da068 clarified font_domain: strict excludes e.g. space character;
wenzelm
parents: 69333
diff changeset
    91
  i = i + 1
69333
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    92
endloop
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    93
"""
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    94
    Library.trim_split_lines(execute(open(path) + script).check.out).
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    95
      map(Value.Int.parse)
c889afca73a5 proper documentation;
wenzelm
parents: 69329
diff changeset
    96
  }
69328
4646fcb59121 support for fontforge and its scripting language;
wenzelm
parents:
diff changeset
    97
}