コード例 #1
0
        public void DrawText(string text, float x, float y, TextPresenter textPresenter, bool multiline)
        {
            bool renderCaret    = textPresenter.ShowCaret && textPresenter.RenderCaret;
            int  selectionStart = Math.Min(textPresenter.SelectionStart, textPresenter.SelectionEnd);
            int  selectionEnd   = Math.Max(textPresenter.SelectionStart, textPresenter.SelectionEnd);

            var textToRender = multiline ? text : text.Replace("\n", string.Empty);

            var lines = textToRender.Split("\n", StringSplitOptions.RemoveEmptyEntries);

            var caretPosition          = textPresenter.GetRealPosition(textToRender, textPresenter.CaretPosition, textPresenter.Foreground);
            var selectionStartPosition = textPresenter.GetRealPosition(textToRender, selectionStart, textPresenter.Foreground);
            var selectionEndPosition   = textPresenter.GetRealPosition(textToRender, selectionEnd, textPresenter.Foreground);

            SKPaint caretPaint = new SKPaint
            {
                Color       = textPresenter.SelectionEnd != textPresenter.SelectionEnd ? Color.Win10GreyDark : Color.Black,
                StrokeWidth = 1
            };

            if (renderCaret)
            {
                Canvas.DrawLine(new SKPoint((caretPosition.XOffset + x) * Scale, (y + 2) * Scale),
                                new SKPoint((caretPosition.XOffset + x) * Scale, (y - textPresenter.Foreground.TextSize - 2) * Scale),
                                ScalePaint(caretPaint));
            }

            SKPaint currentForegroundPaint = textPresenter.Foreground;
            SKPaint currentBackgroundPaint = textPresenter.Background;

            string preSelection  = string.Empty;
            string selection     = string.Empty;
            string postSelection = string.Empty;

            bool inSelection = false;

            for (int i = 0; i < lines.Length; i++)
            {
                var line = lines[i];

                if (selectionStartPosition.Line == i)
                {
                    int selectionLimit = selectionEndPosition.Line == i ? selectionEndPosition.Column : line.Length;

                    selection    = line.Substring(selectionStartPosition.Column, selectionLimit - selectionStartPosition.Column);
                    preSelection = line.Substring(0, selectionStartPosition.Column);

                    if (preSelection.Length > 0)
                    {
                        Canvas.DrawText(preSelection, x * Scale, (y + selectionStartPosition.YOffset) * Scale, ScalePaint(currentForegroundPaint));
                    }

                    currentForegroundPaint = textPresenter.SelectionForeground;
                    currentBackgroundPaint = textPresenter.SelectionBackground;

                    if (selection.Length > 0)
                    {
                        float selectionWidth = currentForegroundPaint.MeasureText(selection);

                        Canvas.DrawRect((x + selectionStartPosition.XOffset) * Scale, (y + selectionStartPosition.YOffset) * Scale,
                                        selectionWidth * Scale, -currentForegroundPaint.TextSize * Scale, ScalePaint(currentBackgroundPaint));

                        Canvas.DrawText(selection, (x + selectionStartPosition.XOffset) * Scale,
                                        (y + selectionStartPosition.YOffset) * Scale, currentForegroundPaint);
                    }

                    inSelection = true;
                }
                if (selectionEndPosition.Line == i)
                {
                    int selectionLimit = selectionStartPosition.Line == i ? selectionStartPosition.Column : 0;

                    selection     = line.Substring(selectionLimit, selectionEndPosition.Column - selectionLimit);
                    postSelection = line.Substring(selectionEndPosition.Column, line.Length - selectionEndPosition.Column);

                    if (selection.Length > 0 && selectionStartPosition.Line != i)
                    {
                        float selectionWidth = currentForegroundPaint.MeasureText(selection);

                        Canvas.DrawRect((x + selectionEndPosition.XOffset - selectionWidth) * Scale, (y + selectionEndPosition.YOffset) * Scale,
                                        selectionWidth * Scale, -currentForegroundPaint.TextSize * Scale, ScalePaint(currentBackgroundPaint));

                        Canvas.DrawText(selection, (x + selectionEndPosition.XOffset - selectionWidth) * Scale,
                                        (y + selectionEndPosition.YOffset) * Scale, ScalePaint(currentForegroundPaint));
                    }

                    currentForegroundPaint = textPresenter.Foreground;
                    currentBackgroundPaint = textPresenter.Background;

                    if (postSelection.Length > 0)
                    {
                        Canvas.DrawText(postSelection, (x + selectionEndPosition.XOffset) * Scale,
                                        (y + selectionEndPosition.YOffset) * Scale, ScalePaint(currentForegroundPaint));
                    }

                    inSelection = false;
                }
                else
                {
                    if (selectionStartPosition.Line != i && selectionEndPosition.Line != i)
                    {
                        float yOffset    = i * currentForegroundPaint.TextSize;
                        float lineLength = currentForegroundPaint.MeasureText(line);

                        if (inSelection)
                        {
                            Canvas.DrawRect(x * Scale, (y + yOffset) * Scale, lineLength * Scale, -currentForegroundPaint.TextSize * Scale,
                                            ScalePaint(currentBackgroundPaint));
                        }

                        Canvas.DrawText(line, x * Scale, (y + yOffset) * Scale, ScalePaint(currentForegroundPaint));
                    }
                }
            }
        }