static Rect GetCharacterBounds(this TextView textView, TextViewPosition pos, HwndSource source)
        {
            VisualLine vl = textView.GetVisualLine(pos.Line);

            if (vl == null)
            {
                return(EMPTY_RECT);
            }
            // this may happen during layout changes in AvalonDock, so we just return an empty rectangle
            // in those cases. It should be refreshed immediately.
            if (source.RootVisual == null || !source.RootVisual.IsAncestorOf(textView))
            {
                return(EMPTY_RECT);
            }
            TextLine line = vl.GetTextLine(pos.VisualColumn);
            Rect     displayRect;

            // calculate the display rect for the current character
            if (pos.VisualColumn < vl.VisualLengthWithEndOfLineMarker)
            {
                displayRect = line.GetTextBounds(pos.VisualColumn, 1).First().Rectangle;
                displayRect.Offset(0, vl.GetTextLineVisualYPosition(line, VisualYPosition.LineTop));
            }
            else
            {
                // if we are in virtual space, we just use one wide-space as character width
                displayRect = new Rect(vl.GetVisualPosition(pos.VisualColumn, VisualYPosition.TextTop),
                                       new Size(textView.WideSpaceWidth, textView.DefaultLineHeight));
            }
            // adjust to current scrolling
            displayRect.Offset(-textView.ScrollOffset);
            return(textView
                   .TransformToAncestor(source.RootVisual).TransformBounds(displayRect) // rect on root visual
                   .TransformToDevice(source.RootVisual));                              // rect on HWND
        }