//
        // overflow operations
        //


        protected virtual void DoMoveToNextRegion(PDFUnit lineheight)
        {
            PDFLayoutLine lastline = this.CurrentLine;

            this.EndText(); //Always end this block of text

            bool             newPage;
            PDFLayoutRegion  region = lastline.Region;
            PDFLayoutBlock   block  = (PDFLayoutBlock)region.Parent;
            LayoutEngineBase engine = this.Parent as LayoutEngineBase;

            if (null == engine)
            {
                throw new NullReferenceException("Parent engine was not the expected BlockLayoutEngine. A Hack that is needed for overflowing textual content");
            }
            else if (engine.MoveToNextRegion(lineheight, ref region, ref block, out newPage))
            {
                if (!this.StartText())
                {
                    return;
                }
            }
            else
            {
                if (this.Context.TraceLog.ShouldLog(TraceLevel.Message))
                {
                    this.Context.TraceLog.Add(TraceLevel.Message, LOG_CATEGORY, "Cannot layout any more text for component '" + this.TextComponent.ID + "'. Available space full and cannot move to another region.");
                }

                this.ContinueLayout = false;
            }
        }
        /// <summary>
        /// Moves the entire list block to a new region or page in the layout
        /// </summary>
        /// <param name="requiredHeight"></param>
        /// <returns></returns>
        protected virtual bool MoveFullListToNextRegion(PDFUnit requiredHeight)
        {
            if (_didmovefulllist)
            {
                this.Context.TraceLog.Add(TraceLevel.Error, ListEngineLogCategory, "Already moved list to the next region so cannot move list '" + this.List.ID + "' to the next region");
                return(false);
            }


            PDFLayoutBlock  block  = this._listBlock;
            PDFLayoutRegion region = this._listBlock.CurrentRegion;
            bool            newPage;

            if (this.MoveToNextRegion(requiredHeight, ref region, ref block, out newPage))
            {
                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, ListEngineLogCategory, "Moved entire list '" + this.List.ID + "' to the next " + (newPage ? "Page" : "Region") + " and list block is now '" + block.ToString() + "'");
                }

                //If we have a new block then we set the old one as invisible
                if (block != _listBlock)
                {
                    _listBlock.Position.Visibility = Visibility.None;
                }

                _listBlock       = block;
                _didmovefulllist = true;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 3
0
        public virtual PDFLayoutPositionedRegionRun AddPositionedRun(PDFLayoutRegion postioned, IPDFComponent component)
        {
            PDFLayoutPositionedRegionRun run = new PDFLayoutPositionedRegionRun(postioned, this, component);

            this.Runs.Add(run);
            return(run);
        }
        //
        // overflow methods
        //

        #region protected virtual bool StartListInAnotherRegion(PDFUnit itemHeight, PDFLayoutBlock item, int itemindex)

        /// <summary>
        /// Closes down the current list and attempts to open a new region to start laying out any further items.
        /// Returns true if a new region was created, otherwise false.
        /// </summary>
        /// <param name="itemHeight"></param>
        /// <param name="item"></param>
        /// <param name="itemindex"></param>
        /// <returns></returns>
        protected virtual bool StartListInAnotherRegion(PDFUnit itemHeight, PDFLayoutBlock item, int itemindex)
        {
            PDFLayoutRegion itemRegion     = item.CurrentRegion;
            PDFLayoutBlock  origListBlock  = item.Parent as PDFLayoutBlock;
            PDFLayoutRegion origListRegion = origListBlock.CurrentRegion;

            if (origListBlock.IsClosed == false)
            {
                origListBlock.Close();
            }
            //(origListBlock.Parent as PDFLayoutBlock).CurrentRegion.AddToSize(origListBlock);

            bool newPage;
            bool started = this.MoveToNextRegion(itemHeight, ref itemRegion, ref item, out newPage);

            if (started)
            {
                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, ListEngineLogCategory, "Started list '" + this.List.ID + "' in a new " + (newPage ? "Page" : "Region") + " and list item block is now '" + item.ToString() + "'");
                }
            }

            return(started);
        }
