src/Tools/Graphview/metrics.scala
author wenzelm
Wed, 30 Jun 2021 22:14:27 +0200
changeset 73909 1d0d9772fff0
parent 73359 d8a0e996614b
child 75393 87ebf5a50283
permissions -rw-r--r--
tuned imports;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     1
/*  Title:      Tools/Graphview/metrics.scala
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     3
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     4
Physical metrics for layout and painting.
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     5
*/
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     6
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     7
package isabelle.graphview
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     8
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
     9
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    10
import isabelle._
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    11
73909
1d0d9772fff0 tuned imports;
wenzelm
parents: 73359
diff changeset
    12
import java.util.HashMap
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    13
import java.awt.{Font, RenderingHints}
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    14
import java.awt.font.FontRenderContext
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    15
import java.awt.geom.Rectangle2D
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    16
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    17
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    18
object Metrics
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    19
{
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    20
  val rendering_hints: RenderingHints =
59389
c427f3de9050 prefer fractional font metrics, for proper scaling of node size;
wenzelm
parents: 59388
diff changeset
    21
  {
73909
1d0d9772fff0 tuned imports;
wenzelm
parents: 73359
diff changeset
    22
    val hints = new HashMap[RenderingHints.Key, AnyRef]
59389
c427f3de9050 prefer fractional font metrics, for proper scaling of node size;
wenzelm
parents: 59388
diff changeset
    23
    hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
c427f3de9050 prefer fractional font metrics, for proper scaling of node size;
wenzelm
parents: 59388
diff changeset
    24
    hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON)
c427f3de9050 prefer fractional font metrics, for proper scaling of node size;
wenzelm
parents: 59388
diff changeset
    25
    new RenderingHints(hints)
c427f3de9050 prefer fractional font metrics, for proper scaling of node size;
wenzelm
parents: 59388
diff changeset
    26
  }
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    27
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    28
  val font_render_context: FontRenderContext =
59389
c427f3de9050 prefer fractional font metrics, for proper scaling of node size;
wenzelm
parents: 59388
diff changeset
    29
    new FontRenderContext(null, true, true)
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    30
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    31
  def apply(font: Font): Metrics = new Metrics(font)
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    32
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    33
  val default: Metrics = apply(new Font("Helvetica", Font.PLAIN, 12))
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    34
}
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    35
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    36
class Metrics private(val font: Font)
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    37
{
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    38
  def string_bounds(s: String): Rectangle2D = font.getStringBounds(s, Metrics.font_render_context)
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    39
  private val mix = string_bounds("mix")
71383
8313dca6dee9 misc tuning, following hint by IntelliJ;
wenzelm
parents: 59389
diff changeset
    40
  val space_width: Double = string_bounds(" ").getWidth
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    41
  def char_width: Double = mix.getWidth / 3
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    42
  def height: Double = mix.getHeight
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    43
  def ascent: Double = font.getLineMetrics("", Metrics.font_render_context).getAscent
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    44
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    45
  def gap: Double = mix.getWidth.ceil
59302
4d985afc0565 explict layout graph structure, with dummies and coordinates;
wenzelm
parents: 59293
diff changeset
    46
59388
04cdfd536e7d tuned metrics;
wenzelm
parents: 59384
diff changeset
    47
  def dummy_size2: Double = (char_width / 2).ceil
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    48
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    49
  def node_width2(lines: List[String]): Double =
73359
d8a0e996614b tuned --- fewer warnings;
wenzelm
parents: 71383
diff changeset
    50
    ((lines.foldLeft(0.0)({ case (w, s) => w max string_bounds(s).getWidth }) + 2 * char_width) / 2)
d8a0e996614b tuned --- fewer warnings;
wenzelm
parents: 71383
diff changeset
    51
      .ceil
59302
4d985afc0565 explict layout graph structure, with dummies and coordinates;
wenzelm
parents: 59293
diff changeset
    52
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    53
  def node_height2(num_lines: Int): Double =
59388
04cdfd536e7d tuned metrics;
wenzelm
parents: 59384
diff changeset
    54
    ((height.ceil * (num_lines max 1) + char_width) / 2).ceil
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    55
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    56
  def level_height2(num_lines: Int, num_edges: Int): Double =
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    57
    (node_height2(num_lines) + gap) max (node_height2(1) * (num_edges max 5))
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    58
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    59
  object Pretty_Metric extends Pretty.Metric
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    60
  {
71383
8313dca6dee9 misc tuning, following hint by IntelliJ;
wenzelm
parents: 59389
diff changeset
    61
    val unit: Double = space_width max 1.0
59384
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    62
    def apply(s: String): Double = if (s == "\n") 1.0 else string_bounds(s).getWidth / unit
c75327a34960 more explicit Layout.Info: size and content;
wenzelm
parents: 59302
diff changeset
    63
  }
59290
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    64
}
569a8109eeb2 separate module Metrics;
wenzelm
parents:
diff changeset
    65