GetLineBoxIter() private method

private GetLineBoxIter ( ) : IEnumerable
return IEnumerable
Beispiel #1
0
            static IEnumerable <CssLineBox> GetLineWalkDownIter(LineWalkVisitor visitor, CssBox box)
            {
                //recursive
                float y = visitor._globalY;

                if (box.LineBoxCount > 0)
                {
                    foreach (CssLineBox linebox in box.GetLineBoxIter())
                    {
                        visitor._globalY = y + linebox.CachedLineTop;
                        yield return(linebox);
                    }
                }
                else
                {
                    //element based
                    foreach (CssBox childbox in box.GetChildBoxIter())
                    {
                        visitor._globalY = y + childbox.LocalY;
                        //recursive
                        foreach (var linebox in GetLineWalkDownIter(visitor, childbox))
                        {
                            yield return(linebox);
                        }
                    }
                }

                visitor._globalY = y;
            }
Beispiel #2
0
        internal static CssLineBox GetNearestLine(CssBox a, Point point, out bool found)
        {
            if (a.LineBoxCount > 0)
            {
                CssLineBox latestLine = null;
                int        y          = point.Y;
                found = false;
                foreach (CssLineBox linebox in a.GetLineBoxIter())
                {
                    if (linebox.CachedLineBottom < y)
                    {
                        latestLine = linebox;
                    }
                    else
                    {
                        if (latestLine != null)
                        {
                            found = true;
                        }
                        break;
                    }
                }

                return(latestLine);
            }
            else
            {
                bool       foundExact = false;
                CssLineBox lastLine   = null;
                foreach (CssBox cbox in a.GetChildBoxIter())
                {
                    CssLineBox candidateLine = GetNearestLine(cbox, point, out foundExact);
                    if (candidateLine != null)
                    {
                        if (foundExact)
                        {
                            found = true;
                            return(lastLine);
                        }
                        //not exact
                        lastLine = candidateLine;
                    }
                    else
                    {
                        if (lastLine != null)
                        {
                            found = false;
                            return(lastLine);
                        }
                    }
                }
                found = foundExact;
            }
            return(null);
        }
Beispiel #3
0
 internal static IEnumerable <CssLineBox> GetDeepDownLineBoxIter(CssBox box)
 {
     if (box.LineBoxCount > 0)
     {
         foreach (CssLineBox linebox in box.GetLineBoxIter())
         {
             yield return(linebox);
         }
     }
     else
     {
         if (box.ChildCount > 0)
         {
             foreach (CssBox child in box.GetChildBoxIter())
             {
                 foreach (CssLineBox linebox in GetDeepDownLineBoxIter(child))
                 {
                     yield return(linebox);
                 }
             }
         }
     }
 }