Esempio n. 5
0
 public PDFLayoutXObject(PDFLayoutLine parent, PDFLayoutRegion childContainer, PDFPositionOptions position, IPDFComponent owner)
     : base(parent, owner as IPDFComponent)
 {
     this._childContainer = childContainer;
     this._resources      = new PDFResourceList(this, false);
     this.SubType         = "Form";
     this.Matrix          = PDFTransformationMatrix.Identity();
     this._position       = position;
 }
Esempio n. 6
0
        //
        // ctor(s)
        //

        #region public PDFLayoutLine(PDFLayoutRegion region, PDFUnit fullwidth)

        /// <summary>
        /// Creates a new line in the specified region.
        /// </summary>
        /// <param name="region">The region that contains this line</param>
        /// <param name="fullwidth">The full available horizontal space for this line </param>
        public PDFLayoutLine(PDFLayoutRegion region, PDFUnit fullwidth, HorizontalAlignment halign, VerticalAlignment valign, int lineindex)
            : base(region, null)
        {
            this.FullWidth      = fullwidth;
            this.HAlignment     = halign;
            this.VAlignment     = valign;
            this.LineIndex      = lineindex;
            this.BaseLineOffset = 0;
        }
        protected virtual void AddReturn(PDFUnit widthOfLastTextDraw, bool hardReturn)
        {
            this.AssertCurrentLine();
            PDFLayoutLine     line = this.CurrentLine;
            PDFTextRunNewLine br   = new PDFTextRunNewLine(false, line, this.TextRenderOptions, this.TextComponent);


            line.AddRun(br);

            //The offset is from the start of the last text drawing operation
            //and the offset of the start of the current line
            PDFUnit lineright = widthOfLastTextDraw;

            PDFUnit back = line.Width - lineright;

            //Previous - 27 Feb 2015
            //br.Offset = new PDFSize(back, line.Height);

            //Updated
            if (line.BaseLineOffset == 0 || this.TextRenderOptions.Leading.HasValue) //we don't have any begins or ends affecting the flow (or an explicit leading)
            {
                br.Offset = new PDFSize(back, line.Height);
            }
            else
            {
                br.Offset = new PDFSize(back, (line.Height - line.BaseLineOffset) + this.TextRenderOptions.GetAscent());
            }


            PDFLayoutRegion reg = line.Region;

            reg.CloseCurrentItem();
            line = reg.BeginNewLine();
            this.BeginningRun.Lines.Add(line);

            PDFUnit inset;

            if (hardReturn)
            {
                inset = this.TextRenderOptions.GetFirstLineInset();
            }
            else
            {
                inset = PDFUnit.Zero;
            }

            PDFTextRunSpacer spacer = this.AddLineInsetRun(inset, 0, line);

            br.NextLineSpacer     = spacer;
            this.CurrentLine      = line;
            this.CurrentLineInset = inset;
        }
Esempio n. 8
0
        private PDFLayoutInlineEnd CreateAndAddInlineEnd(PDFPositionOptions pos, PDFLayoutInlineBegin begin)
        {
            PDFLayoutBlock  containerBlock  = this.DocumentLayout.CurrentPage.LastOpenBlock();
            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            if (containerRegion.HasOpenItem == false)
            {
                containerRegion.BeginNewLine();
            }
            PDFLayoutLine      currline = containerRegion.CurrentItem as PDFLayoutLine;
            PDFLayoutInlineEnd end      = currline.AddInlineRunEnd(this, this.Component, begin, pos);

            return(end);
        }
Esempio n. 9
0
        private PDFLayoutInlineBegin CreateAndAddInlineBegin(PDFPositionOptions pos)
        {
            PDFLayoutBlock  containerBlock  = this.DocumentLayout.CurrentPage.LastOpenBlock();
            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            if (containerRegion.HasOpenItem == false)
            {
                containerRegion.BeginNewLine();
            }
            PDFLayoutLine        currline = containerRegion.CurrentItem as PDFLayoutLine;
            PDFLayoutInlineBegin begin    = currline.AddInlineRunStart(this, this.Component, pos, this.FullStyle);

            return(begin);
        }
