예제 #1
0
        /// <summary>
        /// Correct DOM tree if there is block boxes that are inside inline blocks.<br/>
        /// Need to rearrange the tree so block box will be only the child of other block box.
        /// </summary>
        /// <param name="box">the current box to correct its sub-tree</param>
        private static void CorrectBlockInsideInline(CssBox box)
        {
            try
            {
                if (DomUtils.ContainsInlinesOnly(box) && !ContainsInlinesOnlyDeep(box))
                {
                    var tempRightBox = CorrectBlockInsideInlineImp(box);
                    while (tempRightBox != null)
                    {
                        // loop on the created temp right box for the fixed box until no more need (optimization remove recursion)
                        CssBox newTempRightBox = null;
                        if (DomUtils.ContainsInlinesOnly(tempRightBox) && !ContainsInlinesOnlyDeep(tempRightBox))
                        {
                            newTempRightBox = CorrectBlockInsideInlineImp(tempRightBox);
                        }

                        tempRightBox.ParentBox.SetAllBoxes(tempRightBox);
                        tempRightBox.ParentBox = null;
                        tempRightBox           = newTempRightBox;
                    }
                }

                if (!DomUtils.ContainsInlinesOnly(box))
                {
                    foreach (var childBox in box.Boxes)
                    {
                        CorrectBlockInsideInline(childBox);
                    }
                }
            }
            catch (Exception ex)
            {
                box.HtmlContainer.ReportError(HtmlRenderErrorType.HtmlParsing, "Failed in block inside inline box correction", ex);
            }
        }