Beispiel #4
0
        public static bool HitTest(CssBox box, float x, float y, CssBoxHitChain hitChain)
        {
            //--------------------------------------
            float boxHitLocalX  = x - box.LocalX;
            float boxHitLocalY  = y - box.LocalY;
            bool  isPointInArea = box.IsPointInArea(x, y);

            //----------------------------------------------------------------------
            if (isPointInArea)
            {
                hitChain.AddHit(box, (int)boxHitLocalX, (int)boxHitLocalY);
            }

            //check absolute layer first ***
            if (box.HasAbsoluteLayer)
            {
                hitChain.PushContextBox(box);
                foreach (var absBox in box.GetAbsoluteChildBoxBackwardIter())
                {
                    if (HitTest(absBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //found hit
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                }
                hitChain.PopContextBox(box);
            }
            //----------------------------------------------------------------------
            if (!isPointInArea)
            {
                switch (box.CssDisplay)
                {
                case Css.CssDisplay.TableRow:
                {
                    foreach (var childBox in box.GetChildBoxIter())
                    {
                        if (HitTest(childBox, x, y, hitChain))
                        {
                            return(true);
                        }
                    }
                } break;
                }
                //exit
                return(false);
            }
            //----------------------------------------------------------------------
            //at here point is in the area***

            hitChain.PushContextBox(box);
            if (box.IsCustomCssBox)
            {
                //custom css box
                //return true= stop here
                if (box.CustomContentHitTest(x, y, hitChain))
                {
                    hitChain.PopContextBox(box);
                    return(true);
                }
            }

            if (box.LineBoxCount > 0)
            {
                bool foundSomeLine = false;
                foreach (var lineBox in box.GetLineBoxIter())
                {
                    //line box not overlap
                    if (lineBox.HitTest(boxHitLocalX, boxHitLocalY))
                    {
                        foundSomeLine = true;
                        float lineBoxLocalY = boxHitLocalY - lineBox.CachedLineTop;
                        //2.
                        hitChain.AddHit(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);

                        var foundRun = BoxHitUtils.GetCssRunOnLocation(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);

                        if (foundRun != null)
                        {
                            //3.
                            hitChain.AddHit(foundRun, (int)(boxHitLocalX - foundRun.Left), (int)lineBoxLocalY);
                            //4. go deeper for block run
                            if (foundRun.Kind == CssRunKind.BlockRun)
                            {
                                var        blockRun = (CssBlockRun)foundRun;
                                CssLineBox hostLine = blockRun.HostLine;
                                //adjust with hostline

                                HitTest(((CssBlockRun)foundRun).ContentBox, (int)(boxHitLocalX - foundRun.Left), boxHitLocalY - hostLine.CachedLineTop, hitChain);
                            }
                        }
                        //found line box
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                    else if (foundSomeLine)
                    {
                        return(false);
                    }
                }
            }
            else
            {
                //iterate in child
                foreach (var childBox in box.GetChildBoxIter())
                {
                    if (HitTest(childBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //recursive
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                }
            }
            hitChain.PopContextBox(box);
            return(true);
        }
Beispiel #5
0
        public static bool HitTest(CssBox box, float x, float y, CssBoxHitChain hitChain)
        {
            //--------------------------------------
            float boxHitLocalX = x - box.LocalX;
            float boxHitLocalY = y - box.LocalY;
            bool isPointInArea = box.IsPointInArea(x, y);
            //----------------------------------------------------------------------
            if (isPointInArea)
            {
                hitChain.AddHit(box, (int)boxHitLocalX, (int)boxHitLocalY);
            }

            //check absolute layer first ***
            if (box.HasAbsoluteLayer)
            {
                hitChain.PushContextBox(box);
                foreach (var absBox in box.GetAbsoluteChildBoxBackwardIter())
                {
                    if (HitTest(absBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //found hit 
                        hitChain.PopContextBox(box);
                        return true;
                    }
                }
                hitChain.PopContextBox(box);
            }
            //----------------------------------------------------------------------
            if (!isPointInArea)
            {
                switch (box.CssDisplay)
                {
                    case Css.CssDisplay.TableRow:
                        {
                            foreach (var childBox in box.GetChildBoxIter())
                            {
                                if (HitTest(childBox, x, y, hitChain))
                                {
                                    return true;
                                }
                            }
                        }
                        break;
                }
                //exit 
                return false;
            }
            //----------------------------------------------------------------------
            //at here point is in the area*** 

            hitChain.PushContextBox(box);
            if (box.IsCustomCssBox)
            {
                //custom css box
                //return true= stop here
                if (box.CustomContentHitTest(x, y, hitChain))
                {
                    hitChain.PopContextBox(box);
                    return true;
                }
            }

            if (box.LineBoxCount > 0)
            {
                bool foundSomeLine = false;
                foreach (var lineBox in box.GetLineBoxIter())
                {
                    //line box not overlap
                    if (lineBox.HitTest(boxHitLocalX, boxHitLocalY))
                    {
                        foundSomeLine = true;
                        float lineBoxLocalY = boxHitLocalY - lineBox.CachedLineTop;
                        //2.
                        hitChain.AddHit(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);
                        var foundRun = BoxHitUtils.GetCssRunOnLocation(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);
                        if (foundRun != null)
                        {
                            //3.
                            hitChain.AddHit(foundRun, (int)(boxHitLocalX - foundRun.Left), (int)lineBoxLocalY);
                            //4. go deeper for block run
                            if (foundRun.Kind == CssRunKind.BlockRun)
                            {
                                var blockRun = (CssBlockRun)foundRun;
                                CssLineBox hostLine = blockRun.HostLine;
                                //adjust with hostline 

                                HitTest(((CssBlockRun)foundRun).ContentBox, (int)(boxHitLocalX - foundRun.Left), boxHitLocalY - hostLine.CachedLineTop, hitChain);
                            }
                        }
                        //found line box
                        hitChain.PopContextBox(box);
                        return true;
                    }
                    else if (foundSomeLine)
                    {
                        return false;
                    }
                }
            }
            else
            {
                //iterate in child 
                foreach (var childBox in box.GetChildBoxIter())
                {
                    if (HitTest(childBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //recursive
                        hitChain.PopContextBox(box);
                        return true;
                    }
                }
            }
            hitChain.PopContextBox(box);
            return true;
        }
Beispiel #6
0
 internal static IEnumerable<CssLineBox> GetDeepDownLineBoxIter(CssBox box)
 {
     if (box.LineBoxCount > 0)
     {
         foreach (CssLineBox linebox in box.GetLineBoxIter())
         {
             yield return linebox;
         }
     }
     else
     {
         if (box.ChildCount > 0)
         {
             foreach (CssBox child in box.GetChildBoxIter())
             {
                 foreach (CssLineBox linebox in GetDeepDownLineBoxIter(child))
                 {
                     yield return linebox;
                 }
             }
         }
     }
 }
Beispiel #7
0
        internal static CssLineBox GetNearestLine(CssBox a, Point point, out bool found)
        {
            if (a.LineBoxCount > 0)
            {
                CssLineBox latestLine = null;
                int y = point.Y;
                found = false;
                foreach (CssLineBox linebox in a.GetLineBoxIter())
                {
                    if (linebox.CachedLineBottom < y)
                    {
                        latestLine = linebox;
                    }
                    else
                    {
                        if (latestLine != null)
                        {
                            found = true;
                        }
                        break;
                    }
                }

                return latestLine;
            }
            else
            {
                bool foundExact = false;
                CssLineBox lastLine = null;
                foreach (CssBox cbox in a.GetChildBoxIter())
                {
                    CssLineBox candidateLine = GetNearestLine(cbox, point, out foundExact);
                    if (candidateLine != null)
                    {
                        if (foundExact)
                        {
                            found = true;
                            return lastLine;
                        }
                        //not exact
                        lastLine = candidateLine;
                    }
                    else
                    {
                        if (lastLine != null)
                        {
                            found = false;
                            return lastLine;
                        }
                    }
                }
                found = foundExact;
            }
            return null;
        }
            static IEnumerable<CssLineBox> GetLineWalkDownIter(LineWalkVisitor visitor, CssBox box)
            {
                //recursive
                float y = visitor.globalY;
                if (box.LineBoxCount > 0)
                {
                    foreach (var linebox in box.GetLineBoxIter())
                    {
                        visitor.globalY = y + linebox.CachedLineTop;
                        yield return linebox;
                    }
                }
                else
                {
                    //element based
                    foreach (var childbox in box.GetChildBoxIter())
                    {
                        visitor.globalY = y + childbox.LocalY;
                        //recursive
                        foreach (var linebox in GetLineWalkDownIter(visitor, childbox))
                        {
                            yield return linebox;
                        }
                    }
                }

                visitor.globalY = y;
            }
        /// <summary>
        /// do layout line formatting context
        /// </summary>
        /// <param name="hostBlock"></param>
        /// <param name="lay"></param>
        public static void DoLayoutLinesContext(CssBox hostBlock, LayoutVisitor lay)
        {
            //this in line formatting context
            //*** hostBlock must confirm that it has all inline children     
            hostBlock.SetHeightToZero();
            hostBlock.ResetLineBoxes();
            //----------------------------------------------------------------------------------------
            float limitLocalRight = hostBlock.VisualWidth - (hostBlock.ActualPaddingRight + hostBlock.ActualBorderRightWidth);
            float localX = hostBlock.ActualTextIndent + hostBlock.ActualPaddingLeft + hostBlock.ActualBorderLeftWidth;
            float localY = hostBlock.ActualPaddingTop + hostBlock.ActualBorderTopWidth;
            //----------------------------------------------------------------------------------------

            if (lay.HasFloatBoxInContext)
            {
                var recentLeftFloatBox = lay.LatestLeftFloatBox;
                var recentRightFloatBox = lay.LatestRightFloatBox;
                var latestSibling = lay.LatestSiblingBox;
                if (latestSibling != null)
                {
                    //check latest sibling first 
                    if (hostBlock.Float == CssFloat.None)
                    {
                        if (recentLeftFloatBox != null)
                        {
                            if (hostBlock.LocalY < recentLeftFloatBox.LocalVisualBottom)
                            {
                                localX = recentLeftFloatBox.LocalVisualRight;
                            }
                        }
                        else
                        {
                        }
                    }
                }
                else
                {
                    if (hostBlock.Float == CssFloat.None)
                    {
                        if (recentLeftFloatBox != null)
                        {
                            localX = recentLeftFloatBox.LocalVisualRight;
                        }
                        if (recentRightFloatBox != null)
                        {
                            limitLocalRight = recentRightFloatBox.LocalX;
                        }
                    }
                    //check if need newline or not 
                }
            }

            int interlineSpace = 0;
            //First line box 

            var line = new CssLineBox(hostBlock);
            hostBlock.AddLineBox(line);
            //****
            var floatCtx = new FloatFormattingContext();
            FlowBoxContentIntoHostLineFmtContext(lay, hostBlock, hostBlock,
                  limitLocalRight, localX,
                  ref line, ref localX, ref floatCtx);
            //**** 
            // if width is not restricted we need to lower it to the actual width
            if (hostBlock.VisualWidth + lay.ContainerBlockGlobalX >= CssBoxConstConfig.BOX_MAX_RIGHT)
            {
                float newWidth = localX + hostBlock.ActualPaddingRight + hostBlock.ActualBorderRightWidth;// CssBox.MAX_RIGHT - (args.ContainerBlockGlobalX + blockBox.LocalX);
                if (newWidth <= CSS_OFFSET_THRESHOLD)
                {
                    newWidth = CSS_OFFSET_THRESHOLD;
                }
                hostBlock.SetVisualWidth(newWidth);
            }
            //--------------------- 
            float maxLineWidth = 0;
            if (hostBlock.CssDirection == CssDirection.Rtl)
            {
                CssTextAlign textAlign = hostBlock.CssTextAlign;
                foreach (CssLineBox linebox in hostBlock.GetLineBoxIter())
                {
                    ApplyAlignment(linebox, textAlign, lay);
                    ApplyRightToLeft(linebox); //*** 
                    linebox.CloseLine(lay); //*** 
                    linebox.CachedLineTop = localY;
                    localY += linebox.CacheLineHeight + interlineSpace; // + interline space?
                    if (maxLineWidth < linebox.CachedExactContentWidth)
                    {
                        maxLineWidth = linebox.CachedExactContentWidth;
                    }
                }
            }
            else
            {
                CssTextAlign textAlign = hostBlock.CssTextAlign;
                foreach (CssLineBox linebox in hostBlock.GetLineBoxIter())
                {
                    ApplyAlignment(linebox, textAlign, lay);
                    linebox.CloseLine(lay); //***
                    linebox.CachedLineTop = localY;
                    localY += linebox.CacheLineHeight + interlineSpace;
                    if (maxLineWidth < linebox.CachedExactContentWidth)
                    {
                        maxLineWidth = linebox.CachedExactContentWidth;
                    }
                }
            }

            hostBlock.SetVisualHeight(localY + hostBlock.ActualPaddingBottom + hostBlock.ActualBorderBottomWidth);
            //final 
            SetFinalInnerContentSize(hostBlock, maxLineWidth, hostBlock.VisualHeight, lay);
        }
Beispiel #10
0
        public static bool HitTest(CssBox box, float x, float y, CssBoxHitChain hitChain)
        {
#if DEBUG
            //if (box.ViewportY != 0 && hitChain.debugEventPhase == CssBoxHitChain.dbugEventPhase.MouseDown)
            //{
            //}
#endif
            //--------------------------------------
            bool  isPointInArea = box.IsPointInArea(x, y);
            float boxHitLocalX  = x - box.LocalX; //**
            float boxHitLocalY  = y - box.LocalY; //**
            //----------------------------------------------------------------------
            if (isPointInArea)
            {
                hitChain.AddHit(box, (int)boxHitLocalX, (int)boxHitLocalY);
            }

            //----------------------------------------------------------------------
            //enter children space -> offset with its viewport
            boxHitLocalX += box.ViewportX;
            boxHitLocalY += box.ViewportY;


            //check absolute layer first ***
            if (box.HasAbsoluteLayer)
            {
                hitChain.PushContextBox(box);
                foreach (CssBox absBox in box.GetAbsoluteChildBoxBackwardIter())
                {
                    if (HitTest(absBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //found hit
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                }
                hitChain.PopContextBox(box);
            }
            //----------------------------------------------------------------------
            if (!isPointInArea)
            {
                switch (box.CssDisplay)
                {
                case Css.CssDisplay.TableRow:
                {
                    foreach (CssBox childBox in box.GetChildBoxIter())
                    {
                        if (HitTest(childBox, boxHitLocalX, boxHitLocalY, hitChain))
                        {
                            return(true);
                        }
                    }
                }
                break;
                }
                //exit
                return(false);
            }
            //----------------------------------------------------------------------
            //at here point is in the area***
            hitChain.PushContextBox(box);
            if (box.IsCustomCssBox)
            {
                //custom css box
                //return true= stop here
                if (box.CustomContentHitTest(boxHitLocalX, boxHitLocalY, hitChain))
                {
                    hitChain.PopContextBox(box);
                    return(true);
                }
            }

            if (box.LineBoxCount > 0)
            {
                bool foundSomeLine = false;
                foreach (CssLineBox lineBox in box.GetLineBoxIter())
                {
                    //line box not overlap
                    if (lineBox.HitTest(boxHitLocalX, boxHitLocalY))
                    {
                        foundSomeLine = true;
                        float lineBoxLocalY = boxHitLocalY - lineBox.CachedLineTop;
                        //2.
                        hitChain.AddHit(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);


                        CssRun foundRun = BoxHitUtils.GetCssRunOnLocation(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);
                        //CssRun foundRun = BoxHitUtils.GetCssRunOnLocation(lineBox, (int)x, (int)y);
                        if (foundRun != null)
                        {
                            //3.
                            hitChain.AddHit(foundRun, (int)(boxHitLocalX - foundRun.Left), (int)lineBoxLocalY);
                            //4. go deeper for block run
                            if (foundRun.Kind == CssRunKind.BlockRun)
                            {
                                CssBlockRun blockRun = (CssBlockRun)foundRun;
                                CssLineBox  hostLine = blockRun.HostLine;
                                //adjust with hostline
                                HitTest(blockRun.ContentBox,
                                        (int)(boxHitLocalX + blockRun.ContentBox.LocalX - foundRun.Left),
                                        (int)(boxHitLocalY - hostLine.CachedLineTop),
                                        hitChain);
                            }
                        }
                        //found line box
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                    else if (foundSomeLine)
                    {
                        return(false);
                    }
                }
            }
            else
            {
                //iterate in child
                //foreach (var childBox in box.GetChildBoxIter())
                foreach (CssBox childBox in box.GetChildBoxBackwardIter())
                {
                    if (HitTest(childBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //recursive
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                }
            }
            hitChain.PopContextBox(box);
            return(true);
        }