int DrawLinePortion(Context cr, ChunkStyle style, TextLayout layout, DocumentLine line, int visualOffset, int logicalLength)
        {
            int logicalColumn = line.GetLogicalColumn(editor, visualOffset);
            int logicalEndColumn = logicalColumn + logicalLength;
            int visualEndOffset = line.GetVisualColumn(editor, logicalEndColumn);

            int visualLength = visualEndOffset - visualOffset;

            int indexOffset = visualOffset - 1;

            layout.SetFontStyle(style.FontStyle, indexOffset, visualLength);
            layout.SetFontWeight(style.FontWeight, indexOffset, visualLength);
            if (style.Underline)
                layout.SetUnderline(indexOffset, visualLength);
            layout.SetForeground(style.Foreground, indexOffset, visualLength);

            return visualEndOffset;
        }
        protected void InsertCharacter(uint unicodeKey)
        {
            if (!textEditorData.CanEdit(Data.Caret.Line))
            {
                return;
            }

            HideMouseCursor();

            using (var undo = Document.OpenUndoGroup()) {
                if (textEditorData.IsSomethingSelected && textEditorData.Options.EnableSelectionWrappingKeys && IsSpecialKeyForSelection(unicodeKey))
                {
                    textEditorData.SelectionSurroundingProvider.HandleSpecialSelectionKey(textEditorData, unicodeKey);
                    return;
                }

                textEditorData.DeleteSelectedText(
                    textEditorData.IsSomethingSelected ? textEditorData.MainSelection.SelectionMode != SelectionMode.Block : true);
                // Needs to be called after delete text, delete text handles virtual caret postitions itself,
                // but afterwards the virtual position may need to be restored.
                textEditorData.EnsureCaretIsNotVirtual();

                char ch = (char)unicodeKey;
                if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line))
                {
                    DocumentLine line = Document.GetLine(Caret.Line);
                    if (Caret.IsInInsertMode || Caret.Column >= line.Length + 1)
                    {
                        string text = ch.ToString();
                        if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
                        {
                            var visualInsertLocation = textEditorData.LogicalToVisualLocation(Caret.Location);
                            var selection            = textEditorData.MainSelection;
                            Caret.PreserveSelection = true;
                            for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++)
                            {
                                DocumentLine lineSegment  = textEditorData.GetLine(lineNumber);
                                int          insertOffset = lineSegment.GetLogicalColumn(textEditorData, visualInsertLocation.Column) - 1;
                                string       textToInsert;
                                if (lineSegment.Length < insertOffset)
                                {
                                    int visualLastColumn = lineSegment.GetVisualColumn(textEditorData, lineSegment.Length + 1);
                                    int charsToInsert    = visualInsertLocation.Column - visualLastColumn;
                                    int spaceCount       = charsToInsert % editor.Options.TabSize;
                                    textToInsert = new string ('\t', (charsToInsert - spaceCount) / editor.Options.TabSize) +
                                                   new string (' ', spaceCount) + text;
                                    insertOffset = lineSegment.Length;
                                }
                                else
                                {
                                    textToInsert = text;
                                }
                                textEditorData.Insert(lineSegment.Offset + insertOffset, textToInsert);
                            }
                            var visualColumn = textEditorData.GetLine(Caret.Location.Line).GetVisualColumn(textEditorData, Caret.Column);

                            textEditorData.MainSelection = new Selection(
                                new DocumentLocation(selection.Anchor.Line, textEditorData.GetLine(selection.Anchor.Line).GetLogicalColumn(textEditorData, visualColumn)),
                                new DocumentLocation(selection.Lead.Line, textEditorData.GetLine(selection.Lead.Line).GetLogicalColumn(textEditorData, visualColumn)),
                                SelectionMode.Block
                                );
                            Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
                        }
                        else
                        {
                            textEditorData.Insert(Caret.Offset, text);
                        }
                    }
                    else
                    {
                        textEditorData.Replace(Caret.Offset, 1, ch.ToString());
                    }
                    // That causes unnecessary redraws:
                    //				bool autoScroll = Caret.AutoScrollToCaret;
//					Caret.Column++;
                    if (Caret.PreserveSelection)
                    {
                        Caret.PreserveSelection = false;
                    }
                    //				Caret.AutoScrollToCaret = autoScroll;
                    //				if (autoScroll)
                    //					Editor.ScrollToCaret ();
                    //				Document.RequestUpdate (new LineUpdate (Caret.Line));
                    //				Document.CommitDocumentUpdate ();
                }
            }
            Document.OptimizeTypedUndo();
        }
        public double ColumnToX(DocumentLine line, int column)
        {
            int visualColumn = line.GetVisualColumn(editor, column);

            return (visualColumn - 1) * CharWidth;
        }
        protected internal override void DrawBackground(Context cr, Xwt.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double height)
        {
            if (line == null) return;

            if (lineNumber == editor.Caret.Line)
            {
                cr.SetColor(editor.Options.ColorScheme.LineMarker.Color);
                cr.Rectangle(x, y, editor.GetWidth(), height);
                cr.Fill();
            }

            var style = SyntaxModeService.DefaultColorStyle;
            var selectionStyle = editor.HasFocus ? style.SelectedText : style.SelectedInactiveText;

            var selectionSegment = GetSegmentForLine(editor.Selection, line);
            if (selectionSegment != null)
            {
                int logicalStartColumn = selectionSegment.Value.Offset - line.Offset;
                int visualStartColumn = line.GetVisualColumn(editor, logicalStartColumn);

                if (selectionSegment.Value.Offset == line.Offset)
                    visualStartColumn = 0;

                int logicalEndColumn = selectionSegment.Value.EndOffset - line.Offset;
                int visualEndColumn = line.GetVisualColumn(editor, logicalEndColumn);

                if (editor.Selection.EndOffset != selectionSegment.Value.EndOffset && visualEndColumn > 0)
                    visualEndColumn--;

                if (editor.Selection.Contains(line.EndOffset))
                    ++visualEndColumn;

                cr.SetColor(selectionStyle.Background);
                double startX = x + visualStartColumn * CharWidth;
                double endX = x + visualEndColumn * CharWidth;
                cr.Rectangle(startX, y, endX - startX, LineHeight);
                cr.Fill();
            }
        }