src/Tools/jEdit/src/text_painter.scala
changeset 43376 0f6880c1c759
parent 43375 09d992ab57c6
equal deleted inserted replaced
43375:09d992ab57c6 43376:0f6880c1c759
    15 import org.gjt.sp.jedit.Debug
    15 import org.gjt.sp.jedit.Debug
    16 import org.gjt.sp.jedit.syntax.{DisplayTokenHandler, Chunk}
    16 import org.gjt.sp.jedit.syntax.{DisplayTokenHandler, Chunk}
    17 import org.gjt.sp.jedit.textarea.{JEditTextArea, TextAreaExtension, TextAreaPainter}
    17 import org.gjt.sp.jedit.textarea.{JEditTextArea, TextAreaExtension, TextAreaPainter}
    18 
    18 
    19 
    19 
    20 class Text_Painter(model: Document_Model, text_area: JEditTextArea) extends TextAreaExtension
    20 class Text_Painter(doc_view: Document_View) extends TextAreaExtension
    21 {
    21 {
       
    22   private val text_area = doc_view.text_area
       
    23 
    22   private val orig_text_painter: TextAreaExtension =
    24   private val orig_text_painter: TextAreaExtension =
    23   {
    25   {
    24     val name = "org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText"
    26     val name = "org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText"
    25     text_area.getPainter.getExtensions.iterator.filter(x => x.getClass.getName == name).toList
    27     text_area.getPainter.getExtensions.iterator.filter(x => x.getClass.getName == name).toList
    26     match {
    28     match {
    31 
    33 
    32   override def paintScreenLineRange(gfx: Graphics2D,
    34   override def paintScreenLineRange(gfx: Graphics2D,
    33     first_line: Int, last_line: Int, physical_lines: Array[Int],
    35     first_line: Int, last_line: Int, physical_lines: Array[Int],
    34     start: Array[Int], end: Array[Int], y_start: Int, line_height: Int)
    36     start: Array[Int], end: Array[Int], y_start: Int, line_height: Int)
    35   {
    37   {
    36     def paint_chunk_list(head: Chunk, x: Float, y: Float): Float =
       
    37     {
       
    38       val clip_rect = gfx.getClipBounds
       
    39       var w = 0.0f
       
    40       var chunk = head
       
    41       while (chunk != null) {
       
    42         if (x + w + chunk.width > clip_rect.x &&
       
    43             x + w < clip_rect.x + clip_rect.width &&
       
    44             chunk.accessable && chunk.visible)
       
    45         {
       
    46           gfx.setFont(chunk.style.getFont)
       
    47           gfx.setColor(chunk.style.getForegroundColor)
       
    48           if (!Debug.DISABLE_GLYPH_VECTOR && chunk.gv != null)
       
    49             gfx.drawGlyphVector(chunk.gv, x + w, y)
       
    50           else if (chunk.str != null)
       
    51             gfx.drawString(chunk.str, (x + w).toInt, y.toInt)
       
    52         }
       
    53         w += chunk.width
       
    54         chunk = chunk.next.asInstanceOf[Chunk]
       
    55       }
       
    56       w
       
    57     }
       
    58 
       
    59     val buffer = text_area.getBuffer
    38     val buffer = text_area.getBuffer
    60     Isabelle.swing_buffer_lock(buffer) {
    39     Isabelle.swing_buffer_lock(buffer) {
    61       val painter = text_area.getPainter
    40       val painter = text_area.getPainter
    62       val font = painter.getFont
    41       val font = painter.getFont
    63       val font_context = painter.getFontRenderContext
    42       val font_context = painter.getFontRenderContext
    64       val fm = painter.getFontMetrics
    43       val font_metrics = painter.getFontMetrics
       
    44 
       
    45       def paint_chunk_list(head_offset: Text.Offset, head: Chunk, x: Float, y: Float): Float =
       
    46       {
       
    47         val clip_rect = gfx.getClipBounds
       
    48 
       
    49         var w = 0.0f
       
    50         var offset = head_offset
       
    51         var chunk = head
       
    52         while (chunk != null) {
       
    53           val chunk_length = if (chunk.str == null) 0 else chunk.str.length
       
    54 
       
    55           if (x + w + chunk.width > clip_rect.x &&
       
    56               x + w < clip_rect.x + clip_rect.width &&
       
    57               chunk.accessable && chunk.visible)
       
    58           {
       
    59             val chunk_range = Text.Range(offset, offset + chunk_length)
       
    60             val chunk_font = chunk.style.getFont
       
    61             val chunk_color = chunk.style.getForegroundColor
       
    62 
       
    63             val markup =
       
    64               doc_view.text_area_snapshot.select_markup(chunk_range)(Isabelle_Markup.foreground)
       
    65 
       
    66             gfx.setFont(chunk_font)
       
    67             if (!Debug.DISABLE_GLYPH_VECTOR && chunk.gv != null &&
       
    68                 markup.forall(info => info.info.isEmpty)) {
       
    69               gfx.setColor(chunk_color)
       
    70               gfx.drawGlyphVector(chunk.gv, x + w, y)
       
    71             }
       
    72             else {
       
    73               var xpos = x + w
       
    74               for (Text.Info(range, info) <- markup) {
       
    75                 val str = chunk.str.substring(range.start - offset, range.stop - offset)
       
    76                 gfx.setColor(info.getOrElse(chunk_color))
       
    77                 gfx.drawString(str, xpos.toInt, y.toInt)
       
    78                 xpos += chunk_font.getStringBounds(str, font_context).getWidth.toFloat
       
    79               }
       
    80             }
       
    81           }
       
    82           w += chunk.width
       
    83           offset += chunk_length
       
    84           chunk = chunk.next.asInstanceOf[Chunk]
       
    85         }
       
    86         w
       
    87       }
    65 
    88 
    66       // see org.gjt.sp.jedit.textarea.TextArea.propertiesChanged
    89       // see org.gjt.sp.jedit.textarea.TextArea.propertiesChanged
    67       // see org.gjt.sp.jedit.textarea.TextArea.setMaxLineLength
    90       // see org.gjt.sp.jedit.textarea.TextArea.setMaxLineLength
    68       val char_width = font.getStringBounds(" ", font_context).getWidth.round.toInt
    91       val char_width = font.getStringBounds(" ", font_context).getWidth.round.toInt
    69       val soft_wrap = buffer.getStringProperty("wrap") == "soft"
    92       val soft_wrap = buffer.getStringProperty("wrap") == "soft"
    96         result
   119         result
    97       }
   120       }
    98 
   121 
    99       val clip = gfx.getClip
   122       val clip = gfx.getClip
   100       val x0 = text_area.getHorizontalOffset
   123       val x0 = text_area.getHorizontalOffset
   101       var y0 = y_start + fm.getHeight - (fm.getLeading + 1) - fm.getDescent
   124       var y0 =
       
   125         y_start + font_metrics.getHeight - (font_metrics.getLeading + 1) - font_metrics.getDescent
       
   126 
   102       for (i <- 0 until physical_lines.length) {
   127       for (i <- 0 until physical_lines.length) {
   103         if (physical_lines(i) != -1) {
   128         if (physical_lines(i) != -1) {
   104           line_infos.get(start(i)) match {
   129           line_infos.get(start(i)) match {
   105             case Some(chunk) =>
   130             case Some(chunk) =>
   106               val w = paint_chunk_list(chunk, x0, y0).toInt
   131               val w = paint_chunk_list(start(i), chunk, x0, y0).toInt
   107               gfx.clipRect(x0 + w, 0, Integer.MAX_VALUE, Integer.MAX_VALUE)
   132               gfx.clipRect(x0 + w, 0, Integer.MAX_VALUE, Integer.MAX_VALUE)
   108               orig_text_painter.paintValidLine(gfx,
   133               orig_text_painter.paintValidLine(gfx,
   109                 first_line + i, physical_lines(i), start(i), end(i), y_start + line_height * i)
   134                 first_line + i, physical_lines(i), start(i), end(i), y_start + line_height * i)
   110               gfx.setClip(clip)
   135               gfx.setClip(clip)
   111 
   136