protected int GoComposite(bool simulate) { if (!rectangularMode) throw new DocumentException(MessageLocalization.GetComposedMessage("irregular.columns.are.not.supported.in.composite.mode")); linesWritten = 0; descender = 0; bool firstPass = true; main_loop: while (true) { if (compositeElements.Count == 0) return NO_MORE_TEXT; IElement element = compositeElements[0]; if (element.Type == Element.PARAGRAPH) { Paragraph para = (Paragraph)element; int status = 0; for (int keep = 0; keep < 2; ++keep) { float lastY = yLine; bool createHere = false; if (compositeColumn == null) { compositeColumn = new ColumnText(canvas); compositeColumn.Alignment = para.Alignment; compositeColumn.SetIndent(para.IndentationLeft + para.FirstLineIndent, false); compositeColumn.ExtraParagraphSpace = para.ExtraParagraphSpace; compositeColumn.FollowingIndent = para.IndentationLeft; compositeColumn.RightIndent = para.IndentationRight; compositeColumn.SetLeading(para.Leading, para.MultipliedLeading); compositeColumn.RunDirection = runDirection; compositeColumn.ArabicOptions = arabicOptions; compositeColumn.SpaceCharRatio = spaceCharRatio; compositeColumn.AddText(para); if (!(firstPass && adjustFirstLine)) { yLine -= para.SpacingBefore; } createHere = true; } compositeColumn.UseAscender = ((firstPass || descender == 0) && adjustFirstLine ? useAscender : false); compositeColumn.leftX = leftX; compositeColumn.rightX = rightX; compositeColumn.yLine = yLine; compositeColumn.rectangularWidth = rectangularWidth; compositeColumn.rectangularMode = rectangularMode; compositeColumn.minY = minY; compositeColumn.maxY = maxY; bool keepCandidate = (para.KeepTogether && createHere && !(firstPass && adjustFirstLine)); status = compositeColumn.Go(simulate || (keepCandidate && keep == 0)); lastX = compositeColumn.LastX; UpdateFilledWidth(compositeColumn.filledWidth); if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { compositeColumn = null; yLine = lastY; return NO_MORE_COLUMN; } if (simulate || !keepCandidate) break; if (keep == 0) { compositeColumn = null; yLine = lastY; } } firstPass = false; if (compositeColumn.linesWritten > 0) { yLine = compositeColumn.yLine; linesWritten += compositeColumn.linesWritten; descender = compositeColumn.descender; } currentLeading = compositeColumn.currentLeading; if ((status & NO_MORE_TEXT) != 0) { compositeColumn = null; compositeElements.RemoveAt(0); yLine -= para.SpacingAfter; } if ((status & NO_MORE_COLUMN) != 0) { return NO_MORE_COLUMN; } } else if (element.Type == Element.LIST) { List list = (List)element; List<IElement> items = list.Items; ListItem item = null; float listIndentation = list.IndentationLeft; int count = 0; Stack<Object[]> stack = new Stack<Object[]>(); for (int k = 0; k < items.Count; ++k) { Object obj = items[k]; if (obj is ListItem) { if (count == listIdx) { item = (ListItem)obj; break; } else ++count; } else if (obj is List) { stack.Push(new Object[]{list, k, listIndentation}); list = (List)obj; items = list.Items; listIndentation += list.IndentationLeft; k = -1; continue; } if (k == items.Count - 1) { if (stack.Count > 0) { Object[] objs = stack.Pop(); list = (List)objs[0]; items = list.Items; k = (int)objs[1]; listIndentation = (float)objs[2]; } } } int status = 0; for (int keep = 0; keep < 2; ++keep) { float lastY = yLine; bool createHere = false; if (compositeColumn == null) { if (item == null) { listIdx = 0; compositeElements.RemoveAt(0); goto main_loop; } compositeColumn = new ColumnText(canvas); compositeColumn.UseAscender = ((firstPass || descender == 0) && adjustFirstLine ? useAscender : false); compositeColumn.Alignment = item.Alignment; compositeColumn.SetIndent(item.IndentationLeft + listIndentation + item.FirstLineIndent, false); compositeColumn.ExtraParagraphSpace = item.ExtraParagraphSpace; compositeColumn.FollowingIndent = compositeColumn.Indent; compositeColumn.RightIndent = item.IndentationRight + list.IndentationRight; compositeColumn.SetLeading(item.Leading, item.MultipliedLeading); compositeColumn.RunDirection = runDirection; compositeColumn.ArabicOptions = arabicOptions; compositeColumn.SpaceCharRatio = spaceCharRatio; compositeColumn.AddText(item); if (!(firstPass && adjustFirstLine)) { yLine -= item.SpacingBefore; } createHere = true; } compositeColumn.leftX = leftX; compositeColumn.rightX = rightX; compositeColumn.yLine = yLine; compositeColumn.rectangularWidth = rectangularWidth; compositeColumn.rectangularMode = rectangularMode; compositeColumn.minY = minY; compositeColumn.maxY = maxY; bool keepCandidate = (item.KeepTogether && createHere && !(firstPass && adjustFirstLine)); status = compositeColumn.Go(simulate || (keepCandidate && keep == 0)); lastX = compositeColumn.LastX; UpdateFilledWidth(compositeColumn.filledWidth); if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { compositeColumn = null; yLine = lastY; return NO_MORE_COLUMN; } if (simulate || !keepCandidate) break; if (keep == 0) { compositeColumn = null; yLine = lastY; } } firstPass = false; yLine = compositeColumn.yLine; linesWritten += compositeColumn.linesWritten; descender = compositeColumn.descender; currentLeading = compositeColumn.currentLeading; if (!float.IsNaN(compositeColumn.firstLineY) && !compositeColumn.firstLineYDone) { if (!simulate) ShowTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(item.ListSymbol), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0); compositeColumn.firstLineYDone = true; } if ((status & NO_MORE_TEXT) != 0) { compositeColumn = null; ++listIdx; yLine -= item.SpacingAfter; } if ((status & NO_MORE_COLUMN) != 0) { return NO_MORE_COLUMN; } } else if (element.Type == Element.PTABLE) { // INITIALISATIONS // get the PdfPTable element PdfPTable table = (PdfPTable)element; // tables without a body are dismissed if (table.Size <= table.HeaderRows) { compositeElements.RemoveAt(0); continue; } // Y-offset float yTemp = yLine; yTemp += descender; if (rowIdx == 0 && adjustFirstLine) yTemp -= table.SpacingBefore; // if there's no space left, ask for new column if (yTemp < minY || yTemp > maxY) { return NO_MORE_COLUMN; } // coordinates float yLineWrite = yTemp; float x1 = leftX; currentLeading = 0; // get the width of the table float tableWidth; if (table.LockedWidth) { tableWidth = table.TotalWidth; UpdateFilledWidth(tableWidth); } else { tableWidth = rectangularWidth * table.WidthPercentage / 100f; table.TotalWidth = tableWidth; } // HEADERS / FOOTERS // how many header rows are real header rows; how many are footer rows? table.NormalizeHeadersFooters(); int headerRows = table.HeaderRows; int footerRows = table.FooterRows; int realHeaderRows = headerRows - footerRows; float headerHeight = table.HeaderHeight; float footerHeight = table.FooterHeight; // do we need to skip the header? bool skipHeader = table.SkipFirstHeader && rowIdx <= realHeaderRows; // if not, we wan't to be able to add more than just a header and a footer if (!skipHeader) { yTemp -= headerHeight; if (yTemp < minY || yTemp > maxY) { return NO_MORE_COLUMN; } } // MEASURE NECESSARY SPACE // how many real rows (not header or footer rows) fit on a page? int k = 0; if (rowIdx < headerRows) rowIdx = headerRows; // if the table isn't complete, we need to be able to add a footer if (!table.ElementComplete) { yTemp -= footerHeight; } // k will be the first row that doesn't fit for (k = rowIdx; k < table.Size; ++k) { float rowHeight = table.GetRowHeight(k); if (yTemp - rowHeight < minY) break; yTemp -= rowHeight; } // only for incomplete tables: if (!table.ElementComplete) { yTemp += footerHeight; } // IF ROWS MAY NOT BE SPLIT if (!table.SplitRows) { splittedRow = -1; if (k == rowIdx) { // drop the whole table if (k == table.Size) { compositeElements.RemoveAt(0); continue; } // or drop the row else { table.Rows.RemoveAt(k); return NO_MORE_COLUMN; } } } // IF ROWS SHOULD NOT BE SPLIT else if (table.SplitLate && !table.HasRowspan(k) && rowIdx < k) { splittedRow = -1; } // SPLIT ROWS (IF WANTED AND NECESSARY) else if (k < table.Size) { // if the row hasn't been split before, we duplicate (part of) the table if (k != splittedRow) { splittedRow = k + 1; table = new PdfPTable(table); compositeElements[0] = table; List<PdfPRow> rows = table.Rows; for (int i = headerRows; i < rowIdx; ++i) rows[i] = null; } // we calculate the remaining vertical space float h = yTemp - minY; // we create a new row with the remaining content PdfPRow newRow = table.GetRow(k).SplitRow(table, k, h); // if the row isn't null add it as an extra row if (newRow == null) { splittedRow = -1; if (rowIdx == k) return NO_MORE_COLUMN; } else { yTemp = minY; table.Rows.Insert(++k, newRow); } } // We're no longer in the first pass firstPass = false; // if not in simulation mode, draw the table if (!simulate) { // set the alignment switch (table.HorizontalAlignment) { case Element.ALIGN_LEFT: break; case Element.ALIGN_RIGHT: x1 += rectangularWidth - tableWidth; break; default: x1 += (rectangularWidth - tableWidth) / 2f; break; } // copy the rows that fit on the page in a new table nt PdfPTable nt = PdfPTable.ShallowCopy(table); List<PdfPRow> sub = nt.Rows; // first we add the real header rows (if necessary) if (!skipHeader && realHeaderRows > 0) { sub.AddRange(table.GetRows(0, realHeaderRows)); } else { nt.HeaderRows = footerRows; } // then we add the real content sub.AddRange(table.GetRows(rowIdx, k)); // do we need to show a footer? bool showFooter = !table.SkipLastFooter; bool newPageFollows = false; if (k < table.Size) { nt.ElementComplete = true; showFooter = true; newPageFollows = true; } // we add the footer rows if necessary (not for incomplete tables) if (footerRows > 0 && nt.ElementComplete && showFooter) { sub.AddRange(table.GetRows(realHeaderRows, realHeaderRows + footerRows)); } else { footerRows = 0; } // we need a correction if the last row needs to be extended float rowHeight = 0; int lastIdx = sub.Count - 1 - footerRows; PdfPRow last = sub[lastIdx]; if (table.IsExtendLastRow(newPageFollows)) { rowHeight = last.MaxHeights; last.MaxHeights = yTemp - minY + rowHeight; yTemp = minY; } // newPageFollows indicates that this table is being split if (newPageFollows) { IPdfPTableEvent tableEvent = table.TableEvent; if (tableEvent is IPdfPTableEventSplit) { ((IPdfPTableEventSplit)tableEvent).SplitTable(table); } } // now we render the rows of the new table if (canvases != null) nt.WriteSelectedRows(0, -1, 0, -1, x1, yLineWrite, canvases, false); else nt.WriteSelectedRows(0, -1, 0, -1, x1, yLineWrite, canvas, false); // if the row was split, we copy the content of the last row // that was consumed into the first row shown on the next page if (splittedRow == k && k < table.Size) { PdfPRow splitted = table.Rows[k]; splitted.CopyRowContent(nt, lastIdx); } // reset the row height of the last row if (table.IsExtendLastRow(newPageFollows)) { last.MaxHeights = rowHeight; } } // in simulation mode, we need to take extendLastRow into account else if (table.ExtendLastRow && minY > PdfPRow.BOTTOM_LIMIT) { yTemp = minY; } yLine = yTemp; descender = 0; currentLeading = 0; if (!(skipHeader || table.ElementComplete)) { yLine += footerHeight; } if (k >= table.Size) { // Use up space no more than left if (yLine - table.SpacingAfter < minY) { yLine = minY; } else { yLine -= table.SpacingAfter; } compositeElements.RemoveAt(0); splittedRow = -1; rowIdx = 0; } else { if (splittedRow != -1) { List<PdfPRow> rows = table.Rows; for (int i = rowIdx; i < k; ++i) rows[i] = null; } rowIdx = k; return NO_MORE_COLUMN; } } else if (element.Type == Element.YMARK) { if (!simulate) { IDrawInterface zh = (IDrawInterface)element; zh.Draw(canvas, leftX, minY, rightX, maxY, yLine); } compositeElements.RemoveAt(0); } else if (element.Type == Element.DIV) { List<IElement> floatingElements = new List<IElement>(); do { floatingElements.Add(element); compositeElements.RemoveAt(0); element = compositeElements.Count > 0 ? compositeElements[0] : null; } while (element != null && element.Type == Element.DIV); compositeColumn = new ColumnText(canvas); compositeColumn.UseAscender = (firstPass || descender == 0) && adjustFirstLine ? useAscender : false; //compositeColumn.setAlignment(div.getTextAlignment()); //compositeColumn.setIndent(para.getIndentationLeft() + para.getFirstLineIndent()); compositeColumn.RunDirection = runDirection; compositeColumn.ArabicOptions = arabicOptions; compositeColumn.SpaceCharRatio = spaceCharRatio; FloatLayout fl = new FloatLayout(compositeColumn, floatingElements); fl.SetSimpleColumn(leftX, minY, rightX, yLine); int status = fl.layout(simulate); //firstPass = false; yLine = fl.getYLine(); descender = 0; compositeColumn = null; if ((status & NO_MORE_TEXT) == 0) { foreach (IElement floatingElement in floatingElements) { compositeElements.Add(floatingElement); } return status; } } else compositeElements.RemoveAt(0); } }
internal void FlushFloatingElements() { if (floatingElements != null && floatingElements.Count > 0) { List<IElement> cachedFloatingElements = floatingElements; floatingElements = null; FloatLayout fl = new FloatLayout(cachedFloatingElements, false); int loop = 0; while (true) { fl.SetSimpleColumn(IndentLeft, IndentBottom, IndentRight, IndentTop - currentHeight); try { int status = fl.Layout(IsTagged(writer) ? text : writer.DirectContent, false); if ((status & ColumnText.NO_MORE_TEXT) != 0) { if (IsTagged(writer)) text.SetTextMatrix(IndentLeft, fl.YLine); else text.MoveText(0, fl.YLine - IndentTop + currentHeight); currentHeight = IndentTop - fl.YLine; break; } } catch(Exception) { return; } if (IndentTop - currentHeight == fl.YLine || PageEmpty) ++loop; else { loop = 0; } if (loop == 2) { return; } NewPage(); } } }
internal void FlushFloatingElements() { if (floatingElements != null && floatingElements.Count > 0) { List<IElement> cashedFloatingElements = floatingElements; floatingElements = null; FloatLayout fl = new FloatLayout(writer.DirectContent, cashedFloatingElements); fl.SetSimpleColumn(IndentLeft, IndentBottom, IndentRight, IndentTop - currentHeight); int status = fl.layout(false); //if ((status & ColumnText.NO_MORE_TEXT) != 0) { text.MoveText(0, fl.getYLine() - IndentTop + currentHeight); currentHeight = IndentTop - fl.getYLine(); //} } }
public int layout(ColumnText compositeColumn, bool simulate, float llx, float lly, float urx, float ury) { float leftX = Math.Min(llx, urx); float maxY = Math.Max(lly, ury); float minY = Math.Min(lly, ury); float rightX = Math.Max(llx, urx); float yLine = maxY; if (width != null && width > 0) { if (width < rightX - leftX) { rightX = leftX + (float)width; } else if (width > rightX - leftX) { return(ColumnText.NO_MORE_COLUMN); } } else if (percentageWidth != null) { contentWidth = (rightX - leftX) * (float)percentageWidth; rightX = leftX + contentWidth; } if (height != null && height > 0) { if (height < maxY - minY) { minY = maxY - (float)height; } else if (height > maxY - minY) { return(ColumnText.NO_MORE_COLUMN); } } else if (percentageHeight != null) { contentHeight = (maxY - minY) * (float)percentageHeight; minY = maxY - contentHeight; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { float?translationX = null; if (left != null) { translationX = left; } else if (right != null) { translationX = -right; } else { translationX = 0f; } float?translationY = null; if (top != null) { translationY = -top; } else if (bottom != null) { translationY = bottom; } else { translationY = 0f; } compositeColumn.Canvas.SaveState(); compositeColumn.Canvas.Transform(new System.Drawing.Drawing2D.Matrix(1f, 0, 0, 1f, (float)translationX, (float)translationY)); } if (!simulate) { if (backgroundColor != null && getActualWidth() > 0 && getActualHeight() > 0) { float backgroundWidth = getActualWidth(); float backgroundHeight = getActualHeight(); if (width != null) { backgroundWidth = width > 0 ? (float)width : 0; } if (height != null) { backgroundHeight = height > 0 ? (float)height : 0; } if (backgroundWidth > 0 && backgroundHeight > 0) { Rectangle background = new Rectangle(leftX, maxY - backgroundHeight, leftX + backgroundWidth, maxY); background.BackgroundColor = backgroundColor; compositeColumn.Canvas.Rectangle(background); } } } if (percentageWidth == null) { contentWidth = 0; } if (percentageHeight == null) { contentHeight = 0; } minY += paddingBottom; leftX += paddingLeft; rightX -= paddingRight; yLine -= paddingTop; int status = ColumnText.NO_MORE_TEXT; if (content.Count > 0) { //if (floatLayout == null) { List <IElement> floatingElements = new List <IElement>(content); floatLayout = new FloatLayout(compositeColumn, floatingElements); //} floatLayout.SetSimpleColumn(leftX, minY, rightX, yLine); status = floatLayout.layout(simulate); yLine = floatLayout.getYLine(); if (percentageWidth == null && contentWidth < floatLayout.getFilledWidth()) { contentWidth = floatLayout.getFilledWidth(); } } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { compositeColumn.Canvas.RestoreState(); } yLine -= paddingBottom; if (percentageHeight == null) { contentHeight = maxY - yLine; } if (percentageWidth == null) { contentWidth += paddingLeft + paddingRight; } return(status); }
public int Layout(PdfContentByte canvas, bool useAscender, bool simulate, float llx, float lly, float urx, float ury) { float leftX = Math.Min(llx, urx); float maxY = Math.Max(lly, ury); float minY = Math.Min(lly, ury); float rightX = Math.Max(llx, urx); float yLine = maxY; bool contentCutByFixedHeight = false; if (width != null && width > 0) { if (width < rightX - leftX) { rightX = leftX + (float)width; } else if (width > rightX - leftX) { return(ColumnText.NO_MORE_COLUMN); } } else if (percentageWidth != null) { contentWidth = (rightX - leftX) * (float)percentageWidth; rightX = leftX + contentWidth; } if (height != null && height > 0) { if (height < maxY - minY) { contentCutByFixedHeight = true; minY = maxY - (float)height; } else if (height > maxY - minY) { return(ColumnText.NO_MORE_COLUMN); } } else if (percentageHeight != null) { if (percentageHeight < 1.0) { contentCutByFixedHeight = true; } contentHeight = (maxY - minY) * (float)percentageHeight; minY = maxY - contentHeight; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { float?translationX = null; if (left != null) { translationX = left; } else if (right != null) { translationX = -right; } else { translationX = 0f; } float?translationY = null; if (top != null) { translationY = -top; } else if (bottom != null) { translationY = bottom; } else { translationY = 0f; } canvas.SaveState(); canvas.Transform(new Matrix(1f, 0, 0, 1f, translationX.Value, translationY.Value)); } if (!simulate) { if (backgroundColor != null && getActualWidth() > 0 && getActualHeight() > 0) { float backgroundWidth = getActualWidth(); float backgroundHeight = getActualHeight(); if (width != null) { backgroundWidth = width > 0 ? (float)width : 0; } if (height != null) { backgroundHeight = height > 0 ? (float)height : 0; } if (backgroundWidth > 0 && backgroundHeight > 0) { Rectangle background = new Rectangle(leftX, maxY - backgroundHeight, leftX + backgroundWidth, maxY); background.BackgroundColor = backgroundColor; canvas.Rectangle(background); } } } if (percentageWidth == null) { contentWidth = 0; } if (percentageHeight == null) { contentHeight = 0; } minY += paddingBottom; leftX += paddingLeft; rightX -= paddingRight; yLine -= paddingTop; int status = ColumnText.NO_MORE_TEXT; if (content.Count > 0) { FloatLayout floatLay = null; if (this.floatLayout == null) { List <IElement> floatingElements = new List <IElement>(content); if (simulate) { floatLay = new FloatLayout(floatingElements, useAscender); } else { floatLay = this.floatLayout = new FloatLayout(floatingElements, useAscender); } } else { if (simulate) { List <IElement> floatingElements = new List <IElement>(this.floatLayout.content); floatLay = new FloatLayout(floatingElements, useAscender); } else { floatLay = this.floatLayout; } } floatLay.SetSimpleColumn(leftX, minY, rightX, yLine); status = floatLay.Layout(canvas, simulate); yLine = floatLay.YLine; if (percentageWidth == null && contentWidth < floatLay.FilledWidth) { contentWidth = floatLay.FilledWidth; } } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { canvas.RestoreState(); } yLine -= paddingBottom; if (percentageHeight == null) { contentHeight = maxY - yLine; } if (percentageWidth == null) { contentWidth += paddingLeft + paddingRight; } return(contentCutByFixedHeight ? ColumnText.NO_MORE_TEXT : status); }
virtual public int Layout(PdfContentByte canvas, bool useAscender, bool simulate, float llx, float lly, float urx, float ury) { float leftX = Math.Min(llx, urx); float maxY = Math.Max(lly, ury); float minY = Math.Min(lly, ury); float rightX = Math.Max(llx, urx); yLine = maxY; bool contentCutByFixedHeight = false; if (width != null && width > 0) { if (width < rightX - leftX) rightX = leftX + (float) width; else if (width > rightX - leftX) return ColumnText.NO_MORE_COLUMN; } else if (percentageWidth != null) { contentWidth = (rightX - leftX)*(float) percentageWidth; rightX = leftX + contentWidth; } if (height != null && height > 0) { if (height < maxY - minY) { contentCutByFixedHeight = true; minY = maxY - (float) height; } else if (height > maxY - minY) { return ColumnText.NO_MORE_COLUMN; } } else if (percentageHeight != null) { if (percentageHeight < 1.0) contentCutByFixedHeight = true; contentHeight = (maxY - minY)*(float) percentageHeight; minY = maxY - contentHeight; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { float? translationX = null; if (left != null) translationX = left; else if (right != null) translationX = -right; else translationX = 0f; float? translationY = null; if (top != null) translationY = -top; else if (bottom != null) translationY = bottom; else translationY = 0f; canvas.SaveState(); canvas.Transform(new AffineTransform(1f, 0, 0, 1f, translationX.Value, translationY.Value)); } if (!simulate) { if (backgroundColor != null && getActualWidth() > 0 && getActualHeight() > 0) { float backgroundWidth = getActualWidth(); float backgroundHeight = getActualHeight(); if (width != null) backgroundWidth = width > 0 ? (float) width : 0; if (height != null) backgroundHeight = height > 0 ? (float) height : 0; if (backgroundWidth > 0 && backgroundHeight > 0) { Rectangle background = new Rectangle(leftX, maxY - backgroundHeight, leftX + backgroundWidth, maxY); background.BackgroundColor = backgroundColor; PdfArtifact artifact = new PdfArtifact(); canvas.OpenMCBlock(artifact); canvas.Rectangle(background); canvas.CloseMCBlock(artifact); } } } if (percentageWidth == null) contentWidth = 0; if (percentageHeight == null) contentHeight = 0; minY += paddingBottom; leftX += paddingLeft; rightX -= paddingRight; yLine -= paddingTop; int status = ColumnText.NO_MORE_TEXT; if (content.Count > 0) { if (floatLayout == null) { List<IElement> floatingElements = new List<IElement>(content); floatLayout = new FloatLayout(floatingElements, useAscender); } floatLayout.SetSimpleColumn(leftX, minY, rightX, yLine); status = floatLayout.Layout(canvas, simulate); yLine = floatLayout.YLine; if (percentageWidth == null && contentWidth < floatLayout.FilledWidth) contentWidth = floatLayout.FilledWidth; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) canvas.RestoreState(); yLine -= paddingBottom; if (percentageHeight == null) contentHeight = maxY - yLine; if (percentageWidth == null) contentWidth += paddingLeft + paddingRight; return contentCutByFixedHeight ? ColumnText.NO_MORE_TEXT : status; }
virtual public int Layout(PdfContentByte canvas, bool useAscender, bool simulate, float llx, float lly, float urx, float ury) { float leftX = Math.Min(llx, urx); float maxY = Math.Max(lly, ury); float minY = Math.Min(lly, ury); float rightX = Math.Max(llx, urx); yLine = maxY; bool contentCutByFixedHeight = false; if (width != null && width > 0) { if (width < rightX - leftX) { rightX = leftX + (float)width; } else if (width > rightX - leftX) { return(ColumnText.NO_MORE_COLUMN); } } else if (percentageWidth != null) { contentWidth = (rightX - leftX) * (float)percentageWidth; rightX = leftX + contentWidth; } else if (percentageWidth == null) { if (this.floatType == FloatType.NONE && (this.display == DisplayType.DEFAULT_NULL_VALUE || this.display == DisplayType.BLOCK || this.display == DisplayType.LIST_ITEM || this.display == DisplayType.RUN_IN)) { contentWidth = rightX - leftX; } } if (height != null && height > 0) { if (height < maxY - minY) { contentCutByFixedHeight = true; minY = maxY - (float)height; } else if (height > maxY - minY) { return(ColumnText.NO_MORE_COLUMN); } } else if (percentageHeight != null) { if (percentageHeight < 1.0) { contentCutByFixedHeight = true; } contentHeight = (maxY - minY) * (float)percentageHeight; minY = maxY - contentHeight; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { float?translationX = null; if (left != null) { translationX = left; } else if (right != null) { translationX = -right; } else { translationX = 0f; } float?translationY = null; if (top != null) { translationY = -top; } else if (bottom != null) { translationY = bottom; } else { translationY = 0f; } canvas.SaveState(); canvas.Transform(new AffineTransform(1f, 0, 0, 1f, translationX.Value, translationY.Value)); } if (!simulate) { if ((backgroundColor != null || backgroundImage != null) && getActualWidth() > 0 && getActualHeight() > 0) { float backgroundWidth = getActualWidth(); float backgroundHeight = getActualHeight(); if (width != null) { backgroundWidth = width > 0 ? (float)width : 0; } if (height != null) { backgroundHeight = height > 0 ? (float)height : 0; } if (backgroundWidth > 0 && backgroundHeight > 0) { Rectangle background = new Rectangle(leftX, maxY - backgroundHeight, leftX + backgroundWidth, maxY); if (backgroundColor != null) { background.BackgroundColor = backgroundColor; PdfArtifact artifact = new PdfArtifact(); canvas.OpenMCBlock(artifact); canvas.Rectangle(background); canvas.CloseMCBlock(artifact); } if (backgroundImage != null) { if (backgroundImageWidth == null) { backgroundImage.ScaleToFit(background); } else { backgroundImage.ScaleAbsolute((float)backgroundImageWidth, backgroundImageHeight); } backgroundImage.SetAbsolutePosition(background.Left, background.Bottom); canvas.OpenMCBlock(backgroundImage); canvas.AddImage(backgroundImage); canvas.CloseMCBlock(backgroundImage); } } } } if (percentageWidth == null) { contentWidth = 0; } if (percentageHeight == null) { contentHeight = 0; } minY += paddingBottom; leftX += paddingLeft; rightX -= paddingRight; yLine -= paddingTop; int status = ColumnText.NO_MORE_TEXT; if (content.Count > 0) { if (floatLayout == null) { List <IElement> floatingElements = new List <IElement>(content); floatLayout = new FloatLayout(floatingElements, useAscender); floatLayout.RunDirection = runDirection; } floatLayout.SetSimpleColumn(leftX, minY, rightX, yLine); if (borderTopStyle != BorderTopStyle.NONE) { floatLayout.compositeColumn.IgnoreSpacingBefore = false; } status = floatLayout.Layout(canvas, simulate); yLine = floatLayout.YLine; if (percentageWidth == null && contentWidth < floatLayout.FilledWidth) { contentWidth = floatLayout.FilledWidth; } } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { canvas.RestoreState(); } yLine -= paddingBottom; if (percentageHeight == null) { contentHeight = maxY - yLine; } if (percentageWidth == null) { contentWidth += paddingLeft + paddingRight; } return(contentCutByFixedHeight ? ColumnText.NO_MORE_TEXT : status); }
virtual protected int GoComposite(bool simulate) { PdfDocument pdf = null; if (canvas != null) pdf = canvas.pdf; if (!rectangularMode) throw new DocumentException(MessageLocalization.GetComposedMessage("irregular.columns.are.not.supported.in.composite.mode")); linesWritten = 0; descender = 0; bool firstPass = true; bool isRTL = runDirection == PdfWriter.RUN_DIRECTION_RTL; while (true) { if (compositeElements.Count == 0) return NO_MORE_TEXT; IElement element = compositeElements[0]; if (element.Type == Element.PARAGRAPH) { Paragraph para = (Paragraph)element; int status = 0; for (int keep = 0; keep < 2; ++keep) { float lastY = yLine; bool createHere = false; if (compositeColumn == null) { compositeColumn = new ColumnText(canvas); compositeColumn.Alignment = para.Alignment; compositeColumn.SetIndent(para.IndentationLeft + para.FirstLineIndent, false); compositeColumn.ExtraParagraphSpace = para.ExtraParagraphSpace; compositeColumn.FollowingIndent = para.IndentationLeft; compositeColumn.RightIndent = para.IndentationRight; compositeColumn.SetLeading(para.Leading, para.MultipliedLeading); compositeColumn.RunDirection = runDirection; compositeColumn.ArabicOptions = arabicOptions; compositeColumn.SpaceCharRatio = spaceCharRatio; compositeColumn.AddText(para); if (!(firstPass && adjustFirstLine)) { yLine -= para.SpacingBefore; } createHere = true; } compositeColumn.UseAscender = ((firstPass || descender == 0) && adjustFirstLine ? useAscender : false); compositeColumn.InheritGraphicState = inheritGraphicState; compositeColumn.leftX = leftX; compositeColumn.rightX = rightX; compositeColumn.yLine = yLine; compositeColumn.rectangularWidth = rectangularWidth; compositeColumn.rectangularMode = rectangularMode; compositeColumn.minY = minY; compositeColumn.maxY = maxY; bool keepCandidate = (para.KeepTogether && createHere && !(firstPass && adjustFirstLine)); bool s = simulate || keepCandidate && keep == 0; if (IsTagged(canvas) && !s) { canvas.OpenMCBlock(para); } status = compositeColumn.Go(s); if (IsTagged(canvas) && !s) { canvas.CloseMCBlock(para); } lastX = compositeColumn.LastX; UpdateFilledWidth(compositeColumn.filledWidth); if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { compositeColumn = null; yLine = lastY; return NO_MORE_COLUMN; } if (simulate || !keepCandidate) break; if (keep == 0) { compositeColumn = null; yLine = lastY; } } firstPass = false; if (compositeColumn.linesWritten > 0) { yLine = compositeColumn.yLine; linesWritten += compositeColumn.linesWritten; descender = compositeColumn.descender; isWordSplit |= compositeColumn.IsWordSplit(); } currentLeading = compositeColumn.currentLeading; if ((status & NO_MORE_TEXT) != 0) { compositeColumn = null; compositeElements.RemoveAt(0); yLine -= para.SpacingAfter; } if ((status & NO_MORE_COLUMN) != 0) { return NO_MORE_COLUMN; } } else if (element.Type == Element.LIST) { List list = (List)element; List<IElement> items = list.Items; ListItem item = null; float listIndentation = list.IndentationLeft; int count = 0; Stack<Object[]> stack = new Stack<Object[]>(); for (int k = 0; k < items.Count; ++k) { Object obj = items[k]; if (obj is ListItem) { if (count == listIdx) { item = (ListItem)obj; break; } else ++count; } else if (obj is List) { stack.Push(new Object[]{list, k, listIndentation}); list = (List)obj; items = list.Items; listIndentation += list.IndentationLeft; k = -1; continue; } while (k == items.Count - 1 && stack.Count > 0) { Object[] objs = stack.Pop(); list = (List) objs[0]; items = list.Items; k = (int) objs[1]; listIndentation = (float) objs[2]; } } int status = 0; bool keepTogetherAndDontFit = false; for (int keep = 0; keep < 2; ++keep) { float lastY = yLine; bool createHere = false; if (compositeColumn == null) { if (item == null) { listIdx = 0; compositeElements.RemoveAt(0); break; } compositeColumn = new ColumnText(canvas); compositeColumn.UseAscender = ((firstPass || descender == 0) && adjustFirstLine ? useAscender : false); compositeColumn.InheritGraphicState = inheritGraphicState; compositeColumn.Alignment = item.Alignment; compositeColumn.SetIndent(item.IndentationLeft + listIndentation + item.FirstLineIndent, false); compositeColumn.ExtraParagraphSpace = item.ExtraParagraphSpace; compositeColumn.FollowingIndent = compositeColumn.Indent; compositeColumn.RightIndent = item.IndentationRight + list.IndentationRight; compositeColumn.SetLeading(item.Leading, item.MultipliedLeading); compositeColumn.RunDirection = runDirection; compositeColumn.ArabicOptions = arabicOptions; compositeColumn.SpaceCharRatio = spaceCharRatio; compositeColumn.AddText(item); if (!(firstPass && adjustFirstLine)) { yLine -= item.SpacingBefore; } createHere = true; } compositeColumn.leftX = leftX; compositeColumn.rightX = rightX; compositeColumn.yLine = yLine; compositeColumn.rectangularWidth = rectangularWidth; compositeColumn.rectangularMode = rectangularMode; compositeColumn.minY = minY; compositeColumn.maxY = maxY; bool keepCandidate = (item.KeepTogether && createHere && !(firstPass && adjustFirstLine)); bool s = simulate || keepCandidate && keep == 0; if (IsTagged(canvas) && !s) { item.ListLabel.Indentation = listIndentation; if (list.GetFirstItem() == item || (compositeColumn != null && compositeColumn.bidiLine != null)) canvas.OpenMCBlock(list); canvas.OpenMCBlock(item); } status = compositeColumn.Go(s, item); if (IsTagged(canvas) && !s) { canvas.CloseMCBlock(item.ListBody); canvas.CloseMCBlock(item); } lastX = compositeColumn.LastX; UpdateFilledWidth(compositeColumn.filledWidth); if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { keepTogetherAndDontFit = true; compositeColumn = null; yLine = lastY; } if (simulate || !keepCandidate || keepTogetherAndDontFit) break; if (keep == 0) { compositeColumn = null; yLine = lastY; } } if (IsTagged(canvas) && !simulate) { if (item == null || (list.GetLastItem() == item && (status & NO_MORE_TEXT) != 0) || (status & NO_MORE_COLUMN) != 0) { canvas.CloseMCBlock(list); } } if (keepTogetherAndDontFit) { return NO_MORE_COLUMN; } if (item == null) { continue; } firstPass = false; yLine = compositeColumn.yLine; linesWritten += compositeColumn.linesWritten; descender = compositeColumn.descender; currentLeading = compositeColumn.currentLeading; if (!IsTagged(canvas)) { if (!float.IsNaN(compositeColumn.firstLineY) && !compositeColumn.firstLineYDone) { if (!simulate) { if (isRTL) ShowTextAligned(canvas, Element.ALIGN_RIGHT, new Phrase(item.ListSymbol), compositeColumn.lastX + item.IndentationLeft, compositeColumn.firstLineY, 0, runDirection, arabicOptions); else ShowTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(item.ListSymbol), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0); } compositeColumn.firstLineYDone = true; } } if ((status & NO_MORE_TEXT) != 0) { compositeColumn = null; ++listIdx; yLine -= item.SpacingAfter; } if ((status & NO_MORE_COLUMN) != 0) { return NO_MORE_COLUMN; } } else if (element.Type == Element.PTABLE) { // INITIALISATIONS // get the PdfPTable element PdfPTable table = (PdfPTable) element; // tables without a body are dismissed if (table.Size <= table.HeaderRows) { compositeElements.RemoveAt(0); continue; } // Y-offset float yTemp = yLine; yTemp += descender; if (rowIdx == 0 && adjustFirstLine) yTemp -= table.SpacingBefore; // if there's no space left, ask for new column if (yTemp < minY || yTemp > maxY) { return NO_MORE_COLUMN; } // coordinates float yLineWrite = yTemp; float x1 = leftX; currentLeading = 0; // get the width of the table float tableWidth; if (table.LockedWidth) { tableWidth = table.TotalWidth; UpdateFilledWidth(tableWidth); } else { tableWidth = rectangularWidth * table.WidthPercentage / 100f; table.TotalWidth = tableWidth; } // HEADERS / FOOTERS // how many header rows are real header rows; how many are footer rows? table.NormalizeHeadersFooters(); int headerRows = table.HeaderRows; int footerRows = table.FooterRows; int realHeaderRows = headerRows - footerRows; float footerHeight = table.FooterHeight; float headerHeight = table.HeaderHeight - footerHeight; // do we need to skip the header? bool skipHeader = table.SkipFirstHeader && rowIdx <= realHeaderRows && (table.ElementComplete || rowIdx != realHeaderRows); if (!skipHeader) { yTemp -= headerHeight; } // MEASURE NECESSARY SPACE // how many real rows (not header or footer rows) fit on a page? int k = 0; if (rowIdx < headerRows) { rowIdx = headerRows; } PdfPTable.FittingRows fittingRows = null; //if we skip the last header, firstly, we want to check if table is wholly fit to the page if (table.SkipLastFooter) { // Contributed by Deutsche Bahn Systel GmbH (Thorsten Seitz), splitting row spans fittingRows = table.GetFittingRows(yTemp - minY, rowIdx); } //if we skip the last footer, but the table doesn't fit to the page - we reserve space for footer //and recalculate fitting rows if (!table.SkipLastFooter || fittingRows.lastRow < table.Size - 1) { yTemp -= footerHeight; fittingRows = table.GetFittingRows(yTemp - minY, rowIdx); } //we want to be able to add more than just a header and a footer if (yTemp < minY || yTemp > maxY) { return NO_MORE_COLUMN; } k = fittingRows.lastRow + 1; yTemp -= fittingRows.height; // splitting row spans LOGGER.Info("Want to split at row " + k); int kTemp = k; while ((kTemp > rowIdx && kTemp < table.Size && table.GetRow(kTemp).MayNotBreak)) { kTemp--; } if (kTemp < (table.Size - 1) && !table.GetRow(kTemp).MayNotBreak) { kTemp++; } if ((kTemp > rowIdx && kTemp < k) || (kTemp == headerRows && table.GetRow(headerRows).MayNotBreak && table.LoopCheck)) { yTemp = minY; k = kTemp; table.LoopCheck = false; } LOGGER.Info("Will split at row " + k); // Contributed by Deutsche Bahn Systel GmbH (Thorsten Seitz), splitting row spans if (table.SplitLate && k > 0) { fittingRows.CorrectLastRowChosen(table, k - 1); } // splitting row spans // only for incomplete tables: if (!table.ElementComplete) { yTemp += footerHeight; } // IF ROWS MAY NOT BE SPLIT if (!table.SplitRows) { splittedRow = -1; if (k == rowIdx) { // drop the whole table if (k == table.Size) { compositeElements.RemoveAt(0); continue; } // or drop the row else { // don't drop the row if the table is incomplete and if there's only one row (not counting the header rows) // if there's only one row and this check wasn't here the row would have been deleted and not added at all if (!(!table.Complete && k == 1)) { table.Rows.RemoveAt(k); } return NO_MORE_COLUMN; } } } // IF ROWS SHOULD NOT BE SPLIT // Contributed by Deutsche Bahn Systel GmbH (Thorsten Seitz), splitting row spans //else if (table.isSplitLate() && !table.hasRowspan(k) && rowIdx < k) { //if first row do not fit, splittedRow has value of -2, so in this case we try to avoid split. // Separate constant for the first attempt of splitting first row save us from infinite loop. // Also we check header rows, because in other case we may split right after header row, // while header row can't split before regular rows. else if (table.SplitLate && (rowIdx < k || (splittedRow == -2 && (table.HeaderRows == 0 || table.SkipFirstHeader)))) { splittedRow = -1; } // SPLIT ROWS (IF WANTED AND NECESSARY) else if (k < table.Size) { // we calculate the remaining vertical space // Contributed by Deutsche Bahn Systel GmbH (Thorsten Seitz), splitting row spans // correct yTemp to only take completed rows into account yTemp -= fittingRows.completedRowsHeight - fittingRows.height; // splitting row spans float h = yTemp - minY; // we create a new row with the remaining content PdfPRow newRow = table.GetRow(k).SplitRow(table, k, h); // if the row isn't null add it as an extra row if (newRow == null) { LOGGER.Info("Didn't split row!"); splittedRow = -1; if (rowIdx == k) return NO_MORE_COLUMN; } else { // if the row hasn't been split before, we duplicate (part of) the table if (k != splittedRow) { splittedRow = k + 1; table = new PdfPTable(table); compositeElements[0] = table; List<PdfPRow> rows = table.Rows; for (int i = headerRows; i < rowIdx; ++i) rows[i] = null; } yTemp = minY; table.Rows.Insert(++k, newRow); LOGGER.Info("Inserting row at position " + k); } } // We're no longer in the first pass firstPass = false; // if not in simulation mode, draw the table if (!simulate) { // set the alignment switch (table.HorizontalAlignment) { case Element.ALIGN_RIGHT: if (!isRTL) x1 += rectangularWidth - tableWidth; break; case Element.ALIGN_CENTER: x1 += (rectangularWidth - tableWidth)/2f; break; case Element.ALIGN_LEFT: default: if (isRTL) x1 += rectangularWidth - tableWidth; break; } // copy the rows that fit on the page in a new table nt PdfPTable nt = PdfPTable.ShallowCopy(table); List<PdfPRow> sub = nt.Rows; // first we add the real header rows (if necessary) if (!skipHeader && realHeaderRows > 0) { List<PdfPRow> rows = table.GetRows(0, realHeaderRows); if (IsTagged(canvas)) nt.GetHeader().rows = rows; sub.AddRange(rows); } else { nt.HeaderRows = footerRows; } // then we add the real content { List<PdfPRow> rows = table.GetRows(rowIdx, k); if (IsTagged(canvas)) { nt.GetBody().rows = rows; } sub.AddRange(rows); } // do we need to show a footer? bool showFooter = !table.SkipLastFooter; bool newPageFollows = false; if (k < table.Size) { nt.ElementComplete = true; showFooter = true; newPageFollows = true; } // we add the footer rows if necessary (not for incomplete tables) if (footerRows > 0 && nt.ElementComplete && showFooter) { List<PdfPRow> rows = table.GetRows(realHeaderRows, realHeaderRows + footerRows); if (IsTagged(canvas)) { nt.GetFooter().rows = rows; } sub.AddRange(rows); } else { footerRows = 0; } if (sub.Count > 0) { // we need a correction if the last row needs to be extended float rowHeight = 0; int lastIdx = sub.Count - 1 - footerRows; PdfPRow last = sub[lastIdx]; if (table.IsExtendLastRow(newPageFollows)) { rowHeight = last.MaxHeights; last.MaxHeights = yTemp - minY + rowHeight; yTemp = minY; } // newPageFollows indicates that this table is being split if (newPageFollows) { IPdfPTableEvent tableEvent = table.TableEvent; if (tableEvent is IPdfPTableEventSplit) { ((IPdfPTableEventSplit) tableEvent).SplitTable(table); } } // now we render the rows of the new table if (canvases != null) { if (IsTagged(canvases[PdfPTable.TEXTCANVAS])) { canvases[PdfPTable.TEXTCANVAS].OpenMCBlock(table); } nt.WriteSelectedRows(0, -1, 0, -1, x1, yLineWrite, canvases, false); if (IsTagged(canvases[PdfPTable.TEXTCANVAS])) { canvases[PdfPTable.TEXTCANVAS].CloseMCBlock(table); } } else { if (IsTagged(canvas)) { canvas.OpenMCBlock(table); } nt.WriteSelectedRows(0, -1, 0, -1, x1, yLineWrite, canvas, false); if (IsTagged(canvas)) { canvas.CloseMCBlock(table); } } if (!table.Complete) { table.AddNumberOfRowsWritten(k); } // if the row was split, we copy the content of the last row // that was consumed into the first row shown on the next page if (splittedRow == k && k < table.Size) { PdfPRow splitted = table.Rows[k]; splitted.CopyRowContent(nt, lastIdx); } // Contributed by Deutsche Bahn Systel GmbH (Thorsten Seitz), splitting row spans else if (k > 0 && k < table.Size) { // continue rowspans on next page // (as the row was not split there is no content to copy) PdfPRow row = table.GetRow(k); row.SplitRowspans(table, k - 1, nt, lastIdx); } // splitting row spans // reset the row height of the last row if (table.IsExtendLastRow(newPageFollows)) { last.MaxHeights = rowHeight; } // Contributed by Deutsche Bahn Systel GmbH (Thorsten Seitz) // newPageFollows indicates that this table is being split if (newPageFollows) { IPdfPTableEvent tableEvent = table.TableEvent; if (tableEvent is IPdfPTableEventAfterSplit) { PdfPRow row = table.GetRow(k); ((IPdfPTableEventAfterSplit) tableEvent).AfterSplitTable(table, row, k); } } } } // in simulation mode, we need to take extendLastRow into account else if (table.ExtendLastRow && minY > PdfPRow.BOTTOM_LIMIT) { yTemp = minY; } yLine = yTemp; descender = 0; currentLeading = 0; if (!(skipHeader || table.ElementComplete)) { yLine += footerHeight; } while (k < table.Size) { if (table.GetRowHeight(k) > 0 || table.HasRowspan(k)) { break; } k++; } if (k >= table.Size) { // Use up space no more than left if (yLine - table.SpacingAfter < minY) { yLine = minY; } else { yLine -= table.SpacingAfter; } compositeElements.RemoveAt(0); splittedRow = -1; rowIdx = 0; } else { if (splittedRow > -1) { List<PdfPRow> rows = table.Rows; for (int i = rowIdx; i < k; ++i) rows[i] = null; } rowIdx = k; return NO_MORE_COLUMN; } } else if (element.Type == Element.YMARK) { if (!simulate) { IDrawInterface zh = (IDrawInterface)element; zh.Draw(canvas, leftX, minY, rightX, maxY, yLine); } compositeElements.RemoveAt(0); } else if (element.Type == Element.DIV) { List<IElement> floatingElements = new List<IElement>(); do { floatingElements.Add(element); compositeElements.RemoveAt(0); element = compositeElements.Count > 0 ? compositeElements[0] : null; } while (element != null && element.Type == Element.DIV); FloatLayout fl = new FloatLayout(floatingElements, useAscender); fl.SetSimpleColumn(leftX, minY, rightX, yLine); fl.compositeColumn.IgnoreSpacingBefore = ignoreSpacingBefore; int status = fl.Layout(canvas, simulate); //firstPass = false; yLine = fl.YLine; descender = 0; if ((status & NO_MORE_TEXT) == 0) { foreach (IElement floatingElement in floatingElements) { compositeElements.Add(floatingElement); } return status; } } else compositeElements.RemoveAt(0); } }
internal void FlushFloatingElements() { if (floatingElements != null && floatingElements.Count > 0) { List<IElement> cashedFloatingElements = floatingElements; floatingElements = null; FloatLayout fl = new FloatLayout(writer.DirectContent, cashedFloatingElements); int loop = 0; while (true) { fl.SetSimpleColumn(IndentLeft, IndentBottom, IndentRight, IndentTop - currentHeight); int status = fl.layout(false); if ((status & ColumnText.NO_MORE_TEXT) != 0) { text.MoveText(0, fl.getYLine() - IndentTop + currentHeight); currentHeight = IndentTop - fl.getYLine(); break; } if (IndentTop - currentHeight == fl.getYLine() || PageEmpty) ++loop; else { loop = 0; } if (loop == 2) { return; } NewPage(); } } }
virtual public int Layout(PdfContentByte canvas, bool useAscender, bool simulate, float llx, float lly, float urx, float ury) { float leftX = Math.Min(llx, urx); float maxY = Math.Max(lly, ury); float minY = Math.Min(lly, ury); float rightX = Math.Max(llx, urx); yLine = maxY; bool contentCutByFixedHeight = false; if (width != null && width > 0) { if (width < rightX - leftX) rightX = leftX + (float) width; else if (width > rightX - leftX) return ColumnText.NO_MORE_COLUMN; } else if (percentageWidth != null) { contentWidth = (rightX - leftX)*(float) percentageWidth; rightX = leftX + contentWidth; } else if (percentageWidth == null) { if (this.floatType == FloatType.NONE && (this.display == DisplayType.DEFAULT_NULL_VALUE || this.display == DisplayType.BLOCK || this.display == DisplayType.LIST_ITEM || this.display == DisplayType.RUN_IN)) { contentWidth = rightX - leftX; } } if (height != null && height > 0) { if (height < maxY - minY) { contentCutByFixedHeight = true; minY = maxY - (float) height; } else if (height > maxY - minY) { return ColumnText.NO_MORE_COLUMN; } } else if (percentageHeight != null) { if (percentageHeight < 1.0) contentCutByFixedHeight = true; contentHeight = (maxY - minY)*(float) percentageHeight; minY = maxY - contentHeight; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { float? translationX = null; if (left != null) translationX = left; else if (right != null) translationX = -right; else translationX = 0f; float? translationY = null; if (top != null) translationY = -top; else if (bottom != null) translationY = bottom; else translationY = 0f; canvas.SaveState(); canvas.Transform(new AffineTransform(1f, 0, 0, 1f, translationX.Value, translationY.Value)); } if (!simulate) { if ((backgroundColor != null || backgroundImage != null) && getActualWidth() > 0 && getActualHeight() > 0) { float backgroundWidth = getActualWidth(); float backgroundHeight = getActualHeight(); if (width != null) backgroundWidth = width > 0 ? (float) width : 0; if (height != null) backgroundHeight = height > 0 ? (float) height : 0; if (backgroundWidth > 0 && backgroundHeight > 0) { Rectangle background = new Rectangle(leftX, maxY - backgroundHeight, leftX + backgroundWidth, maxY); if (backgroundColor != null) { background.BackgroundColor = backgroundColor; PdfArtifact artifact = new PdfArtifact(); canvas.OpenMCBlock(artifact); canvas.Rectangle(background); canvas.CloseMCBlock(artifact); } if (backgroundImage != null) { if (backgroundImageWidth == null) { backgroundImage.ScaleToFit(background); } else { backgroundImage.ScaleAbsolute((float)backgroundImageWidth, backgroundImageHeight); } backgroundImage.SetAbsolutePosition(background.Left, background.Bottom); canvas.OpenMCBlock(backgroundImage); canvas.AddImage(backgroundImage); canvas.CloseMCBlock(backgroundImage); } } } } if (percentageWidth == null) contentWidth = 0; if (percentageHeight == null) contentHeight = 0; minY += paddingBottom; leftX += paddingLeft; rightX -= paddingRight; yLine -= paddingTop; int status = ColumnText.NO_MORE_TEXT; if (content.Count > 0) { if (floatLayout == null) { List<IElement> floatingElements = new List<IElement>(content); floatLayout = new FloatLayout(floatingElements, useAscender); floatLayout.RunDirection = runDirection; } floatLayout.SetSimpleColumn(leftX, minY, rightX, yLine); if (borderTopStyle != BorderTopStyle.NONE) floatLayout.compositeColumn.IgnoreSpacingBefore = false; status = floatLayout.Layout(canvas, simulate); yLine = floatLayout.YLine; if (percentageWidth == null && contentWidth < floatLayout.FilledWidth) { contentWidth = floatLayout.FilledWidth; } } if (!simulate && position == PdfDiv.PositionType.RELATIVE) canvas.RestoreState(); yLine -= paddingBottom; if (percentageHeight == null) contentHeight = maxY - yLine; if (percentageWidth == null) contentWidth += paddingLeft + paddingRight; return contentCutByFixedHeight ? ColumnText.NO_MORE_TEXT : status; }
public int layout(ColumnText compositeColumn, bool simulate, float llx, float lly, float urx, float ury) { float leftX = Math.Min(llx, urx); float maxY = Math.Max(lly, ury); float minY = Math.Min(lly, ury); float rightX = Math.Max(llx, urx); float yLine = maxY; bool contentCutByFixedHeight = false; if (width != null && width > 0) { if (width < rightX - leftX) { rightX = leftX + (float)width; } else if (width > rightX - leftX) { return ColumnText.NO_MORE_COLUMN; } } else if (percentageWidth != null) { contentWidth = (rightX - leftX) * (float)percentageWidth; rightX = leftX + contentWidth; } if (height != null && height > 0) { if (height < maxY - minY) { contentCutByFixedHeight = true; minY = maxY - (float)height; } else if (height > maxY - minY) { return ColumnText.NO_MORE_COLUMN; } } else if (percentageHeight != null) { if (percentageHeight < 1.0) { contentCutByFixedHeight = true; } contentHeight = (maxY - minY) * (float)percentageHeight; minY = maxY - contentHeight; } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { float? translationX = null; if (left != null) { translationX = left; } else if (right != null) { translationX = -right; } else { translationX = 0f; } float? translationY = null; if (top != null) { translationY = -top; } else if (bottom != null) { translationY = bottom; } else { translationY = 0f; } compositeColumn.Canvas.SaveState(); //compositeColumn.Canvas.Transform(new System.Drawing.Drawing2D.Matrix(1f, 0, 0, 1f, (float)translationX, (float)translationY)); } if (!simulate) { if (backgroundColor != null && getActualWidth() > 0 && getActualHeight() > 0) { float backgroundWidth = getActualWidth(); float backgroundHeight = getActualHeight(); if (width != null) { backgroundWidth = width > 0 ? (float)width : 0; } if (height != null) { backgroundHeight = height > 0 ? (float)height : 0; } if (backgroundWidth > 0 && backgroundHeight > 0) { Rectangle background = new Rectangle(leftX, maxY - backgroundHeight, leftX + backgroundWidth, maxY); background.BackgroundColor = backgroundColor; compositeColumn.Canvas.Rectangle(background); } } } if (percentageWidth == null) { contentWidth = 0; } if (percentageHeight == null) { contentHeight = 0; } minY += paddingBottom; leftX += paddingLeft; rightX -= paddingRight; yLine -= paddingTop; int status = ColumnText.NO_MORE_TEXT; if (content.Count > 0) { FloatLayout floatLay = null; if (this.floatLayout == null) { List<IElement> floatingElements = new List<IElement>(content); if (simulate){ floatLay = new FloatLayout(compositeColumn, floatingElements); } else{ floatLay = this.floatLayout = new FloatLayout(compositeColumn, floatingElements); } } else{ if (simulate){ List<IElement> floatingElements = new List<IElement>(this.floatLayout.content); floatLay = new FloatLayout(this.floatLayout.compositeColumn, floatingElements); } else { floatLay = this.floatLayout; } } floatLay.SetSimpleColumn(leftX, minY, rightX, yLine); status = floatLay.layout(simulate); yLine = floatLay.getYLine(); if (percentageWidth == null && contentWidth < floatLay.getFilledWidth()) { contentWidth = floatLay.getFilledWidth(); } } if (!simulate && position == PdfDiv.PositionType.RELATIVE) { compositeColumn.Canvas.RestoreState(); } yLine -= paddingBottom; if (percentageHeight == null) { contentHeight = maxY - yLine; } if (percentageWidth == null) { contentWidth += paddingLeft + paddingRight; } return contentCutByFixedHeight ? ColumnText.NO_MORE_TEXT : status; }