Esempio n. 10
0
        private PDFLayoutXObject CreateAndAddInput(PDFPositionOptions pos)
        {
            PDFLayoutBlock  containerBlock  = this.DocumentLayout.CurrentPage.LastOpenBlock();
            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            if (containerRegion.HasOpenItem == false)
            {
                containerRegion.BeginNewLine();
            }
            //pos.Y = 200;
            PDFLayoutRegion container = containerBlock.BeginNewPositionedRegion(pos, this.DocumentLayout.CurrentPage, this.Component, this.FullStyle, false);

            this.Line = containerRegion.CurrentItem as PDFLayoutLine;
            PDFLayoutXObject begin = this.Line.AddXObjectRun(this, this.Field, container, pos, this.FullStyle);

            return(begin);
        }
        protected virtual PDFLayoutXObject ApplyViewPort(PDFPositionOptions oldpos, PDFRect viewPort)
        {
            //Set the size to the viewport size
            var newpos = oldpos.Clone();

            newpos.X = viewPort.X;
            newpos.Y = viewPort.Y;

            //update to new widths
            newpos.Width  = viewPort.Width;
            newpos.Height = viewPort.Height;

            //Set the style values to the viewport too. (and reset the cache)

            this.FullStyle.Size.Width  = newpos.Width.Value;
            this.FullStyle.Size.Height = newpos.Height.Value;

            if (this.FullStyle is Scryber.Styles.StyleFull)
            {
                (this.FullStyle as StyleFull).ClearFullRefs();
            }

            PDFLayoutBlock  containerBlock  = this.DocumentLayout.CurrentPage.LastOpenBlock();
            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            if (containerRegion.HasOpenItem == false)
            {
                containerRegion.BeginNewLine();
            }
            //pos.Y = 200;
            PDFLayoutRegion container = containerBlock.BeginNewPositionedRegion(newpos, this.DocumentLayout.CurrentPage, this.Component, this.FullStyle, false);

            this.Line = containerRegion.CurrentItem as PDFLayoutLine;



            PDFLayoutXObject begin = this.Line.AddXObjectRun(this, this.Component, container, newpos, this.FullStyle);

            begin.SetOutputSize(oldpos.Width, oldpos.Height);


            //this.CurrentBlock.IsFormXObject = true;
            //this.CurrentBlock.XObjectViewPort = pos.ViewPort.Value;

            return(begin);
        }
