Example #1
0
        internal void InvalidateGraphics()
        {
            switch (_runKind)
            {
            case CssRunKind.BlockRun:
            {
                //TODO: review here again

                CssBlockRun blockRun  = (CssBlockRun)this;
                CssLineBox  ownerLine = blockRun.HostLine;
                Rectangle   r         = new Rectangle(
                    (int)(this.Left + blockRun.Left),
                    (int)(this.Top + blockRun.Top + ownerLine.CachedLineTop),
                    (int)this.Width,
                    (int)this.Height);
                CssBox ownerBox = ownerLine.OwnerBox;
                ownerBox.InvalidateGraphics(r);
            }
            break;

            default:
                //fine owner
            {
                CssLineBox ownerLine = this.HostLine;
                Rectangle  r         = new Rectangle(
                    (int)(this.Left),
                    (int)(this.Top + ownerLine.CachedLineTop),
                    (int)this.Width,
                    (int)this.Height);
                CssBox ownerBox = ownerLine.OwnerBox;
                ownerBox.InvalidateGraphics(r);
            }
            break;
            }
        }
Example #2
0
            public LineWalkVisitor(CssBlockRun startBlockRun)
            {
                float endElemX = 0, endElemY = 0;

                startBlockRun.ContentBox.GetGlobalLocation(out endElemX, out endElemY);
                this.globalX       = endElemX;
                this.globalY       = endElemY;
                this.startBlockRun = startBlockRun;
            }
Example #3
0
            public LineWalkVisitor(CssBlockRun startBlockRun)
            {
                PointF p = new PointF();

                startBlockRun.ContentBox.GetGlobalLocationRelativeToRoot(ref p);
                _globalX       = p.X;
                _globalY       = p.Y;
                _startBlockRun = startBlockRun;

                //startBlockRun.ContentBox.GetGlobalLocation(out float endElemX, out float endElemY);
                //_globalX = endElemX;
                //_globalY = endElemY;
                //_startBlockRun = startBlockRun;
            }
Example #4
0
        internal void PaintRuns(PaintVisitor p)
        {
            List <CssRun> tmpRuns = _runs;
            int           j       = tmpRuns.Count;

            if (j < 1)
            {
                return;
            }
            //-----------------------


            //iterate from each words
            CssBox      latestOwner = null;
            DrawBoard   innerCanvas = p.InnerDrawBoard;
            RequestFont enterFont   = innerCanvas.CurrentFont;
            Color       enterColor  = innerCanvas.CurrentTextColor;

            for (int i = 0; i < j; ++i)
            {
                //-----------------
#if DEBUG
                dbugCounter.dbugRunPaintCount++;
#endif
                //-----------------

                CssRun w = tmpRuns[i];
                switch (w.Kind)
                {
                case CssRunKind.SolidContent:
                {
                    w.OwnerBox.Paint(p, new RectangleF(w.Left, w.Top, w.Width, w.Height));
                }
                break;

                case CssRunKind.BlockRun:
                {
                    //Console.WriteLine("blockrun");
                    CssBlockRun blockRun = (CssBlockRun)w;
                    int         ox       = p.CanvasOriginX;
                    int         oy       = p.CanvasOriginY;
                    //p.SetCanvasOrigin(ox + (int)(blockRun.Left + blockRun.ContentBox.LocalX), oy + (int)blockRun.Top);
                    p.SetCanvasOrigin(ox + (int)(blockRun.Left), oy + (int)blockRun.Top);
                    blockRun.ContentBox.Paint(p);
                    p.SetCanvasOrigin(ox, oy);
                }
                break;

                case CssRunKind.Text:
                {
                    if (latestOwner != w.OwnerBox)
                    {
                        //change
                        latestOwner = w.OwnerBox;
                        //change font when change owner

                        p.InnerDrawBoard.CurrentFont      = latestOwner.ResolvedFont;
                        p.InnerDrawBoard.CurrentTextColor = latestOwner.ActualColor;
                    }

                    CssTextRun textRun = (CssTextRun)w;
                    p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                               textRun.TextStartIndex,
                               textRun.TextLength,
                               new PointF(w.Left, w.Top),
                               new SizeF(w.Width, w.Height));
                }
                break;

                default:
                {
#if DEBUG
                    // w.OwnerBox.dbugPaintTextWordArea(g, offset, w);
#endif
                }
                break;
                }
            }


            innerCanvas.CurrentFont      = enterFont;
            innerCanvas.CurrentTextColor = enterColor;
        }
