/** * Writes a number of cells (not necessarily all cells). * * @param colStart The first column to be written. * Remember that the column index starts with 0. * @param colEnd The last column to be written. * Remember that the column index starts with 0. * If -1, all the columns to the end are written. * @param xPos The x-coordinate where the table starts on the canvas * @param yPos The y-coordinate where the table starts on the canvas */ public void WriteCells(int colStart, int colEnd, float xPos, float yPos, PdfContentByte[] canvases) { if (!calculated) { CalculateHeights(); } if (colEnd < 0) { colEnd = cells.Length; } else { colEnd = Math.Min(colEnd, cells.Length); } if (colStart < 0) { colStart = 0; } if (colStart >= colEnd) { return; } int newStart; for (newStart = colStart; newStart >= 0; --newStart) { if (cells[newStart] != null) { break; } if (newStart > 0) { xPos -= widths[newStart - 1]; } } if (newStart < 0) { newStart = 0; } if (cells[newStart] != null) { xPos -= cells[newStart].Left; } for (int k = newStart; k < colEnd; ++k) { PdfPCell cell = cells[k]; if (cell == null) { continue; } float currentMaxHeight = maxHeight + extraHeights[k]; WriteBorderAndBackground(xPos, yPos, currentMaxHeight, cell, canvases); Image img = cell.Image; float tly = cell.Top + yPos - cell.EffectivePaddingTop; if (cell.Height <= currentMaxHeight) { switch (cell.VerticalAlignment) { case Element.ALIGN_BOTTOM: tly = cell.Top + yPos - currentMaxHeight + cell.Height - cell.EffectivePaddingTop; break; case Element.ALIGN_MIDDLE: tly = cell.Top + yPos + (cell.Height - currentMaxHeight) / 2 - cell.EffectivePaddingTop; break; default: break; } } if (img != null) { if (cell.Rotation != 0) { img = Image.GetInstance(img); img.Rotation = img.GetImageRotation() + (float)(cell.Rotation * Math.PI / 180.0); } bool vf = false; if (cell.Height > currentMaxHeight) { img.ScalePercent(100); float scale = (currentMaxHeight - cell.EffectivePaddingTop - cell .EffectivePaddingBottom) / img.ScaledHeight; img.ScalePercent(scale * 100); vf = true; } float left = cell.Left + xPos + cell.EffectivePaddingLeft; if (vf) { switch (cell.HorizontalAlignment) { case Element.ALIGN_CENTER: left = xPos + (cell.Left + cell.EffectivePaddingLeft + cell.Right - cell.EffectivePaddingRight - img .ScaledWidth) / 2; break; case Element.ALIGN_RIGHT: left = xPos + cell.Right - cell.EffectivePaddingRight - img.ScaledWidth; break; default: break; } tly = cell.Top + yPos - cell.EffectivePaddingTop; } img.SetAbsolutePosition(left, tly - img.ScaledHeight); canvases[PdfPTable.TEXTCANVAS].AddImage(img); } else { // rotation sponsored by Connection GmbH if (cell.Rotation == 90 || cell.Rotation == 270) { float netWidth = currentMaxHeight - cell.EffectivePaddingTop - cell.EffectivePaddingBottom; float netHeight = cell.Width - cell.EffectivePaddingLeft - cell.EffectivePaddingRight; ColumnText ct = ColumnText.Duplicate(cell.Column); ct.Canvases = canvases; ct.SetSimpleColumn(0, 0, netWidth + 0.001f, -netHeight); ct.Go(true); float calcHeight = -ct.YLine; if (netWidth <= 0 || netHeight <= 0) { calcHeight = 0; } if (calcHeight > 0) { if (cell.UseDescender) { calcHeight -= ct.Descender; } ct = ColumnText.Duplicate(cell.Column); ct.Canvases = canvases; ct.SetSimpleColumn(-0.003f, -0.001f, netWidth + 0.003f, calcHeight); float pivotX; float pivotY; if (cell.Rotation == 90) { pivotY = cell.Top + yPos - currentMaxHeight + cell.EffectivePaddingBottom; switch (cell.VerticalAlignment) { case Element.ALIGN_BOTTOM: pivotX = cell.Left + xPos + cell.Width - cell.EffectivePaddingRight; break; case Element.ALIGN_MIDDLE: pivotX = cell.Left + xPos + (cell.Width + cell.EffectivePaddingLeft - cell.EffectivePaddingRight + calcHeight) / 2; break; default: //top pivotX = cell.Left + xPos + cell.EffectivePaddingLeft + calcHeight; break; } SaveAndRotateCanvases(canvases, 0, 1, -1, 0, pivotX, pivotY); } else { pivotY = cell.Top + yPos - cell.EffectivePaddingTop; switch (cell.VerticalAlignment) { case Element.ALIGN_BOTTOM: pivotX = cell.Left + xPos + cell.EffectivePaddingLeft; break; case Element.ALIGN_MIDDLE: pivotX = cell.Left + xPos + (cell.Width + cell.EffectivePaddingLeft - cell.EffectivePaddingRight - calcHeight) / 2; break; default: //top pivotX = cell.Left + xPos + cell.Width - cell.EffectivePaddingRight - calcHeight; break; } SaveAndRotateCanvases(canvases, 0, -1, 1, 0, pivotX, pivotY); } try { ct.Go(); } finally { RestoreCanvases(canvases); } } } else { float fixedHeight = cell.FixedHeight; float rightLimit = cell.Right + xPos - cell.EffectivePaddingRight; float leftLimit = cell.Left + xPos + cell.EffectivePaddingLeft; if (cell.NoWrap) { switch (cell.HorizontalAlignment) { case Element.ALIGN_CENTER: rightLimit += 10000; leftLimit -= 10000; break; case Element.ALIGN_RIGHT: if (cell.Rotation == 180) { rightLimit += RIGHT_LIMIT; } else { leftLimit -= RIGHT_LIMIT; } break; default: if (cell.Rotation == 180) { leftLimit -= RIGHT_LIMIT; } else { rightLimit += RIGHT_LIMIT; } break; } } ColumnText ct = ColumnText.Duplicate(cell.Column); ct.Canvases = canvases; float bry = tly - (currentMaxHeight - cell.EffectivePaddingTop - cell.EffectivePaddingBottom); if (fixedHeight > 0) { if (cell.Height > currentMaxHeight) { tly = cell.Top + yPos - cell.EffectivePaddingTop; bry = cell.Top + yPos - currentMaxHeight + cell.EffectivePaddingBottom; } } if ((tly > bry || ct.ZeroHeightElement()) && leftLimit < rightLimit) { ct.SetSimpleColumn(leftLimit, bry - 0.001f, rightLimit, tly); if (cell.Rotation == 180) { float shx = leftLimit + rightLimit; float shy = yPos + yPos - currentMaxHeight + cell.EffectivePaddingBottom - cell.EffectivePaddingTop; SaveAndRotateCanvases(canvases, -1, 0, 0, -1, shx, shy); } try { ct.Go(); } finally { if (cell.Rotation == 180) { RestoreCanvases(canvases); } } } } } IPdfPCellEvent evt = cell.CellEvent; if (evt != null) { Rectangle rect = new Rectangle(cell.Left + xPos, cell.Top + yPos - currentMaxHeight, cell.Right + xPos, cell.Top + yPos); evt.CellLayout(cell, rect, canvases); } } }
/** * Splits a row to newHeight. * The returned row is the remainder. It will return null if the newHeight * was so small that only an empty row would result. * * @param new_height the new height * @return the remainder row or null if the newHeight was so small that only * an empty row would result */ public PdfPRow SplitRow(PdfPTable table, int rowIndex, float new_height) { PdfPCell[] newCells = new PdfPCell[cells.Length]; float[] fixHs = new float[cells.Length]; float[] minHs = new float[cells.Length]; bool allEmpty = true; for (int k = 0; k < cells.Length; ++k) { float newHeight = new_height; PdfPCell cell = cells[k]; if (cell == null) { int index = rowIndex; if (table.RowSpanAbove(index, k)) { newHeight += table.GetRowHeight(index); while (table.RowSpanAbove(--index, k)) { newHeight += table.GetRowHeight(index); } PdfPRow row = table.GetRow(index); if (row != null && row.GetCells()[k] != null) { newCells[k] = new PdfPCell(row.GetCells()[k]); newCells[k].ConsumeHeight(newHeight); newCells[k].Rowspan = row.GetCells()[k].Rowspan - rowIndex + index; allEmpty = false; } } continue; } fixHs[k] = cell.FixedHeight; minHs[k] = cell.MinimumHeight; Image img = cell.Image; PdfPCell newCell = new PdfPCell(cell); if (img != null) { if (newHeight > cell.EffectivePaddingBottom + cell.EffectivePaddingTop + 2) { newCell.Phrase = null; allEmpty = false; } } else { float y; ColumnText ct = ColumnText.Duplicate(cell.Column); float left = cell.Left + cell.EffectivePaddingLeft; float bottom = cell.Top + cell.EffectivePaddingBottom - newHeight; float right = cell.Right - cell.EffectivePaddingRight; float top = cell.Top - cell.EffectivePaddingTop; switch (cell.Rotation) { case 90: case 270: y = SetColumn(ct, bottom, left, top, right); break; default: y = SetColumn(ct, left, bottom, cell.NoWrap ? RIGHT_LIMIT : right, top); break; } int status; status = ct.Go(true); bool thisEmpty = (ct.YLine == y); if (thisEmpty) { newCell.Column = ColumnText.Duplicate(cell.Column); ct.FilledWidth = 0; } else if ((status & ColumnText.NO_MORE_TEXT) == 0) { newCell.Column = ct; ct.FilledWidth = 0; } else { newCell.Phrase = null; } allEmpty = (allEmpty && thisEmpty); } newCells[k] = newCell; cell.FixedHeight = newHeight; } if (allEmpty) { for (int k = 0; k < cells.Length; ++k) { PdfPCell cell = cells[k]; if (cell == null) { continue; } if (fixHs[k] > 0) { cell.FixedHeight = fixHs[k]; } else { cell.MinimumHeight = minHs[k]; } } return(null); } CalculateHeights(); PdfPRow split = new PdfPRow(newCells); split.widths = (float[])widths.Clone(); split.CalculateHeights(); return(split); }
/** * Writes the border and background of one cell in the row. * * @param xPos The x-coordinate where the table starts on the canvas * @param yPos The y-coordinate where the table starts on the canvas * @param currentMaxHeight The height of the cell to be drawn. * @param cell * @param canvases * @since 2.1.6 extra parameter currentMaxHeight */ public void WriteBorderAndBackground(float xPos, float yPos, float currentMaxHeight, PdfPCell cell, PdfContentByte[] canvases) { Color background = cell.BackgroundColor; if (background != null || cell.HasBorders()) { // Add xPos resp. yPos to the cell's coordinates for absolute coordinates float right = cell.Right + xPos; float top = cell.Top + yPos; float left = cell.Left + xPos; float bottom = top - currentMaxHeight; if (background != null) { PdfContentByte backgr = canvases[PdfPTable.BACKGROUNDCANVAS]; backgr.SetColorFill(background); backgr.Rectangle(left, bottom, right - left, top - bottom); backgr.Fill(); } if (cell.HasBorders()) { Rectangle newRect = new Rectangle(left, bottom, right, top); // Clone non-position parameters except for the background color newRect.CloneNonPositionParameters(cell); newRect.BackgroundColor = null; // Write the borders on the line canvas PdfContentByte lineCanvas = canvases[PdfPTable.LINECANVAS]; lineCanvas.Rectangle(newRect); } } }