Esempio n. 12
0
        protected virtual PDFLayoutBlock CreateContinerBlock(PDFPositionOptions position)
        {
            bool            newPage         = false;
            PDFLayoutBlock  containerBlock  = this.DocumentLayout.CurrentPage.LastOpenBlock();
            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            if (containerRegion.HasOpenItem)
            {
                containerRegion.CloseCurrentItem();
            }

            PDFUnit required = PDFUnit.Zero;

            if (position.Height.HasValue)
            {
                required = position.Height.Value;
            }
            //ADDED for min/max sizes.
            else if (position.MinimumHeight.HasValue)
            {
                required = position.MinimumHeight.Value;
            }

            //Do we have space
            if (containerRegion.AvailableHeight <= 0 || (containerRegion.AvailableHeight < required))
            {
                if (this.MoveToNextRegion(required, ref containerRegion, ref containerBlock, out newPage) == false)
                {
                    this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "Cannot fit the block for component " + this.Component.UniqueID + " in the avilable height (required = '" + position.Height + "', available = '" + containerRegion.AvailableHeight + "'), and we cannot overflow to a new region. Layout of component stopped and returning.");
                    this.ContinueLayout = false;
                    return(null);
                }
            }

            CurrentBlock = containerBlock.BeginNewContainerBlock(this.Component, this, this.FullStyle, position.PositionMode);
            CurrentBlock.BlockRepeatIndex = 0;
            return(containerBlock);
        }
        /// <summary>
        /// If there is no open line at the start, or after a hard return, then this created a new one (adding inset as required)
        /// </summary>
        /// <returns></returns>
        private PDFLayoutLine EnsureFirstLineAvailable(out bool startedLine)
        {
            startedLine = false;
            PDFLayoutPage  pg    = this.Context.DocumentLayout.CurrentPage;
            PDFLayoutBlock block = pg.LastOpenBlock();

            if (null == block || block.IsClosed)
            {
                this.Context.TraceLog.Add(TraceLevel.Error, LOG_CATEGORY, "There is no open block on page '" + pg.ToString() + "' to add content to.");
                return(null);

                throw new InvalidOperationException("There is no open block to add the textual content to.");
            }
            PDFLayoutRegion reg = block.CurrentRegion;

            if (null == reg || reg.IsClosed)
            {
                this.Context.TraceLog.Add(TraceLevel.Error, LOG_CATEGORY, "There is no open region in block '" + block.ToString() + "' on page '" + pg.ToString() + "' to add content to.");
                return(null);

                throw new InvalidOperationException("There is no open block to add the textual content to.");
            }
            PDFLayoutLine line;

            if (reg.HasOpenItem)
            {
                line = (PDFLayoutLine)reg.CurrentItem;
            }
            else
            {
                line        = reg.BeginNewLine();
                startedLine = true;
                //No Inset spacer as this will be handled by the begin run
            }

            return(line);
        }
        /// <summary>
        /// Add characters to the line(s), and returns the last width of the characters that were laid out.
        /// </summary>
        protected virtual PDFUnit AddProxyCharacters(PDFTextProxyOp proxy)
        {
            this.AssertCurrentLine();


            PDFUnit         lineheight = this.TextRenderOptions.GetLineHeight();
            ZeroLineCounter zeros      = new ZeroLineCounter();

            PDFSize measured = PDFSize.Empty;
            PDFSize required = PDFSize.Empty;

            PDFLayoutLine   line = this.CurrentLine;
            PDFLayoutRegion reg  = line.Region;

            PDFUnit availH = reg.AvailableHeight;
            PDFUnit availW = line.AvailableWidth;


            if (availH < lineheight)
            {
                if (this.Position.OverflowAction != OverflowAction.Clip)
                {
                    availH = lineheight;
                }
                else
                {
                    this.DoMoveToNextRegion(lineheight);

                    if (!this.ContinueLayout)
                    {
                        return(PDFUnit.Zero);
                    }
                }
            }

            //Measure the string an get the fitted characters

            int fitted;

            this.Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Measure);

            measured = this.MeasureString(availH, availW, proxy.Text, 0, out fitted);

            this.Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Measure);

            required = new PDFSize(measured.Width, lineheight);

            if (fitted < proxy.Text.Length) //cannot split a proxy - must simply be a single run.
            {
                //try on the next line to see if we can put everything on there.
                this.AddSoftReturn(0);

                if (!zeros.AssertIncrement(this.Context))
                {
                    return(PDFUnit.Zero);
                }

                availW = this.CurrentLine.AvailableWidth;

                this.Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Measure);

                measured = this.MeasureString(availH, availW, proxy.Text, 0, out fitted);

                this.Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Measure);

                if (fitted < proxy.Text.Length) //Still cannot fit the proxy so not much we can do. Log it and return
                {
                    this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "The text proxy  for '" + proxy.Text + "' could not fit the characters on a single line. Overflow of proxies is not currently supported.");
                    return(measured.Width);
                }

                required = new PDFSize(measured.Width, lineheight);
            }

            // everything fitted on the line

            zeros.Reset();
            this.AddProxyToCurrentLine(required, proxy);


            return(required.Width);
        }
        /// <summary>
        /// Lays out a single list item based on the entry, and the list position options
        /// </summary>
        /// <param name="index"></param>
        /// <param name="entry"></param>
        /// <param name="listPosOpts"></param>
        /// <returns></returns>
        private PDFUnit LayoutAnItem(int index, ListNumberEntry entry, PDFPositionOptions listPosOpts)
        {
            //restore the items applied style onto the stack
            this.StyleStack.Push(entry.AppliedStyle);

            Style   full        = entry.FullStyle;
            PDFUnit numberWidth = entry.NumberWidth;



            PDFArtefactRegistrationSet artefacts = entry.ListItem.RegisterLayoutArtefacts(this.Context, full);

            PDFPositionOptions itemopts = full.CreatePostionOptions();

            PDFUnit pageHeight = this.Context.DocumentLayout.CurrentPage.Height;
            PDFUnit h          = pageHeight;
            PDFUnit w          = _listBlock.AvailableBounds.Width;
            PDFUnit y          = _itemoffset;

            PDFUnit alley = DefaultListItemAlley;

            if (itemopts.HasAlleyWidth)
            {
                alley = itemopts.AlleyWidth;
            }
            else if (listPosOpts.HasAlleyWidth)
            {
                alley = listPosOpts.AlleyWidth;
            }

            if (itemopts.Height.HasValue)
            {
                h = itemopts.Height.Value;
            }
            else if (itemopts.Margins.IsEmpty == false)
            {
                h -= itemopts.Margins.Top + itemopts.Margins.Bottom;
            }
            h -= itemopts.Padding.Top + itemopts.Padding.Bottom;

            if (itemopts.Width.HasValue)
            {
                w = itemopts.Width.Value;
            }

            else if (itemopts.Margins.IsEmpty == false)
            {
                w -= itemopts.Margins.Left + itemopts.Margins.Right;
            }
            w -= itemopts.Padding.Left + itemopts.Padding.Right;

            PDFRect totalBounds = new PDFRect(PDFUnit.Zero, y, w, h);

            this._itemblock = _listBlock.BeginNewContainerBlock(entry.ListItem, this, full, itemopts.PositionMode);

            PDFColumnOptions colOpts = new PDFColumnOptions()
            {
                AlleyWidth = alley, AutoFlow = false, ColumnCount = 2
            };

            this._itemblock.InitRegions(totalBounds, itemopts, colOpts, this.Context);

            //Alter the widths of the regions to allow for only the number width

            PDFRect region1bounds = this._itemblock.Columns[0].TotalBounds;
            PDFUnit difference    = region1bounds.Width - numberWidth;

            region1bounds.Width = numberWidth;
            this._itemblock.Columns[0].TotalBounds = region1bounds;
            this._itemblock.Columns[0].HAlignment  = entry.NumberAlignment;

            PDFRect region2Bounds = this._itemblock.Columns[1].TotalBounds;

            if (region2Bounds.X > 0)
            {
                region2Bounds.X -= difference;
            }
            region2Bounds.Width += difference;
            this._itemblock.Columns[1].TotalBounds = region2Bounds;

            PDFUnit numberHeight = this.LayoutItemNumber(entry, full);

            this._itemblock.CurrentRegion.Close();

            bool    success       = this._itemblock.MoveToNextRegion(true, PDFUnit.Zero, this.Context); //Pass Zero as we are not interested in overflowing yet
            PDFUnit contentHeight = this.LayoutItemContent(entry);

            //check that we can fit - addind the margins and padding back in.
            PDFUnit itemHeight = PDFUnit.Max(numberHeight, contentHeight);

            if (itemopts.Height.HasValue)
            {
                itemHeight = itemopts.Height.Value;
            }
            else if (itemopts.Margins.IsEmpty == false)
            {
                itemHeight += itemopts.Margins.Top + itemopts.Margins.Bottom;
            }
            itemHeight += itemopts.Padding.Top + itemopts.Padding.Bottom;

            if (itemHeight > this._listBlock.AvailableBounds.Height - _itemoffset)
            {
                PDFLayoutBlock  origparent = this.CurrentBlock;
                PDFLayoutRegion origregion = this.CurrentBlock.CurrentRegion;
                PDFLayoutBlock  origlist   = this._listBlock;
                PDFLayoutBlock  origItem   = this._itemblock;

                if (this._listBlock.Position.OverflowSplit == OverflowSplit.Never)
                {
                    if (this.MoveFullListToNextRegion(_itemoffset + itemHeight))
                    {
                        //_itemoffset += itemHeight;
                        //PDFRect avail = _listBlock.AvailableBounds;
                        //avail.Height = avail.Height - _itemoffset;
                    }
                    else
                    {
                        this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "List '" + this.List.UniqueID + "' has filled the available space, and cannot overflow onto a new region. Layout has stopped at item index " + index);
                        this.ContinueLayout = false;
                        return(0);
                    }
                }
                else if (this.StartListInAnotherRegion(itemHeight, origItem, index))
                {
                    //origregion.AddToSize(origlist);
                    _itemoffset = 0;
                    origItem.Offset(0, 0);
                }
                else
                {
                    (origItem.Parent as PDFLayoutBlock).CurrentRegion.RemoveItem(origItem);
                    this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "List '" + this.List.UniqueID + "' has filled the available space, and cannot overflow onto a new region. Layout has stopped at item index " + index);

                    this.ContinueLayout = false;
                }
            }
            else if (this._itemblock.CurrentRegion.IsClosed)
            {
                this._itemblock = this.CurrentBlock.LastOpenBlock();
                this._listBlock = this._itemblock.Parent as PDFLayoutBlock;
            }

            if (null != this._itemblock)
            {
                if (this._itemblock.CurrentRegion.IsClosed == false)
                {
                    this._itemblock.CurrentRegion.Close();
                }

                if (this._itemblock.IsClosed == false)
                {
                    this._itemblock.Close();
                    this._listBlock.CurrentRegion.AddToSize(this._itemblock);
                }
            }

            if (this.ContinueLayout)
            {
                RegisterChildLayout(entry.ListItem);
            }

            if (null != artefacts)
            {
                entry.ListItem.CloseLayoutArtefacts(this.Context, artefacts, full);
            }

            this.StyleStack.Pop();

            return(itemHeight);
        }
        /// <summary>
        /// Checks the overflow style and if new pages are supported closes the current page layout and
        /// creates a new page layout (becomming the current page) and returns true.
        /// If overflow is not supported - returns false
        /// </summary>
        /// <param name="region">If there is a change in current page, this is set to the new region</param>
        /// <param name="block">If there is a change in current page, this is set to the new block</param>
        /// <returns></returns>
        public override bool MoveToNextPage(IPDFComponent initiator, Style initiatorStyle, Stack <PDFLayoutBlock> depth, ref PDFLayoutRegion region, ref PDFLayoutBlock block)
        {
            StyleValue <OverflowAction> action;

            if (this.FullStyle.TryGetValue(StyleKeys.OverflowActionKey, out action) && action.Value == OverflowAction.NewPage)
            {
                PDFLayoutPage  lastpage = this.DocumentLayout.CurrentPage;
                PDFLayoutBlock open     = lastpage.ContentBlock;
                if (open.IsClosed)
                {
                    open = null;
                }
                else
                {
                    open = open.LastOpenBlock();
                }

                List <PDFLayoutBlock> toclose = new List <PDFLayoutBlock>(depth);

                for (int i = toclose.Count - 1; i >= 0; i--)
                {
                    open = toclose[i];
                    if (open.CurrentRegion != null && open.CurrentRegion.IsClosed == false)
                    {
                        PDFLayoutRegion openRegion = open.CurrentRegion;
                        openRegion.Close();
                    }

                    PDFLayoutBlock parent = open.Parent as PDFLayoutBlock;
                    if (null != parent)
                    {
                        PDFLayoutRegion parentRegion = parent.CurrentRegion;
                        if (null != parentRegion)
                        {
                            open.Close();
                            parentRegion.AddToSize(open);
                        }
                    }

                    //open = parent;
                }
                lastpage.Close();
                var           pgSize = this.GetNextPageSize(initiator, initiatorStyle, lastpage.Size);
                PDFLayoutPage page   = BuildContinuationPage(lastpage, pgSize);

                block  = page.CurrentBlock;
                region = block.CurrentRegion;

                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, LOG_CATEGORY, "Built a new continuation page for " + this.Component + " and recreated the " + toclose.Count + " blocks and regions on the new page");
                }
                return(true);
            }
            else
            {
                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, LOG_CATEGORY, "Cannot overflow content for page " + this.Component + " halting the continued layout by returning false");
                }

                return(false); //Cannot overflow
            }
        }
