73 pick_extension("org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText") |
73 pick_extension("org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText") |
74 |
74 |
75 |
75 |
76 /* common painter state */ |
76 /* common painter state */ |
77 |
77 |
78 @volatile private var painter_snapshot: Document.Snapshot = null |
78 @volatile private var painter_rendering: Isabelle_Rendering = null |
79 @volatile private var painter_clip: Shape = null |
79 @volatile private var painter_clip: Shape = null |
80 |
80 |
81 private val set_state = new TextAreaExtension |
81 private val set_state = new TextAreaExtension |
82 { |
82 { |
83 override def paintScreenLineRange(gfx: Graphics2D, |
83 override def paintScreenLineRange(gfx: Graphics2D, |
84 first_line: Int, last_line: Int, physical_lines: Array[Int], |
84 first_line: Int, last_line: Int, physical_lines: Array[Int], |
85 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
85 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
86 { |
86 { |
87 painter_snapshot = model.snapshot() |
87 painter_rendering = Isabelle_Rendering(model.snapshot(), Isabelle.options.value) |
88 painter_clip = gfx.getClip |
88 painter_clip = gfx.getClip |
89 } |
89 } |
90 } |
90 } |
91 |
91 |
92 private val reset_state = new TextAreaExtension |
92 private val reset_state = new TextAreaExtension |
93 { |
93 { |
94 override def paintScreenLineRange(gfx: Graphics2D, |
94 override def paintScreenLineRange(gfx: Graphics2D, |
95 first_line: Int, last_line: Int, physical_lines: Array[Int], |
95 first_line: Int, last_line: Int, physical_lines: Array[Int], |
96 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
96 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
97 { |
97 { |
98 painter_snapshot = null |
98 painter_rendering = null |
99 painter_clip = null |
99 painter_clip = null |
100 } |
100 } |
101 } |
101 } |
102 |
102 |
103 private def robust_snapshot(body: Document.Snapshot => Unit) |
103 private def robust_rendering(body: Isabelle_Rendering => Unit) |
104 { |
104 { |
105 doc_view.robust_body(()) { body(painter_snapshot) } |
105 doc_view.robust_body(()) { body(painter_rendering) } |
106 } |
106 } |
107 |
107 |
108 |
108 |
109 /* text background */ |
109 /* text background */ |
110 |
110 |
112 { |
112 { |
113 override def paintScreenLineRange(gfx: Graphics2D, |
113 override def paintScreenLineRange(gfx: Graphics2D, |
114 first_line: Int, last_line: Int, physical_lines: Array[Int], |
114 first_line: Int, last_line: Int, physical_lines: Array[Int], |
115 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
115 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
116 { |
116 { |
117 robust_snapshot { snapshot => |
117 robust_rendering { rendering => |
118 val ascent = text_area.getPainter.getFontMetrics.getAscent |
118 val ascent = text_area.getPainter.getFontMetrics.getAscent |
119 |
119 |
120 for (i <- 0 until physical_lines.length) { |
120 for (i <- 0 until physical_lines.length) { |
121 if (physical_lines(i) != -1) { |
121 if (physical_lines(i) != -1) { |
122 val line_range = doc_view.proper_line_range(start(i), end(i)) |
122 val line_range = doc_view.proper_line_range(start(i), end(i)) |
123 |
123 |
124 // background color (1) |
124 // background color (1) |
125 for { |
125 for { |
126 Text.Info(range, color) <- Isabelle_Rendering.background1(snapshot, line_range) |
126 Text.Info(range, color) <- rendering.background1(line_range) |
127 r <- gfx_range(range) |
127 r <- gfx_range(range) |
128 } { |
128 } { |
129 gfx.setColor(color) |
129 gfx.setColor(color) |
130 gfx.fillRect(r.x, y + i * line_height, r.length, line_height) |
130 gfx.fillRect(r.x, y + i * line_height, r.length, line_height) |
131 } |
131 } |
132 |
132 |
133 // background color (2) |
133 // background color (2) |
134 for { |
134 for { |
135 Text.Info(range, color) <- Isabelle_Rendering.background2(snapshot, line_range) |
135 Text.Info(range, color) <- rendering.background2(line_range) |
136 r <- gfx_range(range) |
136 r <- gfx_range(range) |
137 } { |
137 } { |
138 gfx.setColor(color) |
138 gfx.setColor(color) |
139 gfx.fillRect(r.x + 2, y + i * line_height + 2, r.length - 4, line_height - 4) |
139 gfx.fillRect(r.x + 2, y + i * line_height + 2, r.length - 4, line_height - 4) |
140 } |
140 } |
141 |
141 |
142 // squiggly underline |
142 // squiggly underline |
143 for { |
143 for { |
144 Text.Info(range, color) <- Isabelle_Rendering.squiggly_underline(snapshot, line_range) |
144 Text.Info(range, color) <- rendering.squiggly_underline(line_range) |
145 r <- gfx_range(range) |
145 r <- gfx_range(range) |
146 } { |
146 } { |
147 gfx.setColor(color) |
147 gfx.setColor(color) |
148 val x0 = (r.x / 2) * 2 |
148 val x0 = (r.x / 2) * 2 |
149 val y0 = r.y + ascent + 1 |
149 val y0 = r.y + ascent + 1 |
159 } |
159 } |
160 |
160 |
161 |
161 |
162 /* text */ |
162 /* text */ |
163 |
163 |
164 private def paint_chunk_list(snapshot: Document.Snapshot, |
164 private def paint_chunk_list(rendering: Isabelle_Rendering, |
165 gfx: Graphics2D, line_start: Text.Offset, head: Chunk, x: Float, y: Float): Float = |
165 gfx: Graphics2D, line_start: Text.Offset, head: Chunk, x: Float, y: Float): Float = |
166 { |
166 { |
167 val clip_rect = gfx.getClipBounds |
167 val clip_rect = gfx.getClipBounds |
168 val painter = text_area.getPainter |
168 val painter = text_area.getPainter |
169 val font_context = painter.getFontRenderContext |
169 val font_context = painter.getFontRenderContext |
244 { |
244 { |
245 override def paintScreenLineRange(gfx: Graphics2D, |
245 override def paintScreenLineRange(gfx: Graphics2D, |
246 first_line: Int, last_line: Int, physical_lines: Array[Int], |
246 first_line: Int, last_line: Int, physical_lines: Array[Int], |
247 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
247 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
248 { |
248 { |
249 robust_snapshot { snapshot => |
249 robust_rendering { rendering => |
250 val clip = gfx.getClip |
250 val clip = gfx.getClip |
251 val x0 = text_area.getHorizontalOffset |
251 val x0 = text_area.getHorizontalOffset |
252 val fm = text_area.getPainter.getFontMetrics |
252 val fm = text_area.getPainter.getFontMetrics |
253 var y0 = y + fm.getHeight - (fm.getLeading + 1) - fm.getDescent |
253 var y0 = y + fm.getHeight - (fm.getLeading + 1) - fm.getDescent |
254 |
254 |
258 val screen_line = first_line + i |
258 val screen_line = first_line + i |
259 val chunks = text_area.getChunksOfScreenLine(screen_line) |
259 val chunks = text_area.getChunksOfScreenLine(screen_line) |
260 if (chunks != null) { |
260 if (chunks != null) { |
261 val line_start = text_area.getBuffer.getLineStartOffset(line) |
261 val line_start = text_area.getBuffer.getLineStartOffset(line) |
262 gfx.clipRect(x0, y + line_height * i, Integer.MAX_VALUE, line_height) |
262 gfx.clipRect(x0, y + line_height * i, Integer.MAX_VALUE, line_height) |
263 val w = paint_chunk_list(snapshot, gfx, line_start, chunks, x0, y0).toInt |
263 val w = paint_chunk_list(rendering, gfx, line_start, chunks, x0, y0).toInt |
264 gfx.clipRect(x0 + w.toInt, 0, Integer.MAX_VALUE, Integer.MAX_VALUE) |
264 gfx.clipRect(x0 + w.toInt, 0, Integer.MAX_VALUE, Integer.MAX_VALUE) |
265 orig_text_painter.paintValidLine(gfx, |
265 orig_text_painter.paintValidLine(gfx, |
266 screen_line, line, start(i), end(i), y + line_height * i) |
266 screen_line, line, start(i), end(i), y + line_height * i) |
267 gfx.setClip(clip) |
267 gfx.setClip(clip) |
268 } |
268 } |
280 { |
280 { |
281 override def paintScreenLineRange(gfx: Graphics2D, |
281 override def paintScreenLineRange(gfx: Graphics2D, |
282 first_line: Int, last_line: Int, physical_lines: Array[Int], |
282 first_line: Int, last_line: Int, physical_lines: Array[Int], |
283 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
283 start: Array[Int], end: Array[Int], y: Int, line_height: Int) |
284 { |
284 { |
285 robust_snapshot { snapshot => |
285 robust_rendering { rendering => |
286 for (i <- 0 until physical_lines.length) { |
286 for (i <- 0 until physical_lines.length) { |
287 if (physical_lines(i) != -1) { |
287 if (physical_lines(i) != -1) { |
288 val line_range = doc_view.proper_line_range(start(i), end(i)) |
288 val line_range = doc_view.proper_line_range(start(i), end(i)) |
289 |
289 |
290 // foreground color |
290 // foreground color |
291 for { |
291 for { |
292 Text.Info(range, color) <- Isabelle_Rendering.foreground(snapshot, line_range) |
292 Text.Info(range, color) <- rendering.foreground(line_range) |
293 r <- gfx_range(range) |
293 r <- gfx_range(range) |
294 } { |
294 } { |
295 gfx.setColor(color) |
295 gfx.setColor(color) |
296 gfx.fillRect(r.x, y + i * line_height, r.length, line_height) |
296 gfx.fillRect(r.x, y + i * line_height, r.length, line_height) |
297 } |
297 } |
310 for { |
310 for { |
311 info <- doc_view.hyperlink_range() |
311 info <- doc_view.hyperlink_range() |
312 Text.Info(range, _) <- info.try_restrict(line_range) |
312 Text.Info(range, _) <- info.try_restrict(line_range) |
313 r <- gfx_range(range) |
313 r <- gfx_range(range) |
314 } { |
314 } { |
315 gfx.setColor(Isabelle_Rendering.color_value("hyperlink_color")) |
315 gfx.setColor(rendering.hyperlink_color) |
316 gfx.drawRect(r.x, y + i * line_height, r.length - 1, line_height - 1) |
316 gfx.drawRect(r.x, y + i * line_height, r.length - 1, line_height - 1) |
317 } |
317 } |
318 } |
318 } |
319 } |
319 } |
320 } |
320 } |
327 private class Caret_Painter(before: Boolean) extends TextAreaExtension |
327 private class Caret_Painter(before: Boolean) extends TextAreaExtension |
328 { |
328 { |
329 override def paintValidLine(gfx: Graphics2D, |
329 override def paintValidLine(gfx: Graphics2D, |
330 screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int) |
330 screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int) |
331 { |
331 { |
332 robust_snapshot { _ => |
332 robust_rendering { _ => |
333 if (before) gfx.clipRect(0, 0, 0, 0) |
333 if (before) gfx.clipRect(0, 0, 0, 0) |
334 else gfx.setClip(painter_clip) |
334 else gfx.setClip(painter_clip) |
335 } |
335 } |
336 } |
336 } |
337 } |
337 } |
344 private val caret_painter = new TextAreaExtension |
344 private val caret_painter = new TextAreaExtension |
345 { |
345 { |
346 override def paintValidLine(gfx: Graphics2D, |
346 override def paintValidLine(gfx: Graphics2D, |
347 screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int) |
347 screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int) |
348 { |
348 { |
349 robust_snapshot { _ => |
349 robust_rendering { _ => |
350 if (text_area.isCaretVisible) { |
350 if (text_area.isCaretVisible) { |
351 val caret = text_area.getCaretPosition |
351 val caret = text_area.getCaretPosition |
352 if (start <= caret && caret == end - 1) { |
352 if (start <= caret && caret == end - 1) { |
353 val painter = text_area.getPainter |
353 val painter = text_area.getPainter |
354 val fm = painter.getFontMetrics |
354 val fm = painter.getFontMetrics |