--- 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)