clarified signature: afford explicit Scala data types;
authorwenzelm
Thu, 11 Jul 2024 23:36:54 +0200
changeset 80558 69e21910febc
parent 80557 08034bb75ee8
child 80559 38c63d4027c4
clarified signature: afford explicit Scala data types;
src/Tools/jEdit/src/rich_text_area.scala
--- a/src/Tools/jEdit/src/rich_text_area.scala	Thu Jul 11 22:39:04 2024 +0200
+++ b/src/Tools/jEdit/src/rich_text_area.scala	Thu Jul 11 23:36:54 2024 +0200
@@ -18,10 +18,11 @@
 import java.text.AttributedString
 
 import scala.util.matching.Regex
+import scala.collection.mutable
 
 import org.gjt.sp.util.Log
 import org.gjt.sp.jedit.View
-import org.gjt.sp.jedit.syntax.{Chunk => JEditChunk}
+import org.gjt.sp.jedit.syntax.{Chunk => JEditChunk, SyntaxStyle}
 import org.gjt.sp.jedit.textarea.{TextAreaExtension, TextAreaPainter, TextArea}
 
 
@@ -419,13 +420,40 @@
         })
   }
 
+  sealed case class Chunk(
+    id: Byte,
+    style: SyntaxStyle,
+    offset: Int,
+    length: Int,
+    width: Float,
+    font_subst: Boolean,
+    str: String
+  )
+
+  private def make_chunk_list(chunk_head: JEditChunk): List[Chunk] = {
+    val buf = new mutable.ListBuffer[Chunk]
+    var chunk = chunk_head
+    while (chunk != null) {
+      val str =
+        if (chunk.chars == null) Symbol.spaces(chunk.length)
+        else {
+          if (chunk.str == null) { chunk.str = new String(chunk.chars) }
+          chunk.str
+        }
+      buf += Chunk(chunk.id, chunk.style, chunk.offset, chunk.length, chunk.width,
+        chunk.usedFontSubstitution, str)
+      chunk = chunk.next.asInstanceOf[JEditChunk]
+    }
+    buf.toList
+  }
+
   private def paint_chunk_list(
     rendering: JEdit_Rendering,
     font_subst: Font_Subst,
     gfx: Graphics2D,
     line_start: Text.Offset,
     caret_range: Text.Range,
-    chunk_list: JEditChunk,
+    chunk_list: List[Chunk],
     x0: Int,
     y0: Int
   ): Float = {
@@ -433,23 +461,14 @@
 
     val x = x0.toFloat
     val y = y0.toFloat
-    var w = 0.0f
-    var chunk = chunk_list
-    while (chunk != null) {
+    chunk_list.foldLeft(0.0f) { case (w, chunk) =>
       val chunk_offset = line_start + chunk.offset
       if (x + w + chunk.width > clip_rect.x &&
           x + w < clip_rect.x + clip_rect.width && chunk.length > 0) {
         val chunk_range = Text.Range(chunk_offset, chunk_offset + chunk.length)
-        val chunk_str =
-          if (chunk.chars == null) Symbol.spaces(chunk.length)
-          else {
-            if (chunk.str == null) { chunk.str = new String(chunk.chars) }
-            chunk.str
-          }
         val chunk_font = chunk.style.getFont
         val chunk_color = chunk.style.getForegroundColor
-
-        val chunk_text = new AttributedString(chunk_str)
+        val chunk_text = new AttributedString(chunk.str)
 
         def chunk_attrib(attrib: TextAttribute, value: AnyRef, r: Text.Range): Unit =
           chunk_text.addAttribute(attrib, value, r.start - chunk_offset, r.stop - chunk_offset)
@@ -457,9 +476,9 @@
         // font
         chunk_text.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_LTR)
         chunk_text.addAttribute(TextAttribute.FONT, chunk_font)
-        if (chunk.usedFontSubstitution) {
+        if (chunk.font_subst) {
           for {
-            (c, i) <- Codepoint.iterator_offset(chunk_str) if !chunk_font.canDisplay(c)
+            (c, i) <- Codepoint.iterator_offset(chunk.str) if !chunk_font.canDisplay(c)
             subst_font <- font_subst.get(c)
           } {
             val r = Text.Range(i, i + Character.charCount(c)) + chunk_offset
@@ -483,10 +502,8 @@
 
         gfx.drawString(chunk_text.getIterator, x + w, y)
       }
-      w += chunk.width
-      chunk = chunk.next.asInstanceOf[JEditChunk]
+      w + chunk.width
     }
-    w
   }
 
   private val text_painter = new TextAreaExtension {
@@ -525,8 +542,8 @@
 
             // text chunks
             val screen_line = first_line + i
-            val chunks = text_area.getChunksOfScreenLine(screen_line)
-            if (chunks != null) {
+            val chunk_list = make_chunk_list(text_area.getChunksOfScreenLine(screen_line))
+            if (chunk_list.nonEmpty) {
               try {
                 val line_start = buffer.getLineStartOffset(line)
                 val caret_range =
@@ -535,7 +552,7 @@
                 gfx.clipRect(x0, y + line_height * i, Int.MaxValue, line_height)
                 val w =
                   paint_chunk_list(rendering, font_subst, gfx,
-                    line_start, caret_range, chunks, x0, y0)
+                    line_start, caret_range, chunk_list, x0, y0)
                 gfx.clipRect(x0 + w.toInt, 0, Int.MaxValue, Int.MaxValue)
                 orig_text_painter.paintValidLine(gfx,
                   screen_line, line, start(i), end(i), y + line_height * i)