Ejemplo n.º 1
0
        public Paragraph(int index, float maxWidth)
        {
            Index      = index;
            Top        = index;
            BreakWidth = maxWidth;

            m_Glyphs = new GlyphList();
            m_Breaks = new BreakList();
        }
Ejemplo n.º 2
0
        public void WordWrap(float breakWidth)
        {
            // ToDo: Still not perfect:
            // * Lines with ending NewLine may hang over
            // (the non-printable NewLine character is right above breakwidth)
            // * Lines without any break-chars may hang one character over breakwidth

            lock (SyncObject) {
                if (!NeedsWordWrap && BreakWidth == breakWidth)
                {
                    return;
                }

                BreakWidth    = breakWidth;
                NeedsWordWrap = false;

                // Since here, we completely work with temporary local variables
                // and set final values once finished.

                GlyphList.Node curr       = Glyphs.Head;
                GlyphList.Node prev       = curr;
                BreakList      lineBreaks = new BreakList();

                float currentWidth = 0;
                float totalWidth   = 0;
                float maxWidth     = 0;

                int pos = 0;
                int prevBreakCharPos = 0;

                while (curr != null)
                {
                    currentWidth += curr.Value.Width;
                    totalWidth   += currentWidth;

                    if (currentWidth > BreakWidth && curr.Next != null)
                    {
                        if (prevBreakCharPos == 0)
                        {
                            lineBreaks.AddLast(pos);
                            currentWidth = curr.Value.Width;
                            prev         = curr;
                        }
                        else
                        {
                            lineBreaks.AddLast(prevBreakCharPos);
                            prevBreakCharPos = 0;
                            currentWidth     = 0;
                            while (prev != curr)
                            {
                                currentWidth += prev.Value.Width;
                                prev          = prev.Next;
                            }
                        }
                    }
                    else if (IsSpaceWrapCharacter(curr.Value.Char) || (IsWrapCharacter(curr.Value.Char) && curr.Next != null && !IsSpaceWrapCharacter(curr.Next.Value.Char)))
                    {
                        prevBreakCharPos = pos + 1;
                        prev             = curr;
                    }

                    maxWidth = Math.Max(maxWidth, currentWidth);
                    curr     = curr.Next;
                    pos++;
                }

                // Update final values
                Concurrency.LockFreeUpdate(ref m_Breaks, lineBreaks);
                Width           = maxWidth.Ceil();
                TotalGlyphWidth = totalWidth;
            }
        }