private void DrawItem()

in src/XmlNotepad/NodeTextView.cs [661:815]


        private void DrawItem(Rectangle bounds, TreeNode tn, Graphics g)
        {

            //g.SmoothingMode = SmoothingMode.AntiAlias;
            Color c = tn.ForeColor;

            Brush myBrush = null;
            bool focusSelected = false;
            if (this.Focused && tn == this.SelectedNode)
            {
                focusSelected = true;
                g.FillRectangle(SystemBrushes.Highlight, bounds);
                myBrush = Brushes.HighlightTextBrush(c);
            }
            else
            {
                myBrush = new SolidBrush(c);
            }

            Font font = this.Font;
            Rectangle inset = new Rectangle(bounds.Left + 3, bounds.Top, bounds.Width - 3, bounds.Height);

            string value = null;
            if (this._visibleTextCache.ContainsKey(tn))
            {
                value = this._visibleTextCache[tn];
            }
            else
            {
                value = GetNodeText(tn);
            }
            if (value == null && !focusSelected)
            {
                using (Brush b = new SolidBrush(_containerBackground))
                {
                    g.FillRectangle(b, bounds);
                }
            }

            if (value != null && value.Length > 0)
            {

                //inset.Inflate(-3, -2);

                char ellipsis = Convert.ToChar(0x2026);

                value = value.Trim();

                int i = value.IndexOfAny(new char[] { '\r', '\n' });
                if (i > 0)
                {
                    value = value.Substring(0, i) + ellipsis;
                }

                // Figure out how much of the text we can display                
                int width = inset.Width; ;
                //int height = inset.Height;
                string s = value;
                if (width < 0) return;
                int length = value.Length;
                SizeF size = SizeF.Empty;
                bool measurable = false;
                while (!measurable)
                {
                    try
                    {
                        if (s.Length >= 65536)
                        {
                            // MeasureString tops out at 64kb strings.
                            s = s.Substring(0, 65535);
                        }
                        size = g.MeasureString(s, font, width + 1000, StringFormat.GenericTypographic);
                        measurable = true;
                    }
                    catch (Exception)
                    {
                        // perhaps the string is just too long!
                        s = s.Substring(0, s.Length / 2);
                    }
                }
                int j = s.Length;
                int dy = (font.Height - (int)Math.Ceiling(size.Height)) / 2;
                if (dy < 0) dy = 0;
                char[] ws = new char[] { ' ', '\t' };
                if ((int)size.Width > width && j > 1)
                { // line wrap?
                    int start = 0;
                    int w = 0;
                    int k = value.IndexOfAny(ws);
                    while (k > 0)
                    {
                        s = value.Substring(0, k) + ellipsis;
                        size = g.MeasureString(s, font, width + 1000, StringFormat.GenericTypographic);
                        if ((int)size.Width < width && k < length)
                        {
                            start = k;
                            w = (int)size.Width;
                            while (start < length && (value[start] == ' ' || value[start] == '\t'))
                            {
                                start++;
                            }
                            k = value.IndexOfAny(ws, start);
                        }
                        else
                        {
                            break;
                        }
                    }
                    j = start;
                    if (w < width / 2)
                    {
                        // if we have a really long word (e.g. binhex) then just take characters
                        // up to the end of the line.                        
                        while ((int)w < width && j < length)
                        {
                            j++;
                            s = value.Substring(0, j) + ellipsis;
                            size = g.MeasureString(s, font, width + 1000, StringFormat.GenericTypographic);
                            w = (int)size.Width;
                        }
                    }
                    if (j <= 0)
                    {
                        s = "";
                    }
                    else if (j < length)
                    {
                        s = value.Substring(0, j - 1) + ellipsis;
                    }

                    this._visibleTextCache[tn] = s;
                }


                // Draw the current item text based on the current Font and the custom brush settings.
                g.DrawString(s, font, myBrush, inset.Left, dy + inset.Top, StringFormat.GenericTypographic);
            }

            // If the ListBox has focus, draw a focus rectangle around the selected item.
            if (tn == this.SelectedNode)
            {
                g.SmoothingMode = SmoothingMode.Default;
                Pen p = new Pen(Color.Black, 1);
                p.DashStyle = DashStyle.Dot;
                p.Alignment = PenAlignment.Inset;
                p.LineJoin = LineJoin.Round;
                bounds.Width--;
                bounds.Height--;
                g.DrawRectangle(p, bounds);
                p.Dispose();
            }

            myBrush.Dispose();

        }