Example #5
0
        void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, ITextService textService)
        {
            //find global location of end point
            HitInfo    endHit        = endChain.GetLastHit();
            int        xposOnEndLine = 0;
            CssLineBox endline       = null;

            //find endline first
            _endHitRunCharIndex = 0;
            _endHitRun          = null;
            switch (endHit.hitObjectKind)
            {
            default:
            {
                throw new NotSupportedException();
            }

            case HitObjectKind.Run:
            {
                CssRun endRun = (CssRun)endHit.hitObject;
#if DEBUG
                //if (endRun.Text != null && endRun.Text.Contains("Jose"))
                //{
                //}
                if (endHit.localX > 23)
                {
                }
                System.Diagnostics.Debug.WriteLine(endHit.localX);
#endif
                endRun.FindSelectionPoint(textService,
                                          endHit.localX,
                                          out int run_sel_index,
                                          out int run_sel_offset);
                endline             = endRun.HostLine;
                xposOnEndLine       = (int)(endRun.Left + run_sel_offset);
                _endHitRunCharIndex = run_sel_index;

#if DEBUG
                System.Diagnostics.Debug.WriteLine(_endHitRunCharIndex);
#endif
                _endHitRun = endRun;
            }
            break;

            case HitObjectKind.LineBox:
            {
                endline       = (CssLineBox)endHit.hitObject;
                xposOnEndLine = endHit.localX;
            }
            break;

            case HitObjectKind.CssBox:
            {
                CssBox hitBox = (CssBox)endHit.hitObject;
                endline       = FindNearestLine(hitBox, endChain.RootGlobalY, 5);
                xposOnEndLine = endHit.localX;
            }
            break;
            }

#if DEBUG
            if (xposOnEndLine == 0)
            {
            }
#endif

            //----------------------------------
            _selectedLines = new List <CssLineBox>();
            if (_startHitHostLine == endline)
            {
                _selectedLines.Add(endline);
                _startHitHostLine.Select(_startLineBeginSelectionAtPixel, xposOnEndLine,
                                         _startHitRun, _startHitRunCharIndex,
                                         _endHitRun, _endHitRunCharIndex);
                return; //early exit here ***
            }
            //----------------------------------
            //select on different line
            LineWalkVisitor lineWalkVisitor = null;

            if (FindCommonGround(startChain, endChain, out int breakAtLevel) && breakAtLevel > 0)
            {
                CssBlockRun hitBlockRun = endChain.GetHitInfo(breakAtLevel).hitObject as CssBlockRun;
                //multiple select
                //1. first part
                if (hitBlockRun != null)
                {
                    _startHitHostLine.Select(_startLineBeginSelectionAtPixel, (int)hitBlockRun.Left,
                                             _startHitRun, _startHitRunCharIndex,
                                             _endHitRun, _endHitRunCharIndex);
                    _selectedLines.Add(_startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(hitBlockRun);
                }
                else
                {
                    _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex);
                    _selectedLines.Add(_startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(_startHitHostLine);
                }
            }
            else
            {
                _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex);
                _selectedLines.Add(_startHitHostLine);
                lineWalkVisitor = new LineWalkVisitor(_startHitHostLine);
            }

            lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY);

#if DEBUG
            int dbugExpectedId = 1;
#endif
            lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) =>
            {
#if DEBUG
                //System.Diagnostics.Debug.WriteLine("sel:" + linebox.dbugId);
                if (dbugExpectedId != linebox.dbugId)
                {
                }
                dbugExpectedId++;
#endif
                switch (lineCoverage)
                {
                case LineCoverage.EndLine:
                    {
                        //found end line
                        linebox.SelectPartialFromStart(xposOnEndLine, _endHitRun, _endHitRunCharIndex);
                        _selectedLines.Add(linebox);
                    }
                    break;

                case LineCoverage.PartialLine:
                    {
                        linebox.SelectPartialFromStart((int)partialLineRun.Right, _endHitRun, _endHitRunCharIndex);
                        _selectedLines.Add(linebox);
                    }
                    break;

                case LineCoverage.FullLine:
                    {
                        //check if hitpoint is in the line area
                        linebox.SelectFull();
                        _selectedLines.Add(linebox);
                    }
                    break;
                }
            });
        }
