// // 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); } }
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); }
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; }
// // 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; }
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); }
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); }
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); }
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 } }
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."); }
public PDFLayoutPositionedRegionRun(PDFLayoutRegion region, PDFLayoutLine line, IPDFComponent owner) : base(line, owner) { this.Region = region; }
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); }