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)); }
protected override void OnMouseMove(MouseEventArgs e) { if (Capture && !dragging) { // We're extending the selection var pos = ClientToLogicalPosition(e.Location); if (layout.ComparePositions(cursorPos, pos) != 0) { this.cursorPos = pos; Invalidate(); } } else { // Not captured, so rat is just floating over us. // Show the right cursor. var span = GetSpan(e.Location); if (span != null) { GetStyleStack().PushStyle(StyleClass); styleStack.PushStyle(span.Style); this.Cursor = styleStack.GetCursor(this); styleStack.PopStyle(); styleStack.PopStyle(); } else { this.Cursor = Cursors.Default; } if (span != spanHover) { if (spanHover != null) { SpanLeave.Fire(this, new SpanEventArgs(spanHover)); } spanHover = span; if (span != null) { SpanEnter.Fire(this, new SpanEventArgs(span)); } } } base.OnMouseMove(e); }
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); } }
public SpanEventArgs(LayoutSpan span) { this.Span = span; }
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(); } }