Esempio n. 17
0
        public PDFLayoutXObject AddXObjectRun(IPDFLayoutEngine engine, IPDFComponent component, PDFLayoutRegion container, PDFPositionOptions options, Style full)
        {
            PDFLayoutXObject xobject = new PDFLayoutXObject(this, container, options, component);

            this.Runs.Add(xobject);
            return(xobject);
        }
 public bool MoveToNextPage(IPDFComponent initiator, Style initiatorStyle, Stack <PDFLayoutBlock> depth, ref PDFLayoutRegion region, ref PDFLayoutBlock block)
 {
     throw new NotSupportedException("TextLayoutEngine should never be the top layout engine - and therefore should never control pages");
 }
 public PDFLayoutBlock CloseCurrentBlockAndStartNewInRegion(PDFLayoutBlock blockToClose, PDFLayoutRegion joinToRegion)
 {
     throw new NotSupportedException("CloseCurrentBlockAndStartNewInRegion should never be called on the text layout engine.");
 }
Esempio n. 20
0
 public PDFLayoutPositionedRegionRun(PDFLayoutRegion region, PDFLayoutLine line, IPDFComponent owner)
     : base(line, owner)
 {
     this.Region = region;
 }
Esempio n. 21
0
        protected void EnsureContentsFit()
        {
            bool           newPage;
            PDFLayoutBlock block = this.CurrentBlock;
            //re-retrieve our container block and region
            //it could have changed whilst laying out other regions / pages.
            PDFLayoutBlock containerBlock = block.Parent as PDFLayoutBlock;

            if (block.IsClosed == false)
            {
                block.Close();
            }

            bool    updateSize = false;
            PDFSize updated    = block.Size;



            if (block.Position.MinimumHeight.HasValue && block.Height < block.Position.MinimumHeight.Value)
            {
                updated.Height = block.Position.MinimumHeight.Value - (block.Position.Padding.Top + block.Position.Padding.Bottom);
                updateSize     = true;
            }

            if (block.Position.MinimumWidth.HasValue && block.Width < block.Position.MinimumWidth.Value)
            {
                updated.Width = block.Position.MinimumWidth.Value - (block.Position.Padding.Left + block.Position.Padding.Right);
                updateSize    = true;
            }



            if (updateSize)
            {
                block.SetContentSize(updated.Width, updated.Height);
            }



            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            //ADDED to support blocks flowing to the next region or page
            PDFUnit vspace = containerRegion.TotalBounds.Height - containerRegion.UsedSize.Height;
            PDFUnit req    = block.Height;



            bool canfitvertical = req <= vspace;


            if (!canfitvertical && containerRegion.Contents.Count > 1)
            {
                PDFLayoutRegion prev = containerRegion;
                if (this.MoveToNextRegion(req, ref containerRegion, ref containerBlock, out newPage))
                {
                    prev.Contents.Remove(block);
                    containerRegion.AddExistingItem(block);
                }
                else
                {
                    this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "Cannot fit the block for component " + this.Component.UniqueID + " in the avilable height (required = '" + req + "', available = '" + vspace + "'), and we cannot overflow to a new region. Layout of component stopped and returning.");

                    this.ContinueLayout = false;
                }
            }
            else
            {
                //Region has not updated its size as the block was directly closed.
                containerRegion.AddToSize(block);
            }
        }
        /// <summary>
        /// Overrides the base method to close the current list block, and set up a new block in the provided region.
        /// Updates the references in this engine.
        /// </summary>
        /// <param name="blockToClose"></param>
        /// <param name="joinToRegion"></param>
        /// <returns></returns>
        public override PDFLayoutBlock CloseCurrentBlockAndStartNewInRegion(PDFLayoutBlock blockToClose, PDFLayoutRegion joinToRegion)
        {
            PDFLayoutBlock orig  = this.CurrentBlock;
            PDFRect        avail = this._listBlock.AvailableBounds;

            avail.Height = joinToRegion.AvailableHeight;
            PDFThickness margins = _listBlock.Position.Margins;

            PDFLayoutBlock newList = base.CloseCurrentBlockAndStartNewInRegion(blockToClose, joinToRegion);

            this.CurrentBlock = (PDFLayoutBlock)newList.Parent;

            this._listBlock = newList;
            avail.Y         = 0;

            avail.Width  -= margins.Left + margins.Right;
            avail.Height -= margins.Top + margins.Bottom;
            avail.X      += margins.Left;
            avail.Y      += margins.Top;

            this._listBlock.AvailableBounds = avail;
            this._itemoffset = 0;

            return(newList);
        }
        /// <summary>
        /// Add characters to the line(s), and returns the last width of the characters that were laid out.
        /// </summary>
        protected virtual PDFUnit AddCharacters(string chars)
        {
            this.AssertCurrentLine();


            PDFUnit         lineheight = this.TextRenderOptions.GetLineHeight();
            int             offset     = 0;
            ZeroLineCounter zeros      = new ZeroLineCounter();

            PDFSize measured = PDFSize.Empty;
            PDFSize required = PDFSize.Empty;

            while (offset < chars.Length)
            {
                //Check that we have enough space for the next line

                PDFLayoutLine   line   = this.CurrentLine;
                PDFLayoutRegion reg    = line.Region;
                PDFUnit         availH = reg.AvailableHeight;
                PDFUnit         availW = line.AvailableWidth;

                if (availH < lineheight)
                {
                    if (this.Position.OverflowAction != OverflowAction.Clip)
                    {
                        this.DoMoveToNextRegion(lineheight);

                        if (!this.ContinueLayout)
                        {
                            return(PDFUnit.Zero);
                        }
                        else
                        {
                            line   = this.CurrentLine;
                            reg    = line.Region;
                            availW = line.AvailableWidth;
                            availH = reg.AvailableHeight;
                        }
                    }
                    else
                    {
                        availH = lineheight;
                    }
                }

                //Measure the string an get the fitted characters

                Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Measure);

                int fitted;
                measured = this.MeasureString(availH, availW, chars, offset, out fitted);

                Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Measure);

                required = new PDFSize(measured.Width, lineheight);

                if (fitted <= 0) //nothing fitted on the line
                {
                    this.AddSoftReturn(0);
                    if (!zeros.AssertIncrement(this.Context))
                    {
                        return(PDFUnit.Zero);
                    }
                }
                else if (fitted + offset == chars.Length) // everything fitted on the line
                {
                    zeros.Reset();
                    string all = chars.Substring(offset);
                    //if (offset == 0)
                    this.AddCharactersToCurrentLine(required, all);
                    //else
                    //    this.AddCharactersToCurrentLine(required, chars, offset, fitted);
                    offset += fitted;
                }
                else if (IsBrokenInWord(chars, offset, fitted) && CanSplitOnWordsOnly() && !IsEmptyLine()) //don't break on words unless we have to.
                {
                    this.AddSoftReturn(0);
                    if (!zeros.AssertIncrement(this.Context))
                    {
                        return(PDFUnit.Zero);
                    }
                }
                else //partial fit
                {
                    zeros.Reset();

                    string partial = chars.Substring(offset, fitted);
                    this.AddCharactersToCurrentLine(required, partial);
                    //this.AddCharactersToCurrentLine(required, chars, offset, fitted);
                    this.AddSoftReturn(measured.Width);
                    offset += fitted;

                    //Consume any white space as we are now on a new line.
                    //We should never get here for NoWrap as it will alywys fit all characters one one line.
                    while (offset < chars.Length && char.IsWhiteSpace(chars, offset))
                    {
                        offset++;
                    }
                }
            }
            return(required.Width);
        }