public SetLocation ( float localX, float localY ) : void | ||
localX | float | |
localY | float | |
return | void |
void AddToProperContainer(CssBox box) { var rectChild = new RectangleF(box.LocalX, box.LocalY, box.InnerContentWidth, box.InnerContentHeight); CssBox parent = box.ParentBox; bool found = false; while (parent != null) { var rectParent = new RectangleF(0, 0, parent.VisualWidth, parent.VisualHeight); if (rectParent.Contains(rectChild)) { found = true; //add to here float bfx, bfy; box.GetGlobalLocation(out bfx, out bfy); float rfx, rfy; parent.GetGlobalLocation(out rfx, out rfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; box.SetLocation(nx, ny); parent.AppendToAbsoluteLayer(box); break; } else { rectChild.Offset(parent.LocalX, parent.LocalY); parent = parent.ParentBox; } } if (!found) { //add to root top float bfx, bfy; box.GetGlobalLocation(out bfx, out bfy); float rfx, rfy; this._rootBox.GetGlobalLocation(out rfx, out rfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; box.SetLocation(nx, ny); this._rootBox.AppendToAbsoluteLayer(box); } }
public void Arrange() { int j = flexItems.Count; float curX = 0; float curY = 0; float availableW = AvaliableParentWidth; for (int i = 0; i < j; ++i) { FlexItem flexItem = flexItems[i]; CssBox box = flexItem.Box; box.SetLocation(curX, curY); curX += flexItem.PlanWidth; } //----------------------------------------------- if (curX < availableW) { //find box that can expand List <FlexItem> widthResizableItems = new List <FlexItem>(); for (int i = 0; i < j; ++i) { FlexItem flexItem = flexItems[i]; if (!flexItem.ReachMaxHeight) { widthResizableItems.Add(flexItem); } } //remain some space //so expand it if ((j = widthResizableItems.Count) > 0) { //how to expand it //1. check grow feature int totalExpandCount = 0; for (int i = j - 1; i >= 0; --i) { totalExpandCount += widthResizableItems[i].FlexGrow; } if (totalExpandCount > 0) { float remainingW = availableW - curX; float onePart = remainingW / totalExpandCount; //add to plan width for (int i = j - 1; i >= 0; --i) { widthResizableItems[i].PlanWidth += (onePart * widthResizableItems[i].FlexGrow); } //then rearrange the line again curX = 0;//reset for (int i = 0; i < j; ++i) { FlexItem flexItem = flexItems[i]; CssBox box = flexItem.Box; box.SetLocation(curX, curY); box.SetVisualSize(flexItem.PlanWidth, flexItem.PlanHeight); curX += flexItem.PlanWidth; } } } } else if (curX > availableW) { //use more than available width //find if it can shrink? } this.LineWidthAfterArrange = curX; //----------------------------------------------- //check for height float maxHeight = 0; for (int i = flexItems.Count - 1; i >= 0; --i) { FlexItem flexItem = flexItems[i]; CssBox box = flexItem.Box; if (maxHeight < box.VisualHeight) { maxHeight = box.VisualHeight; } } if (maxHeight < this.AvaliableParentHeight) { //expand item or shrink if (this.flexCssBox.Height.IsEmptyOrAuto) { //autoheight //then set new height for parent this.LineHeightAfterArrange = maxHeight; } else { //try expand flex item for (int i = flexItems.Count - 1; i >= 0; --i) { FlexItem flexItem = flexItems[i]; if (!flexItem.ReachMaxHeight) { flexItem.Box.SetVisualHeight(this.AvaliableParentHeight); } } this.LineHeightAfterArrange = this.AvaliableParentHeight; } } }
public void PerformLayout(LayoutVisitor lay) { if (this._rootBox == null) { return; } //----------------------- //reset _actualWidth = _actualHeight = 0; // if width is not restricted we set it to large value to get the actual later _rootBox.SetLocation(0, 0); _rootBox.SetVisualSize(this._maxWidth > 0 ? this._maxWidth : MAX_WIDTH, 0); CssBox.ValidateComputeValues(_rootBox); //----------------------- //LayoutVisitor layoutArgs = new LayoutVisitor(this.GraphicsPlatform, this); lay.PushContaingBlock(_rootBox); //----------------------- _rootBox.PerformLayout(lay); if (this._maxWidth <= 0.1) { // in case the width is not restricted we need to double layout, first will find the width so second can layout by it (center alignment) _rootBox.SetVisualWidth((int)Math.Ceiling(this._actualWidth)); _actualWidth = _actualHeight = 0; _rootBox.PerformLayout(lay); } lay.PopContainingBlock(); //----------------------- //TODO: review here again FloatingContextStack floatStack = lay.GetFloatingContextStack(); List <FloatingContext> totalContexts = floatStack.GetTotalContexts(); int j = totalContexts.Count; for (int i = 0; i < j; ++i) { FloatingContext floatingContext = totalContexts[i]; int floatBoxCount = floatingContext.FloatBoxCount; if (floatBoxCount == 0) { continue; } CssBox floatingOwner = floatingContext.Owner; float rfx, rfy; floatingOwner.GetGlobalLocation(out rfx, out rfy); CssBox prevParent = null; //TODO: review here again float extraAdjustX = 0; //temp fixed for (int n = 0; n < floatBoxCount; ++n) { float bfx, bfy; CssBox box = floatingContext.GetBox(n); box.GetGlobalLocation(out bfx, out bfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; if (prevParent != null && prevParent != box.ParentBox) { if (n > 0) { CssBox prevFloatChild = floatingContext.GetBox(n - 1); //TODO: review here again //temp fix extraAdjustX = prevFloatChild.ActualMarginRight + box.ActualMarginLeft; ny += box.ActualMarginTop; } } box.SetLocation(nx + extraAdjustX, ny); prevParent = box.ParentBox; floatingOwner.AppendToAbsoluteLayer(box); } } OnLayoutFinished(); //----------------------- unchecked { layoutVersion++; } //----------------------- }
public void SetInnerBox(CssBox innerBox) { if (_innerBox != null) { return; } _innerBox = innerBox; _scrollView = new CssScrollWrapper(innerBox); //scroll barwidth = 10; bool needHScrollBar = false; bool needVScrollBar = false; int originalBoxW = (int)innerBox.VisualWidth; int originalBoxH = (int)innerBox.VisualHeight; int newW = originalBoxW; int newH = originalBoxH; const int scBarWidth = 10; if (innerBox.InnerContentHeight > innerBox.ExpectedHeight) { needVScrollBar = true; newW -= scBarWidth; } if (innerBox.InnerContentWidth > innerBox.ExpectedWidth) { needHScrollBar = true; newH -= scBarWidth; } innerBox.SetVisualSize(newW, newH); innerBox.SetExpectedSize(newW, newH); this.AppendToAbsoluteLayer(innerBox); //check if need vertical scroll and/or horizontal scroll //vertical scrollbar if (needVScrollBar) { _vscbar = new ScrollBar(scBarWidth, needHScrollBar ? newH : originalBoxH); _vscbar.ScrollBarType = ScrollBarType.Vertical; _vscbar.MinValue = 0; _vscbar.MaxValue = innerBox.VisualHeight; _vscbar.SmallChange = 20; //add relation between viewpanel and scroll bar _vscRelation = new ScrollingRelation(_vscbar.SliderBox, _scrollView); //---------------------- CssBox scBarWrapCssBox = LayoutFarm.Composers.CustomCssBoxGenerator.CreateCssWrapper( _htmlhost, _vscbar, _vscbar.GetPrimaryRenderElement(), CssBox.UnsafeGetBoxSpec(this), null, false); scBarWrapCssBox.SetLocation(newW, 0); this.AppendToAbsoluteLayer(scBarWrapCssBox); } if (needHScrollBar) { _hscbar = new ScrollBar(needVScrollBar ? newW : originalBoxW, scBarWidth); _hscbar.ScrollBarType = ScrollBarType.Horizontal; _hscbar.MinValue = 0; _hscbar.MaxValue = innerBox.VisualHeight; _hscbar.SmallChange = 20; //add relation between viewpanel and scroll bar _hscRelation = new ScrollingRelation(_hscbar.SliderBox, _scrollView); //---------------------- CssBox scBarWrapCssBox = LayoutFarm.Composers.CustomCssBoxGenerator.CreateCssWrapper( _htmlhost, _hscbar, _hscbar.GetPrimaryRenderElement(), CssBox.UnsafeGetBoxSpec(this), null, false); scBarWrapCssBox.SetLocation(0, newH); this.AppendToAbsoluteLayer(scBarWrapCssBox); } }
void dbugAddToProperContainer(CssBox box) { var rectChild = new RectangleF(box.LocalX, box.LocalY, box.InnerContentWidth, box.InnerContentHeight); CssBox parent = box.ParentBox; bool found = false; while (parent != null) { var rectParent = new RectangleF(0, 0, parent.VisualWidth, parent.VisualHeight); if (rectParent.Contains(rectChild)) { found = true; //add to here float bfx, bfy; box.GetGlobalLocation(out bfx, out bfy); float rfx, rfy; parent.GetGlobalLocation(out rfx, out rfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; box.SetLocation(nx, ny); parent.AppendToAbsoluteLayer(box); break; } else { rectChild.Offset(parent.LocalX, parent.LocalY); parent = parent.ParentBox; } } if (!found) { //add to root top float bfx, bfy; box.GetGlobalLocation(out bfx, out bfy); float rfx, rfy; this._rootBox.GetGlobalLocation(out rfx, out rfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; box.SetLocation(nx, ny); this._rootBox.AppendToAbsoluteLayer(box); } }
public static void PerformContentLayout(CssBox box, LayoutVisitor lay) { //recursive //this box has its own container property //this box may use... // 1) line formatting context , or // 2) block formatting context CssBox myContainingBlock = lay.LatestContainingBlock; CssBox prevSibling = lay.LatestSiblingBox; if (box.CssDisplay != Css.CssDisplay.TableCell) { //------------------------------------------- if (box.CssDisplay != Css.CssDisplay.Table) { float availableWidth = myContainingBlock.GetClientWidth(); // Console.WriteLine(availableWidth.ToString()); if (!box.Width.IsEmptyOrAuto) { float w = CssValueParser.ConvertToPx(box.Width, availableWidth, box); //specific width box.SetCssBoxWidth(w); } else { box.SetCssBoxFromContainerAvailableWidth(availableWidth); } } //------------------------------------------- float localLeft = myContainingBlock.GetClientLeft() + box.ActualMarginLeft; float localTop = 0; if (prevSibling == null) { //this is first child of parent if (box.ParentBox != null) { localTop = myContainingBlock.GetClientTop(); } } else { localTop = prevSibling.LocalVisualBottom; } //if (box.Float != CssFloat.None) //{ // //float box // //find context floating c // if (lay.HasFloatBoxInContext) // { // } //} localTop += box.UpdateMarginTopCollapse(prevSibling); box.SetLocation(localLeft, localTop); box.SetHeightToZero(); } //-------------------------------------------------------------------------- switch (box.CssDisplay) { case Css.CssDisplay.Table: case Css.CssDisplay.InlineTable: { //If we're talking about a table here.. lay.PushContaingBlock(box); var currentLevelLatestSibling = lay.LatestSiblingBox; lay.LatestSiblingBox = null;//reset CssTableLayoutEngine.PerformLayout(box, myContainingBlock.GetClientWidth(), lay); lay.LatestSiblingBox = currentLevelLatestSibling; lay.PopContainingBlock(); //TODO: check if this can have absolute layer? } break; default: { //formatting context for... //1. line formatting context //2. block formatting context if (box.IsCustomCssBox) { //has custom layout method box.ReEvaluateComputedValues(lay.SampleIFonts, lay.LatestContainingBlock); box.CustomRecomputedValue(lay.LatestContainingBlock); } else { if (ContainsInlinesOnly(box)) { //This will automatically set the bottom of this block LinesFormattingEngine.DoLayoutLinesContext(box, lay); } else if (box.ChildCount > 0) { DoLayoutBlocksContext(box, lay); } if (box.HasAbsoluteLayer) { LayoutContentInAbsoluteLayer(lay, box); } } //--------------------- //again! switch (box.CssDisplay) { case CssDisplay.Flex: case CssDisplay.InlineFlex: { //------------------------------------------------ RearrangeWithFlexContext(box, lay); //------------------------------------------------ } break; default: { //TODO: review here again //if (box.Float != CssFloat.None) //{ // var iw = box.InnerContentWidth; // var ew = box.VisualWidth; // box.SetVisualSize(box.InnerContentWidth, box.InnerContentHeight); // //float to specific position // //box.SetVisualSize(iw, box.VisualHeight); //} } break; } //--------------------- } break; } switch (box.Float) { case CssFloat.Left: { #if DEBUG CssBox a = box; #endif //place it to floating context CssBox currentFloatOwner = lay.GetFloatingContextStack().CurrentTopOwner; CssBox recentLeftFloatBox = lay.LatestLeftFloatBox; CssBox recentRightFloatBox = lay.LatestRightFloatBox; float availableWidth2 = myContainingBlock.GetClientWidth(); if (recentRightFloatBox != null) { availableWidth2 -= recentRightFloatBox.LocalX; } float sx = myContainingBlock.GetClientLeft(); //-------------------------------------------------------------------- float sy = 0; if (myContainingBlock.LineBoxCount > 0) { //line context sy = myContainingBlock.GetClientTop(); } else { var prevNode = box.GetPrevNode(); if (prevNode != null) { if (prevNode.Float != CssFloat.None) { //float left/right //TODO: review inherit here if (box.VisualWidth < availableWidth2) { sy = prevNode.LocalY; } else { sy = prevNode.LocalVisualBottom; } } else { sy = prevNode.LocalVisualBottom; } } else { sy = myContainingBlock.GetClientTop(); } } if (recentLeftFloatBox != null) { availableWidth2 -= recentLeftFloatBox.LocalVisualRight; //TODO: review here again sx = recentLeftFloatBox.LocalVisualRight + recentLeftFloatBox.ActualMarginRight; sy = recentLeftFloatBox.LocalY; } if (box.VisualWidth > availableWidth2) { //start newline sx = myContainingBlock.GetClientLeft(); float sy1 = 0; float sy2 = 0; sy1 = sy2 = myContainingBlock.GetClientTop(); if (recentLeftFloatBox != null) { sy1 = recentLeftFloatBox.LocalVisualBottom + recentLeftFloatBox.ActualMarginBottom; } if (recentRightFloatBox != null) { sy2 = recentRightFloatBox.LocalVisualBottom + recentRightFloatBox.ActualMarginBottom; } sy = (sy1 > sy2) ? sy1 : sy2; } sx += box.ActualMarginLeft; sy += box.ActualMarginTop; box.SetLocation(sx, sy); lay.AddFloatBox(box); } break; case CssFloat.Right: { CssBox recentLeftFloatBox = lay.LatestLeftFloatBox; CssBox recentRightFloatBox = lay.LatestRightFloatBox; float availableWidth2 = myContainingBlock.GetClientWidth(); if (recentLeftFloatBox != null) { availableWidth2 -= recentLeftFloatBox.LocalVisualRight; } float sx = myContainingBlock.GetClientRight() - (box.VisualWidth + box.ActualMarginLeft + box.ActualMarginRight); //-------------------------------------------------------------------- float sy = 0; if (myContainingBlock.LineBoxCount > 0) { //line context sy = myContainingBlock.GetClientTop(); } else { var prevNode = box.GetPrevNode(); if (prevNode != null) { if (prevNode.Float != CssFloat.None) { //float left/right //TODO: review inherit here if (box.VisualWidth < availableWidth2) { sy = prevNode.LocalY; } else { sy = prevNode.LocalVisualBottom; } } else { sy = prevNode.LocalVisualBottom; } } else { sy = myContainingBlock.GetClientTop(); } } //-------------------------------------------------------------------- if (recentRightFloatBox != null) { availableWidth2 -= recentRightFloatBox.LocalX; sx = recentRightFloatBox.LocalX - box.VisualWidth; sy = recentRightFloatBox.LocalY; } if (box.VisualWidth > availableWidth2) { //start newline sx = myContainingBlock.GetClientRight() - (box.VisualWidth + box.ActualMarginLeft + box.ActualMarginRight); float sy1 = 0; float sy2 = 0; sy1 = sy2 = myContainingBlock.GetClientTop(); //if (recentLeftFloatBox != null) //{ // sy1 = recentLeftFloatBox.LocalY + recentLeftFloatBox.InnerContentHeight + // recentLeftFloatBox.ActualPaddingBottom + // recentLeftFloatBox.ActualMarginBottom; //} //if (recentRightFloatBox != null) //{ // sy2 = recentRightFloatBox.LocalY + recentRightFloatBox.InnerContentHeight + // recentRightFloatBox.ActualPaddingBottom + // recentRightFloatBox.ActualMarginBottom; //} if (recentLeftFloatBox != null) { sy1 = recentLeftFloatBox.LocalVisualBottom + recentLeftFloatBox.ActualMarginBottom; } if (recentRightFloatBox != null) { sy2 = recentRightFloatBox.LocalVisualBottom + recentRightFloatBox.ActualMarginBottom; } sy = (sy1 > sy2) ? sy1 : sy2; } sx += box.ActualMarginLeft; sy += box.ActualMarginTop; box.SetLocation(sx, sy); lay.AddFloatBox(box); } break; case CssFloat.None: default: { //review here for inherit property } break; } }
/// <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); } }