Example #6
0
        internal void PaintRuns(PaintVisitor p)
        {
            List <CssRun> tmpRuns = _runs;
            int           j       = tmpRuns.Count;

            if (j < 1)
            {
                return;
            }
            //-----------------------


            //iterate from each words
            CssBox      latestOwner = null;
            DrawBoard   innerCanvas = p.InnerDrawBoard;
            RequestFont enterFont   = innerCanvas.CurrentFont;
            Color       enterColor  = innerCanvas.CurrentTextColor;

            for (int i = 0; i < j; ++i)
            {
                //-----------------
#if DEBUG
                dbugCounter.dbugRunPaintCount++;
#endif
                //-----------------

                CssRun w = tmpRuns[i];
                switch (w.Kind)
                {
                case CssRunKind.SolidContent:
                {
#if DEBUG
                    //System.Diagnostics.Debug.WriteLine("ox,oy=" + p.CanvasOriginX + "," + p.CanvasOriginY);
                    //System.Diagnostics.Debug.WriteLine("clip=" + p.CurrentClipRect);
#endif

                    Rectangle currentClipRect = p.CurrentClipRect;
                    Rectangle wRect           = new Rectangle((int)w.Left, (int)w.Top, (int)w.Width, (int)w.Height);
                    wRect.Intersect(currentClipRect);
#if DEBUG
                    //System.Diagnostics.Debug.WriteLine("empty_clip=" + (wRect.Height == 0 || wRect.Width == 0));
#endif

                    if (wRect.Height != 0 && wRect.Width != 0)
                    {
                        w.OwnerBox.Paint(p, new RectangleF(w.Left, w.Top, w.Width, w.Height));
                    }
                }
                break;

                case CssRunKind.BlockRun:
                {
                    //Console.WriteLine("blockrun");
                    CssBlockRun blockRun = (CssBlockRun)w;
                    int         ox       = p.CanvasOriginX;
                    int         oy       = p.CanvasOriginY;
                    //p.SetCanvasOrigin(ox + (int)(blockRun.Left + blockRun.ContentBox.LocalX), oy + (int)blockRun.Top);
                    p.SetCanvasOrigin(ox + (int)(blockRun.Left), oy + (int)blockRun.Top);
                    blockRun.ContentBox.Paint(p);
                    p.SetCanvasOrigin(ox, oy);
                }
                break;

                case CssRunKind.Text:
                {
                    if (latestOwner != w.OwnerBox)
                    {
                        //change
                        latestOwner = w.OwnerBox;
                        //change font when change owner

                        p.InnerDrawBoard.CurrentFont      = latestOwner.ResolvedFont;
                        p.InnerDrawBoard.CurrentTextColor = latestOwner.ActualColor;
                    }

                    CssTextRun textRun = (CssTextRun)w;
                    p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                               textRun.TextStartIndex,
                               textRun.TextLength,
                               new PointF(w.Left, w.Top),
                               new SizeF(w.Width, w.Height));


                    //RenderVxFormattedString formattedStr = CssTextRun.GetCachedFormatString(textRun);
                    //if (formattedStr == null)
                    //{
                    //    formattedStr = p.CreateRenderVx(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                    //                                textRun.TextStartIndex,
                    //                                textRun.TextLength);

                    //    CssTextRun.SetCachedFormattedString(textRun, formattedStr);
                    //}
                    //if (formattedStr != null)
                    //{
                    //    p.DrawText(formattedStr,
                    //                               new PointF(w.Left, w.Top),
                    //                               new SizeF(w.Width, w.Height));
                    //}
                    //else
                    //{
                    //    p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                    //                               textRun.TextStartIndex,
                    //                               textRun.TextLength,
                    //                               new PointF(w.Left, w.Top),
                    //                               new SizeF(w.Width, w.Height));
                    //}
                }
                break;

                default:
                {
#if DEBUG
                    // w.OwnerBox.dbugPaintTextWordArea(g, offset, w);
#endif
                }
                break;
                }
            }


            innerCanvas.CurrentFont      = enterFont;
            innerCanvas.CurrentTextColor = enterColor;
        }
