Пример #1
0
        public static string[] WrapWords(string source, int lineWidth, FontMetrics metrics)
        {
            int           pos              = 0;
            int           lastWrap         = 0;
            int           lastPossibleWrap = 0;
            int           curWidth         = 0;
            List <string> lines            = new List <string>();

            while (pos < source.Length)
            {
                char ch        = source[pos];
                int  charWidth = metrics.GetCharacterWidth(ch);

                if (ch == '\n')
                {
                    // wrap here
                    string line = source.Substring(lastWrap, pos - lastWrap);
                    lastWrap = lastPossibleWrap = pos;
                    curWidth = 0;

                    lines.Add(line.PadRight(line.Length + (lineWidth - StringWidth(line, metrics)) / metrics.HalfWidthHorizontalSpacing));
                }
                else if (curWidth + charWidth > lineWidth)
                {
                    if (lastPossibleWrap > lastWrap)
                    {
                        // check length of current word
                        int end = pos;
                        while (end < source.Length && !char.IsWhiteSpace(source[end]) && !IsFullWidthCharacter(source[end]))
                        {
                            end++;
                        }
                        string curWord = source.Substring(lastPossibleWrap, end - lastPossibleWrap).Trim();

                        if (StringWidth(curWord, metrics) > lineWidth)
                        {
                            // word wouldn't fit in its own line, so we keep its start on the current one and force a hard wrap (no padding)
                            lines.Add(source.Substring(lastWrap, pos - lastWrap));
                            lastWrap = lastPossibleWrap = pos;
                            curWidth = 0;
                        }
                        else
                        {
                            // push the current word to the next line
                            string line         = source.Substring(lastWrap, lastPossibleWrap - lastWrap);
                            int    curLineWidth = StringWidth(line, metrics);
                            lastWrap  = lastPossibleWrap;
                            curWidth -= curLineWidth;

                            // pad and add line
                            lines.Add(line.PadRight(line.Length + (lineWidth - curLineWidth) / metrics.HalfWidthHorizontalSpacing));
                        }
                    }
                    else
                    {
                        // force a hard wrap here (no padding)
                        lines.Add(source.Substring(lastWrap, pos - lastWrap));
                        lastWrap = lastPossibleWrap = pos;
                        curWidth = 0;
                    }
                }

                curWidth += charWidth;

                pos++;

                // allow soft wraps after each full-width character
                if (char.IsWhiteSpace(ch) || IsFullWidthCharacter(ch))
                {
                    lastPossibleWrap = pos;
                }
            }

            // add the last line
            if (pos > lastWrap)
            {
                string line = source.Substring(lastWrap, pos - lastWrap);
                if (line.Trim().Length > 0)
                {
                    lines.Add(line.PadRight(line.Length + (lineWidth - StringWidth(line, metrics)) / metrics.HalfWidthHorizontalSpacing));
                }
            }

            return(lines.ToArray());
        }
Пример #2
0
 public static int StringWidth(string str, FontMetrics metrics)
 {
     return(str.Aggregate(0, (int l, char ch) => l + metrics.GetCharacterWidth(ch)));
 }