예제 #2
0
        /// <summary>
        /// Makes block boxes be among only block boxes and all inline boxes have block parent box.<br/>
        /// Inline boxes should live in a pool of Inline boxes only so they will define a single block.<br/>
        /// At the end of this process a block box will have only block siblings and inline box will have
        /// only inline siblings.
        /// </summary>
        /// <param name="box">the current box to correct its sub-tree</param>
        private static void CorrectInlineBoxesParent(CssBox box)
        {
            if (ContainsVariantBoxes(box))
            {
                for (int i = 0; i < box.Boxes.Count; i++)
                {
                    if (box.Boxes[i].IsInline)
                    {
                        var newbox = CssBox.CreateBlock(box, null, box.Boxes[i++]);
                        while (i < box.Boxes.Count && box.Boxes[i].IsInline)
                        {
                            box.Boxes[i].ParentBox = newbox;
                        }
                    }
                }
            }

            if (!DomUtils.ContainsInlinesOnly(box))
            {
                foreach (var childBox in box.Boxes)
                {
                    CorrectInlineBoxesParent(childBox);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Makes block boxes be among only block boxes and all inline boxes have block parent box.<br/>
        /// Inline boxes should live in a pool of Inline boxes only so they will define a single block.<br/>
        /// At the end of this process a block box will have only block siblings and inline box will have
        /// only inline siblings.
        ///
        /// </summary>
        /// <param name="box">the current box to correct its sub-tree</param>
        private static void CorrectInlineBoxesParent(CssBox box)
        {
            if (ContainsVariantBoxes(box)) //if this box contains inline and block elements
            {
                for (int i = 0; i < box.Boxes.Count; i++)
                {
                    //if the child isInline box take the child and add it to newbox
                    // then set newbox as the parentbox
                    if (box.Boxes[i].IsInline)
                    {
                        //creates new box in parent(box) at position it was in currently in
                        var newbox = CssBox.CreateBlock(box, null, box.Boxes[i++]);
                        while (i < box.Boxes.Count && box.Boxes[i].IsInline)
                        {
                            box.Boxes[i].ParentBox = newbox;
                        }
                    }
                }
            }

            if (!DomUtils.ContainsInlinesOnly(box))
            {
                foreach (var childBox in box.Boxes)
                {
                    CorrectInlineBoxesParent(childBox);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Gets if this box has only inline siblings (including itself)
        /// </summary>
        /// <returns></returns>
        internal bool HasJustInlineSiblings()
        {
            if (ParentBox == null)
            {
                return(false);
            }

            return(DomUtils.ContainsInlinesOnly(ParentBox));
        }
예제 #5
0
        /// <summary>
        /// Correct DOM tree if there is block boxes that are inside inline blocks.<br/>
        /// Need to rearange the tree so block box will be only the child of other block box.
        /// </summary>
        /// <param name="box">the current box to correct its sub-tree</param>
        private static void CorrectBlockInsideInline(CssBox box)
        {
            if (DomUtils.ContainsInlinesOnly(box) && !ContainsInlinesOnlyDeep(box))
            {
                CorrectBlockInsideInlineImp(box);
            }

            if (!DomUtils.ContainsInlinesOnly(box))
            {
                foreach (var childBox in box.Boxes)
                {
                    CorrectBlockInsideInline(childBox);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Correct DOM tree if there is block boxes that are inside inline blocks.<br/>
        /// Need to rearrange the tree so block box will be only the child of other block box.
        /// </summary>
        /// <param name="box">the current box to correct its sub-tree</param>
        private static void CorrectBlockInsideInline(CssBox box)
        {
            try
            {
                if (DomUtils.ContainsInlinesOnly(box) && !ContainsInlinesOnlyDeep(box))
                {
                    CorrectBlockInsideInlineImp(box);
                }

                if (!DomUtils.ContainsInlinesOnly(box))
                {
                    foreach (var childBox in box.Boxes)
                    {
                        CorrectBlockInsideInline(childBox);
                    }
                }
            }
            catch (Exception ex)
            {
                box.HtmlContainer.ReportError(HtmlRenderErrorType.HtmlParsing, "Failed in block inside inline box correction", ex);
            }
        }
예제 #7
0
        /// <summary>
        /// Measures the bounds of box and children, recursively.<br/>
        /// Performs layout of the DOM structure creating lines by set bounds restrictions.
        /// </summary>
        /// <param name="g">Device context to use</param>
        private void MeasureBoundsImp(Graphics g)
        {
            if (Display == CssConstants.None)
            {
                return;
            }

            RectanglesReset();

            MeasureWordsSize(g);

            if (Display == CssConstants.Block ||
                Display == CssConstants.ListItem ||
                Display == CssConstants.Table ||
                Display == CssConstants.InlineTable ||
                Display == CssConstants.TableCell ||
                Display == CssConstants.None)
            {
                if (Display != CssConstants.TableCell)
                {
                    var   prevSibling = DomUtils.GetPreviousSibling(this);
                    float left        = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft + ContainingBlock.ActualBorderLeftWidth;
                    float top         = (prevSibling == null && ParentBox != null ? ParentBox.ClientTop : ParentBox == null ? Location.Y : 0) + MarginTopCollapse(prevSibling) + (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0);
                    Location     = new PointF(left, top);
                    ActualBottom = top;
                }

                // Because their width and height are set by CssTable
                if (Display != CssConstants.TableCell && Display != CssConstants.Table)
                {
                    //width at 100% (or auto)
                    float minwidth = GetMinimumWidth();
                    float width    = ContainingBlock.Size.Width
                                     - ContainingBlock.ActualPaddingLeft - ContainingBlock.ActualPaddingRight
                                     - ContainingBlock.ActualBorderLeftWidth - ContainingBlock.ActualBorderRightWidth
                                     - ActualMarginLeft - ActualMarginRight - ActualBorderLeftWidth - ActualBorderRightWidth;

                    //Check width if not auto
                    if (Width != CssConstants.Auto && !string.IsNullOrEmpty(Width))
                    {
                        width = CssValueParser.ParseLength(Width, width, this);
                    }

                    if (width < minwidth || width >= 9999)
                    {
                        width = minwidth;
                    }

                    Size = new SizeF(width, Size.Height);
                }

                //If we're talking about a table here..
                if (Display == CssConstants.Table || Display == CssConstants.InlineTable)
                {
                    new CssTable(this, g);
                }
                else
                {
                    //If there's just inlines, create LineBoxes
                    if (DomUtils.ContainsInlinesOnly(this))
                    {
                        ActualBottom = Location.Y;
                        CssLayoutEngine.CreateLineBoxes(g, this); //This will automatically set the bottom of this block
                    }
                    else if (_boxes.Count > 0)
                    {
                        foreach (var childBox in Boxes)
                        {
                            childBox.MeasureBoundsImp(g);
                        }
                        ActualBottom = MarginBottomCollapse();
                    }
                }
            }

            if (HtmlContainer != null)
            {
                HtmlContainer.ActualSize = new SizeF(Math.Max(HtmlContainer.ActualSize.Width, Size.Width < 9999 ? Size.Width : 0), Math.Max(HtmlContainer.ActualSize.Height, Size.Height));
            }
        }