Beispiel #1
0
        private FormattedLine consumeComponents(List <string> components, int startIndex, double desiredWidth, double fontSize)
        {
            FormattedLine bestResult = null;
            int           lowCount   = 1;
            int           highCount  = components.Count() - startIndex;

            while (highCount >= lowCount)
            {
                int testCount = Math.Min(lowCount * 2, (lowCount + highCount) / 2);

                string testText     = String.Join("", components.GetRange(startIndex, testCount));
                Size   requiredSize = this.getLineSize(testText, fontSize);
                if (requiredSize.Width <= desiredWidth)
                {
                    // we found some characters that all fit into one line
                    bestResult = new FormattedLine(testCount, testText, requiredSize);
                    lowCount   = testCount + 1;
                }
                else
                {
                    // we tried to use too many characters at once, and they didn't all fit
                    if (bestResult == null)
                    {
                        // We can only get here on the first iteration, when measuring only the first word
                        // If not even the first word fit, then we return it anyway, so the caller knows how much space it needs
                        bestResult = new FormattedLine(testCount, testText, requiredSize);
                    }
                    highCount = testCount - 1;
                }
            }
            return(bestResult);
        }
Beispiel #2
0
        public FormattedParagraph FormatParagraph(String text, double desiredWidth, bool allowSplittingWords, double fontSize)
        {
            if (text == null || text == "")
            {
                return(new FormattedParagraph(new Size(), text));
            }

            // total size of the paragraph
            Size totalSize = new Size();

            // the unsplittable units that we're going to measure
            List <string> components;
            int           i;

            if (allowSplittingWords)
            {
                components = new List <string>();
                for (i = 0; i < text.Length; i++)
                {
                    components.Add(text.Substring(i, 1));
                }
            }
            else
            {
                string[] words = text.Split(' ');
                components = new List <string>();
                for (i = 0; i < words.Length; i++)
                {
                    if (i != 0)
                    {
                        components.Add(" ");
                    }
                    components.Add(words[i]);
                }
            }
            List <string> formattedLines = new List <string>();

            i = 0;
            while (i < components.Count())
            {
                // consume as many words as will fit on this line
                FormattedLine line = consumeComponents(components, i, desiredWidth, fontSize);
                // add new text
                formattedLines.Add(line.Text);
                // update size
                totalSize.Width   = Math.Max(totalSize.Width, line.Size.Width);
                totalSize.Height += line.Size.Height;
                // continue to subsequent components
                i += line.NumComponents;
                // If a space character wrapped to the next line, we can skip it instead
                if (i < components.Count)
                {
                    if (components[i] == " ")
                    {
                        i++;
                    }
                }
            }
            return(new FormattedParagraph(totalSize, String.Join("\n", formattedLines)));
        }