src/Tools/jEdit/src/text_painter.scala
author wenzelm
Sun, 12 Jun 2011 22:26:03 +0200
changeset 43371 98de43fc9733
parent 43370 1d6ce56e9b2f
child 43372 2df2144b0910
permissions -rw-r--r--
more precise imitation of original TextAreaPainter$PaintText;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     1
/*  Title:      Tools/jEdit/src/text_painter.scala
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     3
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     4
Replacement painter for jEdit text area.
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     5
*/
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     6
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     7
package isabelle.jedit
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     8
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     9
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    10
import isabelle._
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    11
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    12
import java.awt.{Graphics, Graphics2D}
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    13
import java.util.ArrayList
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    14
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    15
import org.gjt.sp.jedit.Debug
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    16
import org.gjt.sp.jedit.syntax.{DisplayTokenHandler, Chunk}
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    17
import org.gjt.sp.jedit.textarea.{JEditTextArea, TextAreaExtension, TextAreaPainter}
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    18
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    19
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    20
class Text_Painter(model: Document_Model, text_area: JEditTextArea) extends TextAreaExtension
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    21
{
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    22
  private val orig_text_painter: TextAreaExtension =
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    23
  {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    24
    val name = "org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText"
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    25
    text_area.getPainter.getExtensions.iterator.filter(x => x.getClass.getName == name).toList
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    26
    match {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    27
      case List(x) => x
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    28
      case _ => error("Expected exactly one " + name)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    29
    }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    30
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    31
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    32
  var use = false
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    33
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    34
  override def paintScreenLineRange(gfx: Graphics2D,
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    35
    first_line: Int, last_line: Int, physical_lines: Array[Int],
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    36
    start: Array[Int], end: Array[Int], y: Int, line_height: Int)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    37
  {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    38
    if (use) {
43371
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    39
      val buffer = text_area.getBuffer
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    40
      Isabelle.swing_buffer_lock(buffer) {
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    41
        val painter = text_area.getPainter
43371
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    42
        val font = painter.getFont
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    43
        val font_context = painter.getFontRenderContext
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    44
        val fm = painter.getFontMetrics
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    45
43371
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    46
        // see org.gjt.sp.jedit.textarea.TextArea.propertiesChanged
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    47
        // and org.gjt.sp.jedit.textarea.TextArea.setMaxLineLength
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    48
        val char_width = font.getStringBounds(" ", font_context).getWidth.round.toInt
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    49
        val soft_wrap = buffer.getStringProperty("wrap") == "soft"
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    50
        val wrap_margin =
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    51
        {
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    52
          val max = buffer.getIntegerProperty("maxLineLen", 0)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    53
          if (max > 0) font.getStringBounds(" " * max, font_context).getWidth.toInt
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    54
          else if (soft_wrap)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    55
            painter.getWidth - (font.getStringBounds(" ", font_context).getWidth.round.toInt) * 3
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    56
          else 0
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    57
        }.toFloat
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    58
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    59
        type Line_Info = (Chunk, Boolean)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    60
        val line_infos: Map[Text.Offset, Line_Info] =
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    61
        {
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    62
          import scala.collection.JavaConversions._
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    63
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    64
          val out = new ArrayList[Chunk]
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    65
          val handler = new DisplayTokenHandler
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    66
          val margin = if (soft_wrap) wrap_margin else 0.0f
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    67
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    68
          var result = Map[Text.Offset, Line_Info]()
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    69
          for (line <- physical_lines.iterator.filter(i => i != -1)) {
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    70
            out.clear
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    71
            handler.init(painter.getStyles, font_context, painter, out, margin)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    72
            buffer.markTokens(line, handler)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    73
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    74
            val line_start = buffer.getLineStartOffset(line)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    75
            val len = out.size
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    76
            for (i <- 0 until len) {
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    77
              val chunk = out.get(i)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    78
              result += (line_start + chunk.offset -> (chunk, i == len - 1))
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    79
            }
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    80
          }
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    81
          result
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    82
        }
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    83
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    84
        val x0 = text_area.getHorizontalOffset
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    85
        var y0 = y + fm.getHeight - (fm.getLeading + 1) - fm.getDescent
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    86
        for (i <- 0 until physical_lines.length) {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    87
          if (physical_lines(i) != -1) {
43371
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    88
            line_infos.get(start(i)) match {
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    89
              case Some((chunk, last_subregion)) =>
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    90
                val x1 = x0 + Chunk.paintChunkList(chunk, gfx, x0, y0, !Debug.DISABLE_GLYPH_VECTOR)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    91
                if (!last_subregion) {
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    92
                  gfx.setFont(font)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    93
                  gfx.setColor(painter.getEOLMarkerColor)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    94
                  gfx.drawString(":", (x0 + wrap_margin + char_width) max x1, y0)
98de43fc9733 more precise imitation of original TextAreaPainter$PaintText;
wenzelm
parents: 43370
diff changeset
    95
                }
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    96
              case None =>
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    97
            }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    98
          }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    99
          y0 += line_height
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   100
        }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   101
      }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   102
    }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   103
    else
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   104
      orig_text_painter.paintScreenLineRange(
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   105
        gfx, first_line, last_line, physical_lines, start, end, y, line_height)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   106
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   107
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   108
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   109
  /* activation */
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   110
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   111
  def activate()
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   112
  {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   113
    val painter = text_area.getPainter
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   114
    painter.removeExtension(orig_text_painter)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   115
    painter.addExtension(TextAreaPainter.TEXT_LAYER, this)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   116
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   117
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   118
  def deactivate()
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   119
  {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   120
    val painter = text_area.getPainter
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   121
    painter.removeExtension(this)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   122
    painter.addExtension(TextAreaPainter.TEXT_LAYER, orig_text_painter)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   123
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   124
}
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   125