src/Tools/jEdit/src/rich_text_area.scala
changeset 73875 6e43936f2111
parent 73367 77ef8bef0593
child 73876 e6c9c1c3f580
equal deleted inserted replaced
73874:7730b882f14a 73875:6e43936f2111
   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