Example #7
0
 public LineWalkVisitor(CssBlockRun startBlockRun)
 {
     float endElemX = 0, endElemY = 0;
     startBlockRun.ContentBox.GetGlobalLocation(out endElemX, out endElemY);
     this.globalX = endElemX;
     this.globalY = endElemY;
     this.startBlockRun = startBlockRun;
 }
Example #8
0
        /// <summary>
        /// Recursively flows the content of the box using the inline model
        /// </summary>
        /// <param name="lay"></param>
        /// <param name="hostBox"></param>
        /// <param name="srcBox"></param>
        /// <param name="limitLocalRight"></param>
        /// <param name="firstRunStartX"></param>
        /// <param name="hostLine"></param>
        /// <param name="cx"></param>
        static void FlowBoxContentIntoHostLineFmtContext(
          LayoutVisitor lay,
          CssBox hostBox, //target host box that contains line formatting context
          CssBox srcBox, //src that has  runs /splitable content) to flow into hostBox line model
          float limitLocalRight,
          float firstRunStartX,
          ref CssLineBox hostLine,
          ref float cx,
          ref FloatFormattingContext floatCtx)
        {
            //recursive *** 
            //-------------------------------------------------------------------- 
            var oX = cx;
            if (srcBox.HasOnlyRuns)
            {
                //condition 3 

                FlowRunsIntoHost(lay, hostBox, srcBox, srcBox, 0,
                     limitLocalRight, firstRunStartX,
                     0, 0,
                     CssBox.UnsafeGetRunList(srcBox),
                     ref hostLine, ref cx
                     );
            }
            else
            {
                int childNumber = 0;
                var ifonts = lay.SampleIFonts;
                CssBoxCollection children = CssBox.UnsafeGetChildren(srcBox);
                var cNode = children.GetFirstLinkedNode();
                while (cNode != null)
                {
                    float leftMostSpace = 0, rightMostSpace = 0;
                    CssBox b = cNode.Value;
                    //if b has absolute pos then it is removed from the flow 
                    if (b.NeedComputedValueEvaluation)
                    {
                        b.ReEvaluateComputedValues(ifonts, hostBox);
                    }
                    b.MeasureRunsSize(lay);
#if DEBUG
                    if (b.Position == CssPosition.Absolute)
                    {
                        //should not found here!
                        throw new NotSupportedException();
                    }
#endif


                    cx += leftMostSpace;
                    if (b.CssDisplayInside == CssDisplayInside.FlowRoot)//eg. inline block
                    {
                        //--------
                        // if inside display is FlowRoot *** 
                        //--------- 

                        //outside -> inline
                        //inside -> flow-root

                        //can't split 
                        //create 'block-run'  
                        CssLayoutEngine.PerformContentLayout(b, lay);
                        CssBlockRun blockRun = b.JustBlockRun;
                        if (blockRun == null)
                        {
                            blockRun = new CssBlockRun(b);
                            blockRun.SetOwner(srcBox);
                            b.JustBlockRun = blockRun;
                        }


                        if (b.Width.IsEmptyOrAuto)
                        {
                            blockRun.SetSize(CssBox.GetLatestCachedMinWidth(b), b.VisualHeight);
                        }
                        else
                        {
                            blockRun.SetSize(b.VisualWidth, b.VisualHeight);
                        }

                        b.SetLocation(b.LocalX, 0); //because of inline***
                        FlowRunsIntoHost(lay, hostBox, srcBox, b, childNumber,
                            limitLocalRight, firstRunStartX,
                            leftMostSpace, rightMostSpace,
                            new List<CssRun>() { b.JustBlockRun },
                            ref hostLine, ref cx);
                    }
                    else if (b.CssDisplayOutside == CssDisplayOutside.Block)
                    {
                        //warning : this code block not follow w3c spec ***


                        CssLayoutEngine.PerformContentLayout(b, lay);
                        CssBlockRun blockRun = b.JustBlockRun;
                        if (blockRun == null)
                        {
                            blockRun = new CssBlockRun(b);
                            blockRun.SetOwner(srcBox);
                            b.JustBlockRun = blockRun;
                        }

                        //set width to full ***
                        blockRun.SetSize(hostBox.GetClientWidth(), b.VisualHeight);
                        b.SetLocation(b.LocalX, 0); //because of inline***
                        FlowRunsIntoHost(lay, hostBox, srcBox, b, childNumber,
                            limitLocalRight, firstRunStartX,
                            leftMostSpace, rightMostSpace,
                            new List<CssRun>() { b.JustBlockRun },
                            ref hostLine, ref cx);
                    }
                    else if (b.HasOnlyRuns)
                    {
                        switch (b.Float)
                        {
                            default:
                            case CssFloat.None:
                                {
                                    FlowRunsIntoHost(lay, hostBox, srcBox, b, childNumber,
                                        limitLocalRight, firstRunStartX,
                                        leftMostSpace, rightMostSpace,
                                        CssBox.UnsafeGetRunList(b),
                                        ref hostLine, ref cx);
                                }
                                break;
                            case CssFloat.Left:
                                {
                                    //float is out of flow item 
                                    //1. current line is shortening
                                    //2. add 'b' to special container ***  

                                    var newAnonBlock = new CssFloatContainerBox(
                                        CssBox.UnsafeGetBoxSpec(b),
                                        b.RootGfx, CssDisplay.Block);
                                    newAnonBlock.ReEvaluateComputedValues(ifonts, hostBox);
                                    //add to abs layer
                                    hostBox.AppendToAbsoluteLayer(newAnonBlock);
                                    newAnonBlock.ResetLineBoxes();
                                    float localX1 = 0;
                                    var line = new CssLineBox(newAnonBlock);
                                    newAnonBlock.AddLineBox(line);
                                    var newFloatCtx = new FloatFormattingContext();
                                    FlowBoxContentIntoHostLineFmtContext(lay, newAnonBlock, b,
                                        limitLocalRight, 0,
                                        ref line, ref localX1, ref newFloatCtx);
                                    float localY = 0;
                                    int interlineSpace = 0;
                                    float maxLineWidth = 0;
                                    CssTextAlign textAlign = newAnonBlock.CssTextAlign;
                                    foreach (CssLineBox linebox in newAnonBlock.GetLineBoxIter())
                                    {
                                        ApplyAlignment(linebox, textAlign, lay);
                                        linebox.CloseLine(lay); //*** 
                                        linebox.CachedLineTop = localY;
                                        localY += linebox.CacheLineHeight + interlineSpace;
                                        if (maxLineWidth < linebox.CachedExactContentWidth)
                                        {
                                            maxLineWidth = linebox.CachedExactContentWidth;
                                        }
                                    }

                                    float hostSizeW = hostBox.VisualWidth;
                                    SetFinalInnerContentSize(newAnonBlock, maxLineWidth, localY, lay);
                                    //need to adjust line box   

                                    //TODO: review here!, 
                                    if (hostLine.CanDoMoreLeftOffset(newAnonBlock.InnerContentWidth, limitLocalRight))
                                    {
                                        hostLine.DoLeftOffset(newAnonBlock.InnerContentWidth);
                                        cx = hostLine.GetRightOfLastRun();
                                        newAnonBlock.SetLocation(floatCtx.lineLeftOffset, floatCtx.offsetFloatTop); //TODO: review top location again
                                        floatCtx.lineLeftOffset = newAnonBlock.LocalX + newAnonBlock.InnerContentWidth;
                                    }
                                    else
                                    {
                                        //newline
                                        newAnonBlock.SetLocation(hostBox.GetClientLeft(), hostLine.CalculateLineHeight());
                                        floatCtx.offsetFloatTop = newAnonBlock.LocalY;
                                    }
                                }
                                break;
                            case CssFloat.Right:
                                {
                                    //float is out of flow item      
                                    //1. create new block box and then
                                    //flow content in to this new box
                                    var newAnonBlock = new CssFloatContainerBox(
                                        CssBox.UnsafeGetBoxSpec(b),
                                        b.RootGfx, CssDisplay.Block);
                                    newAnonBlock.ReEvaluateComputedValues(ifonts, hostBox);
                                    //add to abs layer
                                    hostBox.AppendToAbsoluteLayer(newAnonBlock);
                                    newAnonBlock.ResetLineBoxes();
                                    float localX1 = 0;
                                    var line = new CssLineBox(newAnonBlock);
                                    newAnonBlock.AddLineBox(line);
                                    var newFloatCtx = new FloatFormattingContext();
                                    FlowBoxContentIntoHostLineFmtContext(lay, newAnonBlock, b,
                                        limitLocalRight, 0,
                                        ref line, ref localX1, ref newFloatCtx);
                                    float localY = 0;
                                    int interlineSpace = 0;
                                    float maxLineWidth = 0;
                                    CssTextAlign textAlign = newAnonBlock.CssTextAlign;
                                    foreach (CssLineBox linebox in newAnonBlock.GetLineBoxIter())
                                    {
                                        ApplyAlignment(linebox, textAlign, lay);
                                        linebox.CloseLine(lay); //*** 
                                        linebox.CachedLineTop = localY;
                                        localY += linebox.CacheLineHeight + interlineSpace;
                                        if (maxLineWidth < linebox.CachedExactContentWidth)
                                        {
                                            maxLineWidth = linebox.CachedExactContentWidth;
                                        }
                                    }
                                    SetFinalInnerContentSize(newAnonBlock, maxLineWidth, localY, lay);
                                    //todo: review here
                                    float hostSizeW = hostBox.VisualWidth;
                                    var rightOfLastRun = hostLine.GetRightOfLastRun();
                                    if (!floatCtx.floatingOutOfLine)
                                    {
                                        if (rightOfLastRun + maxLineWidth < hostSizeW - floatCtx.lineRightOffset)
                                        {
                                            float newX = hostSizeW - (maxLineWidth + floatCtx.lineRightOffset);
                                            newAnonBlock.SetLocation(newX, floatCtx.offsetFloatTop);
                                            floatCtx.lineRightOffset = newX;
                                            floatCtx.rightFloatBox = newAnonBlock;
                                            floatCtx.floatingOutOfLine = true;
                                        }
                                        else
                                        {
                                            //start newline 
                                            float newX = hostSizeW - maxLineWidth;
                                            newAnonBlock.SetLocation(newX, floatCtx.offsetFloatTop + hostLine.CalculateLineHeight());
                                            floatCtx.lineRightOffset = newX;
                                            floatCtx.rightFloatBox = newAnonBlock;
                                            floatCtx.floatingOutOfLine = true;
                                            floatCtx.offsetFloatTop = newAnonBlock.LocalY;
                                        }
                                    }
                                    else
                                    {
                                        //out-of-line mode
                                        if (floatCtx.rightFloatBox != null)
                                        {
                                            float newX = floatCtx.rightFloatBox.LocalX - maxLineWidth;
                                            if (newX > 0)
                                            {
                                                newAnonBlock.SetLocation(newX, floatCtx.offsetFloatTop);
                                                floatCtx.lineRightOffset = newX;
                                                floatCtx.rightFloatBox = newAnonBlock;
                                                floatCtx.offsetFloatTop = newAnonBlock.LocalY;
                                            }
                                            else
                                            {  //start new line
                                                newX = hostSizeW - maxLineWidth;
                                                newAnonBlock.SetLocation(newX, floatCtx.rightFloatBox.LocalY + floatCtx.rightFloatBox.InnerContentHeight);
                                                floatCtx.lineRightOffset = newX;
                                                floatCtx.rightFloatBox = newAnonBlock;
                                                floatCtx.offsetFloatTop = newAnonBlock.LocalY + newAnonBlock.InnerContentHeight;
                                            }
                                        }
                                        else
                                        {
                                            throw new NotSupportedException();
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    else
                    {
                        //go deeper  
                        //recursive *** 
                        //not new lineFormatting context
                        FlowBoxContentIntoHostLineFmtContext(lay, hostBox, b,
                                   limitLocalRight, firstRunStartX,
                                   ref hostLine, ref cx, ref floatCtx);
                    }

                    cx += rightMostSpace;
                    childNumber++;
                    //---------------------
                    cNode = cNode.Next;
                }
            }
            if (srcBox.Position == CssPosition.Relative)
            {
                //offset content relative to it 'flow' position'
                var left = CssValueParser.ConvertToPx(srcBox.Left, hostBox.VisualWidth, srcBox);
                var top = CssValueParser.ConvertToPx(srcBox.Top, hostBox.VisualWidth, srcBox);
                srcBox.SetLocation(srcBox.LocalX + left, srcBox.LocalY + top);
            }
        }
Example #9
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);
        }