406 |
406 |
407 private def paint_chunk_list(rendering: JEdit_Rendering, |
407 private def paint_chunk_list(rendering: JEdit_Rendering, |
408 gfx: Graphics2D, line_start: Text.Offset, head: Chunk, x: Float, y: Float): Float = |
408 gfx: Graphics2D, line_start: Text.Offset, head: Chunk, x: Float, y: Float): Float = |
409 { |
409 { |
410 val clip_rect = gfx.getClipBounds |
410 val clip_rect = gfx.getClipBounds |
411 val painter = text_area.getPainter |
|
412 val font_context = painter.getFontRenderContext |
|
413 |
411 |
414 val caret_range = |
412 val caret_range = |
415 if (caret_enabled) JEdit_Lib.caret_range(text_area) |
413 if (caret_enabled) JEdit_Lib.caret_range(text_area) |
416 else Text.Range.offside |
414 else Text.Range.offside |
417 |
415 |
430 chunk.str |
428 chunk.str |
431 } |
429 } |
432 val chunk_font = chunk.style.getFont |
430 val chunk_font = chunk.style.getFont |
433 val chunk_color = chunk.style.getForegroundColor |
431 val chunk_color = chunk.style.getForegroundColor |
434 |
432 |
435 def string_width(s: String): Float = |
433 val chunk_text = new AttributedString(chunk_str) |
436 if (s.isEmpty) 0.0f |
434 |
437 else chunk_font.getStringBounds(s, font_context).getWidth.toFloat |
435 def chunk_attrib(attrib: TextAttribute, value: AnyRef, r: Text.Range): Unit = |
438 |
436 chunk_text.addAttribute(attrib, value, r.start - chunk_offset, r.stop - chunk_offset) |
439 val markup = |
437 |
440 for { |
438 |
441 r1 <- rendering.text_color(chunk_range, chunk_color) |
439 // font |
442 r2 <- r1.try_restrict(chunk_range) |
440 chunk_text.addAttribute(TextAttribute.FONT, chunk_font) |
443 } yield r2 |
441 chunk_text.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_LTR) |
444 |
442 |
445 val padded_markup_iterator = |
443 // color |
446 if (markup.isEmpty) |
444 chunk_text.addAttribute(TextAttribute.FOREGROUND, chunk_color) |
447 Iterator(Text.Info(chunk_range, chunk_color)) |
445 for { |
448 else |
446 Text.Info(r1, color) <- rendering.text_color(chunk_range, chunk_color).iterator |
449 Iterator( |
447 r2 <- r1.try_restrict(chunk_range) if !r2.is_singularity |
450 Text.Info(Text.Range(chunk_range.start, markup.head.range.start), chunk_color)) ++ |
448 } chunk_attrib(TextAttribute.FOREGROUND, color, r2) |
451 markup.iterator ++ |
449 |
452 Iterator(Text.Info(Text.Range(markup.last.range.stop, chunk_range.stop), chunk_color)) |
450 // caret |
453 |
451 for { r <- caret_range.try_restrict(chunk_range) if !r.is_singularity } { |
454 var x1 = x + w |
452 chunk_attrib(TextAttribute.FOREGROUND, caret_color(rendering, r.start), r) |
455 gfx.setFont(chunk_font) |
453 chunk_attrib(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON, r) |
456 for (Text.Info(range, color) <- padded_markup_iterator if !range.is_singularity) { |
454 } |
457 val str = chunk_str.substring(range.start - chunk_offset, range.stop - chunk_offset) |
455 |
458 gfx.setColor(color) |
456 gfx.drawString(chunk_text.getIterator, x + w, y) |
459 |
|
460 range.try_restrict(caret_range) match { |
|
461 case Some(r) if !r.is_singularity => |
|
462 val i = r.start - range.start |
|
463 val j = r.stop - range.start |
|
464 val s1 = str.substring(0, i) |
|
465 val s2 = str.substring(i, j) |
|
466 val s3 = str.substring(j) |
|
467 |
|
468 if (s1.nonEmpty) gfx.drawString(Word.bidi_override(s1), x1, y) |
|
469 |
|
470 val astr = new AttributedString(Word.bidi_override(s2)) |
|
471 astr.addAttribute(TextAttribute.FONT, chunk_font) |
|
472 astr.addAttribute(TextAttribute.FOREGROUND, caret_color(rendering, r.start)) |
|
473 astr.addAttribute(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON) |
|
474 gfx.drawString(astr.getIterator, x1 + string_width(s1), y) |
|
475 |
|
476 if (s3.nonEmpty) |
|
477 gfx.drawString(Word.bidi_override(s3), x1 + string_width(str.substring(0, j)), y) |
|
478 |
|
479 case _ => |
|
480 gfx.drawString(Word.bidi_override(str), x1, y) |
|
481 } |
|
482 x1 += string_width(str) |
|
483 } |
|
484 } |
457 } |
485 w += chunk.width |
458 w += chunk.width |
486 chunk = chunk.next.asInstanceOf[Chunk] |
459 chunk = chunk.next.asInstanceOf[Chunk] |
487 } |
460 } |
488 w |
461 w |