示例#1
0
        private void PositionWordsHorizontally(float maxWidth, out float longestLineWidth)
        {
            fittedWords.Clear();
            fittedWords.AddRange(words);
            longestLineWidth = 0;
            float x = 0;
            // We're using breakStart to join multiple words into one with  
            int breakStart = 0;

            for (int i = 0; i < fittedWords.Count; i++)
            {
                var word = fittedWords[i].Clone();
                word.LineBreak = word.ForceLineBreak;
                if (word.LineBreak)
                {
                    x = 0;
                }
                if (i > 0 && !fittedWords[i - 1].IsNbsp && !word.IsNbsp)
                {
                    breakStart = i;
                }
                word.Width = CalcWordWidth(word);
                var t = texts[word.TextIndex];
                var isTextOrBullet = (t.Length > 0 && t[word.Start] > ' ') || IsBullet(word);
                if (x + word.Width > maxWidth && isTextOrBullet)
                {
                    if (wordSplitAllowed || t.HasJapaneseChineseSymbols(word.Start, word.Length))
                    {
                        var fittedCharsCount = CalcFittedCharactersCount(word, maxWidth - x);
                        if (fittedCharsCount > 0)
                        {
                            var wordEnd = word.Start + fittedCharsCount;
                            TextLineSplitter.AdjustLineBreakPosition(t, ref wordEnd, word.Start + word.Length - 1);
                            if (wordEnd > word.Start)
                            {
                                fittedCharsCount = wordEnd - word.Start;
                            }
                            var newWord = word.Clone();
                            newWord.IsTagBegin     = false;
                            newWord.Start          = word.Start + fittedCharsCount;
                            newWord.Length         = word.Length - fittedCharsCount;
                            newWord.Width          = CalcWordWidth(newWord);
                            newWord.ForceLineBreak = true;
                            word.Length            = fittedCharsCount;
                            word.Width             = CalcWordWidth(word);
                            word.X = x;
                            fittedWords.Insert(i + 1, newWord);
                            goto skip_default_placement;
                        }
                    }
                    // Splitting by words
                    var isWordContinue =
                        breakStart < i ||
                        word.TextIndex > 0 &&
                        word.Start == 0 &&
                        t.Length > 0 &&
                        t[word.Start] > ' ' &&
                        (GetLastChar(texts[fittedWords[i - 1].TextIndex]) > ' ' || IsBullet(fittedWords[i - 1]));
                    if (isWordContinue)
                    {
                        breakStart = Math.Min(breakStart, i - 1);
                        fittedWords[breakStart].LineBreak = true;
                        x = 0;
                        Word prev = null;
                        // It's required to save our cloned word
                        fittedWords[i] = word;
                        for (var j = breakStart; j <= i; j++)
                        {
                            prev   = fittedWords[j];
                            prev.X = x;
                            x     += prev.Width;
                        }
                        word = prev ?? word;
                    }
                    else
                    {
                        word.X         = 0;
                        word.LineBreak = true;
                        word.Width     = CalcWordWidth(word);
                        x = word.Width;
                    }
                }
                else
                {
                    word.X = x;
                    x     += word.Width;
                }

skip_default_placement:

                if (overflowMode == TextOverflowMode.Ellipsis)
                {
                    if (word.X == 0 && word.Width > maxWidth)
                    {
                        ClipWordWithEllipsis(word, maxWidth);
                    }
                }
                if (isTextOrBullet)                   // buz: при автопереносе на концах строк остаются пробелы, они не должны влиять на значение длины строки
                {
                    longestLineWidth = Math.Max(longestLineWidth, word.X + word.Width);
                }
                fittedWords[i] = word;
            }
        }
示例#2
0
Test_TextLineSplitter()
{
    Print( "Pull" );
    Assert(
        "\nline1\nline2\rline3\r\nline4\r\rline6\n\nline8\nline9"
            .AsStream()
            .To( new TextLineSplitter() )
            .SequenceEqual(
                Stream.Create(
                    "", "line1", "line2", "line3", "line4", "", "line6", "",
                    "line8", "line9" ) ) );
    Print( "Push" );
    var lines = new List< string >();
    var sink =
        new TextLineSplitter()
        .To( lines.AsSink() );
    "\nline1\nline2\rline3\r\nline4\r\rline6\n\nline8\nline9"
        .AsStream()
        .EmptyTo( sink );
    sink.Dispose();
    Assert(
        lines
            .AsStream()
            .SequenceEqual(
                Stream.Create(
                    "", "line1", "line2", "line3", "line4", "", "line6", "",
                    "line8", "line9" ) ) );
}