/// <summary>
        ///     Splits the text on words using rules of the specified box
        /// </summary>
        /// <returns></returns>
        public void SplitWords()
        {
            if (string.IsNullOrEmpty(Text)) return;

            _curword = new BoxWord(Box);

            var onspace = IsSpace(Text[0]);

            for (var i = 0; i < Text.Length; i++)
            {
                if (IsSpace(Text[i]))
                {
                    if (!onspace) CutWord();

                    if (IsLineBreak(Text[i]))
                    {
                        _curword.AppendChar('\n');
                        CutWord();
                    }
                    else if (IsTab(Text[i]))
                    {
                        _curword.AppendChar('\t');
                        CutWord();
                    }
                    else
                    {
                        _curword.AppendChar(' ');
                    }

                    onspace = true;
                }
                else
                {
                    if (onspace) CutWord();
                    _curword.AppendChar(Text[i]);

                    onspace = false;
                }
            }

            CutWord();
        }
Example #2
0
 /// <summary>
 ///     Gets the longest word (in width) inside the box, deeply.
 /// </summary>
 /// <param name="b"></param>
 /// <param name="maxw"></param>
 /// <param name="word"></param>
 /// <returns></returns>
 private void GetMinimumWidth_LongestWord(Box b, ref float maxw, ref BoxWord word)
 {
     if (b.Words.Count > 0)
     {
         foreach (var w in b.Words)
         {
             if (!(w.FullWidth > maxw)) continue;
             maxw = w.FullWidth;
             word = w;
         }
     }
     else
     {
         foreach (var bb in b.Boxes)
             GetMinimumWidth_LongestWord(bb, ref maxw, ref word);
     }
 }
Example #3
0
        /// <summary>
        ///     Assigns words its width and height
        /// </summary>
        /// <param name="g"></param>
        internal void MeasureWordsSize(Graphics g)
        {
            if (_wordsSizeMeasured) return;

            //Measure white space if not yet done
            if (float.IsNaN(_actualWordSpacing))
                MeasureWordSpacing(g);

            if (HtmlTag != null && HtmlTag.TagName.Equals("img", StringComparison.CurrentCultureIgnoreCase))
            {
                #region Measure image

                var word = new BoxWord(this, Value.GetImage(GetAttribute("src")));
                Words.Clear();
                Words.Add(word);

                #endregion
            }
            else
            {
                #region Measure text words

                var lastWasSpace = false;

                foreach (var b in Words)
                {
                    var collapse = BoxWordSplitter.CollapsesWhiteSpaces(this);
                    if (BoxWordSplitter.EliminatesLineBreaks(this)) b.ReplaceLineBreaksAndTabs();

                    if (b.IsSpaces)
                    {
                        b.Height = FontLineSpacing;

                        if (b.IsTab)
                        {
                            b.Width = ActualWordSpacing*4; //TODO: Configure tab size
                        }
                        else if (b.IsLineBreak)
                        {
                            b.Width = 0;
                        }
                        else
                        {
                            if (!(lastWasSpace && collapse))
                            {
                                b.Width = ActualWordSpacing*(collapse ? 1 : b.Text.Length);
                            }
                        }

                        lastWasSpace = true;
                    }
                    else
                    {
                        var word = b.Text;

                        CharacterRange[] measurable = {new CharacterRange(0, word.Length)};
                        var sf = new StringFormat();

                        sf.SetMeasurableCharacterRanges(measurable);

                        var regions = g.MeasureCharacterRanges(word, ActualFont,
                            new RectangleF(0, 0, float.MaxValue, float.MaxValue),
                            sf);

                        var s = regions[0].GetBounds(g).Size;
                        var p = regions[0].GetBounds(g).Location;

                        b.LastMeasureOffset = new PointF(p.X, p.Y);
                        b.Width = s.Width; // +p.X;
                        b.Height = s.Height; // +p.Y;

                        lastWasSpace = false;
                    }
                }

                #endregion
            }

            _wordsSizeMeasured = true;
        }
Example #4
0
        /// <summary>
        ///     Recursively flows the content of the box using the inline model
        /// </summary>
        /// <param name="g">Device Info</param>
        /// <param name="blockbox">Blockbox that contains the text flow</param>
        /// <param name="box">Current box to flow its content</param>
        /// <param name="maxright">Maximum reached right</param>
        /// <param name="linespacing">Space to use between rows of text</param>
        /// <param name="startx">x starting coordinate for when breaking lines of text</param>
        /// <param name="line">Current linebox being used</param>
        /// <param name="curx">Current x coordinate that will be the left of the next word</param>
        /// <param name="cury">Current y coordinate that will be the top of the next word</param>
        /// <param name="maxbottom">Maximum bottom reached so far</param>
        private static void FlowBox(Graphics g, Box blockbox, Box box, float maxright, float linespacing,
            float startx, ref LineBox line, ref float curx, ref float cury, ref float maxbottom)
        {
            box.FirstHostingLineBox = line;

            foreach (var b in box.Boxes)
            {
                var leftspacing = b.ActualMarginLeft + b.ActualBorderLeftWidth + b.ActualPaddingLeft;
                var rightspacing = b.ActualMarginRight + b.ActualBorderRightWidth + b.ActualPaddingRight;
                var topspacing = b.ActualBorderTopWidth + b.ActualPaddingTop;
                var bottomspacing = b.ActualBorderBottomWidth + b.ActualPaddingTop;

                b.RectanglesReset();
                b.MeasureWordsSize(g);

                curx += leftspacing;

                if (b.Words.Count > 0)
                {
                    #region Flow words

                    foreach (var word in b.Words)
                    {
                        //curx += word.SpacesBeforeWidth;

                        if ((b.WhiteSpace != Constants.Nowrap && curx + word.Width + rightspacing > maxright) ||
                            word.IsLineBreak)
                        {
                            #region Break line

                            curx = startx;
                            cury = maxbottom + linespacing;

                            line = new LineBox(blockbox);

                            if (word.IsImage || word.Equals(b.FirstWord))
                            {
                                curx += leftspacing;
                            }

                            #endregion
                        }

                        line.ReportExistanceOf(word);

                        word.Left = curx; // -word.LastMeasureOffset.X + 1;
                        word.Top = cury; // - word.LastMeasureOffset.Y;

                        curx = word.Right; // +word.SpacesAfterWidth;
                        maxbottom = Math.Max(maxbottom, word.Bottom);
                        //+ (word.IsImage ? topspacing + bottomspacing : 0));

                        _lastTreatedWord = word;
                    }

                    #endregion
                }
                else
                {
                    FlowBox(g, blockbox, b, maxright, linespacing, startx, ref line, ref curx, ref cury, ref maxbottom);
                }

                curx += rightspacing;
            }

            box.LastHostingLineBox = line;
        }
Example #5
0
        /// <summary>
        ///     Lets the linebox add the word an its box to their lists if necessary.
        /// </summary>
        /// <param name="word"></param>
        internal void ReportExistanceOf(BoxWord word)
        {
            if (!Words.Contains(word))
            {
                Words.Add(word);
            }

            if (!RelatedBoxes.Contains(word.OwnerBox))
            {
                RelatedBoxes.Add(word.OwnerBox);
            }
        }
 private BoxWordSplitter()
 {
     Words = new List<BoxWord>();
     _curword = null;
 }
 private void CutWord()
 {
     if (_curword.Text.Length > 0)
         Words.Add(_curword);
     _curword = new BoxWord(Box);
 }