private void CalcSize()

in src/AccessibilityInsights.SharedUx/Highlighting/TextTip.cs [229:354]


        private void CalcSize()
        {
            if (this.Text == null)
            {
                size.x = 0;
                size.y = 0;
                return;
            }

            // Have to parse the text into lines, and
            // work out width, height of each line.
            // Eventually, use the max width, and cumulative height.
            // Since Tabs stops aren't handled if we're using CALCRECT, we have
            // to roll our own... (ick)
            IntPtr hDC = NativeMethods.GetDC(IntPtr.Zero);
            IntPtr hFont = NativeMethods.SelectObject(hDC, this.hFont);

            int TotalHeight = 0;
            int MaxWidth1 = 0; // before the tab...
            int MaxWidth2 = 0; // after the tab...

            int idxCur = 0;
            while (idxCur < this.Text.Length)
            {
                // Find the end of the line...
                int idxEnd = idxCur;
                var ch = this.Text[idxEnd];

                while (ch != '\r' && ch != '\n' && ch != '\t')
                {
                    idxEnd++;
                    if (idxEnd < this.Text.Length)
                    {
                        ch = this.Text[idxEnd];
                    }
                    else
                    {
                        break;
                    }
                }

                // (int) cast for 64-bit compat. (We don't need 64-bit ptr diff here...)
                int Len = (int)(idxEnd - idxCur);

                // Now pass the line to DrawText to get the height/length...
                RECT rc = new RECT() { left = 0, top = 0, right = 2, bottom = 32768 };

                int Height = NativeMethods.DrawText(hDC, this.Text.Substring(idxCur, Len), Len, ref rc,
                        Win32Constants.DT_CALCRECT | Win32Constants.DT_LEFT | Win32Constants.DT_SINGLELINE | Win32Constants.DT_NOPREFIX);
                if (rc.right > MaxWidth1)
                    MaxWidth1 = rc.right;

                if (ch == '\t')
                {
                    // work out second part of the tab-stop'd line...
                    idxEnd++;
                    idxCur = idxEnd;

                    while (ch != '\r' && ch != '\n')
                    {
                        idxEnd++;
                        if (idxEnd < this.Text.Length)
                        {
                            ch = this.Text[idxEnd];
                        }
                        else
                        {
                            break;
                        }
                    }

                    Len = (int)(idxEnd - idxCur);

                    // Limit the rect to 1/4 of screen, and use DT_END_ELLIPSIS...
                    rc = new RECT() { left = 0, top = 0, right = 2, bottom = 32767 };
                    rc.right = NativeMethods.GetSystemMetrics(SystemMetric.SM_CXSCREEN) / 4;

                    int Height2 = NativeMethods.DrawText(hDC, this.Text.Substring(idxCur, Len), Len, ref rc,
                        Win32Constants.DT_CALCRECT | Win32Constants.DT_LEFT | Win32Constants.DT_SINGLELINE | Win32Constants.DT_NOPREFIX | Win32Constants.DT_END_ELLIPSIS);
                    if (MaxWidth2 < rc.right)
                        MaxWidth2 = rc.right;
                    if (Height < Height2)
                        Height = Height2;
                }

                TotalHeight += Height;

                // Skip over the \r (or \n) - and allow for a trailing \n (or \r) if on exists.
                if (ch == '\r')
                {
                    idxEnd++;
                    ch = this.Text[idxEnd];
                    if (ch == '\n')
                    {
                        idxEnd++;
                    }
                }
                else if (ch == '\n')
                {
                    idxEnd++;
                    ch = this.Text[idxEnd];
                    if (ch == '\r')
                    {
                        idxEnd++;
                    }
                }

                // Use this as the new starting pos...
                idxCur = idxEnd;
            }

            size.x = MaxWidth1 + TEXTBORDER * 2 + 2;
            if (MaxWidth2 != 0)
            {
                size.x += TEXTTABMIN + MaxWidth2;
                m_TabStop = MaxWidth1;
            }
            else
            {
                m_TabStop = 0;
            }
            size.y = TotalHeight + TEXTBORDER * 2 + 2;

            NativeMethods.SelectObject(hDC, hFont);
            NativeMethods.ReleaseDC(IntPtr.Zero, hDC);
        }