private float MeasureLineHeight(LineSpan line) { float height = 0.0F; foreach (var span in line.TextSpans) { styleStack.PushStyle(span.Style); var font = styleStack.GetFont(defaultFont); height = Math.Max( height, font.Height + styleStack.GetNumber(s => s.PaddingTop) + styleStack.GetNumber(s => s.PaddingBottom)); styleStack.PopStyle(); } return(height); }
private RectangleF CharPositionToClient(Graphics g, TextPointer pos, LayoutSpan span, StyleStack styleStack) { var iChar = pos.Character; styleStack.PushStyle(span.Style); var font = styleStack.GetFont(defaultFont); var textStub = span.Text.Substring(0, iChar); var sz = MeasureText(g, textStub, font); var x = sz.Width + span.ContentExtent.Left; var width = 1; styleStack.PopStyle(); return(new RectangleF(x, span.ContentExtent.Top, width, span.ContentExtent.Height)); }
private int GetCharPosition(Graphics g, Point ptClient, LayoutSpan span, StyleStack styleStack) { var x = ptClient.X - span.ContentExtent.Left; var textStub = span.Text; int iLow = 0; int iHigh = textStub.Length; styleStack.PushStyle(span.Style); var font = styleStack.GetFont(defaultFont); var sz = MeasureText(g, textStub, font); float xLow = 0; float xHigh = sz.Width; while (iLow < iHigh - 1) { int iMid = iLow + (iHigh - iLow) / 2; textStub = span.Text.Substring(0, iMid); sz = MeasureText(g, textStub, font); if (x < sz.Width) { iHigh = iMid; xHigh = sz.Width; } else { iLow = iMid; xLow = sz.Width; } } styleStack.PopStyle(); var cx = xHigh - xLow; if (x - xLow > cx) { return(iHigh); } else { return(iLow); } }
private void PaintLine(LayoutLine line) { this.line = line; // Paint the last piece of the line RectangleF rcTrailer = line.Extent; float xMax = 0; if (line.Spans.Length > 0) { xMax = line.Spans[line.Spans.Length - 1].ContentExtent.Right; } var cx = extent.Width - xMax; if (cx > 0) { rcTrailer.X = xMax; rcTrailer.Width = cx; graphics.FillRectangle( styleStack.GetBackground(defaultBgColor), rcTrailer); } for (int iSpan = 0; iSpan < line.Spans.Length; ++iSpan) { this.span = line.Spans[iSpan]; this.styleStack.PushStyle(span.Style); var pos = new TextPointer(line.Position, iSpan, 0); var insideSelection = outer.ComparePositions(selStart, pos) <= 0 && outer.ComparePositions(pos, selEnd) < 0; this.fg = styleStack.GetForegroundColor(defaultFgColor); this.bg = styleStack.GetBackground(defaultBgColor); this.font = styleStack.GetFont(defaultFont); this.rcContent = span.ContentExtent; this.rcTotal = span.PaddedExtent; if (!insideSelection) { if (selStart.Line == line.Position && selStart.Span == iSpan) { // Selection starts inside the current span. Write // any unselected text first. if (selStart.Character > 0) { DrawTextSegment(0, selStart.Character, false); } if (selEnd.Line == line.Position && selEnd.Span == iSpan) { // Selection ends inside the current span. Write // selected text. DrawTextSegment(selStart.Character, selEnd.Character - selStart.Character, true); DrawTrailingTextSegment(selEnd.Character, false); } else { // Select all the way to the end of the span. DrawTrailingTextSegment(selStart.Character, true); } } else { // Not in selection at all. DrawText(span.Text, false); } } else { // Inside selection. Does it end? if (selEnd.Line == line.Position && selEnd.Span == iSpan) { // Selection ends inside the current span. Write // selected text. DrawTextSegment(0, selEnd.Character, true); DrawTrailingTextSegment(selEnd.Character, false); } else { DrawText(span.Text, true); } } #if DEBUG var text = span.Text; if (line.Position == selStart.Line && iSpan == selStart.Span) { var textFrag = text.Substring(0, selStart.Character); var sz = outer.MeasureText(graphics, textFrag, font); graphics.FillRectangle( Brushes.Red, span.ContentExtent.Left + sz.Width, line.Extent.Top, 1, line.Extent.Height); } if (line.Position == selEnd.Line && iSpan == selEnd.Span) { var textFrag = text.Substring(0, selEnd.Character); var sz = outer.MeasureText(graphics, textFrag, font); graphics.FillRectangle( Brushes.Blue, span.ContentExtent.Left + sz.Width, line.Extent.Top, 1, line.Extent.Height); } #endif styleStack.PopStyle(); } }