/** * Add a new column. The parameters are limits for each column * wall in the format of a sequence of points (x1,y1,x2,y2,...). * * @param left limits for left column * @param right limits for right column */ public void AddColumn(float[] left, float[] right) { ColumnDef nextDef = new ColumnDef(left, right, this); simple = nextDef.IsSimple(); columnDefs.Add(nextDef); }
/** * Add a new column. The parameters are limits for each column * wall in the format of a sequence of points (x1,y1,x2,y2,...). * * @param left limits for left column * @param right limits for right column */ public void AddColumn(float[] left, float[] right) { ColumnDef nextDef = new ColumnDef(left, right, this); if (!nextDef.IsSimple()) { simple = false; } columnDefs.Add(nextDef); }
/** * Write out the columns. After writing, use * {@link #isOverflow()} to see if all text was written. * @param canvas PdfContentByte to write with * @param document document to write to (only used to get page limit info) * @param documentY starting y position to begin writing at * @return the current height (y position) after writing the columns * @throws DocumentException on error */ public float Write(PdfContentByte canvas, PdfDocument document, float documentY) { this.document = document; columnText.Canvas = canvas; if (columnDefs.Count == 0) { throw new DocumentException(MessageLocalization.GetComposedMessage("multicolumntext.has.no.columns")); } overflow = false; float currentHeight = 0; bool done = false; while (!done) { if (top == AUTOMATIC) { top = document.GetVerticalPosition(true); } else if (nextY == AUTOMATIC) { nextY = document.GetVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page. } ColumnDef currentDef = (ColumnDef)columnDefs[CurrentColumn]; columnText.YLine = top; float[] left = currentDef.ResolvePositions(Rectangle.LEFT_BORDER); float[] right = currentDef.ResolvePositions(Rectangle.RIGHT_BORDER); if (document.IsMarginMirroring() && document.PageNumber % 2 == 0) { float delta = document.RightMargin - document.Left; left = (float[])left.Clone(); right = (float[])right.Clone(); for (int i = 0; i < left.Length; i += 2) { left[i] -= delta; } for (int i = 0; i < right.Length; i += 2) { right[i] -= delta; } } currentHeight = Math.Max(currentHeight, GetHeight(left, right)); if (currentDef.IsSimple()) { columnText.SetSimpleColumn(left[2], left[3], right[0], right[1]); } else { columnText.SetColumns(left, right); } int result = columnText.Go(); if ((result & ColumnText.NO_MORE_TEXT) != 0) { done = true; top = columnText.YLine; } else if (ShiftCurrentColumn()) { top = nextY; } else // check if we are done because of height { totalHeight += currentHeight; if ((desiredHeight != AUTOMATIC) && (totalHeight >= desiredHeight)) { overflow = true; break; } else // need to start new page and reset the columns { documentY = nextY; NewPage(); currentHeight = 0; } } } if (desiredHeight == AUTOMATIC && columnDefs.Count == 1) { currentHeight = documentY - columnText.YLine; } return(currentHeight); }
/** * Add a new column. The parameters are limits for each column * wall in the format of a sequence of points (x1,y1,x2,y2,...). * * @param left limits for left column * @param right limits for right column */ public void AddColumn(float[] left, float[] right) { ColumnDef nextDef = new ColumnDef(left, right, this); if (!nextDef.IsSimple()) simple = false; columnDefs.Add(nextDef); }
/// <summary> /// Write out the columns. After writing, use /// {@link #isOverflow()} to see if all text was written. /// @throws DocumentException on error /// </summary> /// <param name="canvas">PdfContentByte to write with</param> /// <param name="document">document to write to (only used to get page limit info)</param> /// <param name="documentY">starting y position to begin writing at</param> /// <returns>the current height (y position) after writing the columns</returns> public float Write(PdfContentByte canvas, PdfDocument document, float documentY) { _document = document; _columnText.Canvas = canvas; if (_columnDefs.Count == 0) { throw new DocumentException("MultiColumnText has no columns"); } _overflow = false; float currentHeight = 0; bool done = false; while (!done) { if (_top.ApproxEquals(AUTOMATIC)) { _top = document.GetVerticalPosition(true); } else if (_nextY.ApproxEquals(AUTOMATIC)) { _nextY = document.GetVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page. } ColumnDef currentDef = (ColumnDef)_columnDefs[CurrentColumn]; _columnText.YLine = _top; float[] left = currentDef.ResolvePositions(Rectangle.LEFT_BORDER); float[] right = currentDef.ResolvePositions(Rectangle.RIGHT_BORDER); if (document.IsMarginMirroring() && document.PageNumber % 2 == 0) { float delta = document.RightMargin - document.Left; left = (float[])left.Clone(); right = (float[])right.Clone(); for (int i = 0; i < left.Length; i += 2) { left[i] -= delta; } for (int i = 0; i < right.Length; i += 2) { right[i] -= delta; } } currentHeight = Math.Max(currentHeight, getHeight(left, right)); if (currentDef.IsSimple()) { _columnText.SetSimpleColumn(left[2], left[3], right[0], right[1]); } else { _columnText.SetColumns(left, right); } int result = _columnText.Go(); if ((result & ColumnText.NO_MORE_TEXT) != 0) { done = true; _top = _columnText.YLine; } else if (ShiftCurrentColumn()) { _top = _nextY; } else { // check if we are done because of height _totalHeight += currentHeight; if ((_desiredHeight.ApproxNotEqual(AUTOMATIC)) && (_totalHeight >= _desiredHeight)) { _overflow = true; break; } else { // need to start new page and reset the columns documentY = _nextY; newPage(); currentHeight = 0; } } } if (_desiredHeight.ApproxEquals(AUTOMATIC) && _columnDefs.Count == 1) { currentHeight = documentY - _columnText.YLine; } return(currentHeight); }
// try to balance out the content of the columns to have equal content length private float getBalanceDesiredHeight(PdfContentByte canvas, PdfDocument document, float documentY) { this.document = document; if (columnDefs.Count == 0) { throw new DocumentException("MultiColumnText has no columns"); } float origintop = top; float originnextY = nextY; float originDesired = desiredHeight; desiredHeight = -1; float maxHeight = 0; // as much height that's left on the page top = document.GetVerticalPosition(true); foreach (ColumnDef cd in columnDefs) { float[] left = cd.ResolvePositions(Rectangle.LEFT_BORDER); float[] right = cd.ResolvePositions(Rectangle.RIGHT_BORDER); maxHeight = Math.Max(maxHeight, GetHeight(left, right)); } float measureHeight = maxHeight; float heightAdust = maxHeight / 2.0f; float fitHeight = -1; bool firstPass = true; while (heightAdust > 0.25) { ColumnText columnText = new ColumnText(canvas); columnText.Canvas = canvas; columnText.SetACopy(this.columnText); bool fitAll = false; desiredHeight = measureHeight; top = origintop; nextY = originnextY; float currentHeight = 0; bool done = false; while (!done) { if (top == AUTOMATIC) { top = document.GetVerticalPosition(true); } else if (nextY == AUTOMATIC) { nextY = document.GetVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page. } ColumnDef currentDef = (ColumnDef)columnDefs[CurrentColumn]; columnText.YLine = top; float[] left = currentDef.ResolvePositions(Rectangle.LEFT_BORDER); float[] right = currentDef.ResolvePositions(Rectangle.RIGHT_BORDER); if (document.IsMarginMirroring() && document.PageNumber % 2 == 0) { float delta = document.RightMargin - document.Left; left = (float[])left.Clone(); right = (float[])right.Clone(); for (int i = 0; i < left.Length; i += 2) { left[i] -= delta; } for (int i = 0; i < right.Length; i += 2) { right[i] -= delta; } } currentHeight = Math.Max(currentHeight, GetHeight(left, right)); if (currentDef.IsSimple()) { columnText.SetSimpleColumn(left[2], left[3], right[0], right[1]); } else { columnText.SetColumns(left, right); } int result = columnText.Go(true); if ((result & ColumnText.NO_MORE_TEXT) != 0) { done = true; top = columnText.YLine; fitAll = true; } else if (ShiftCurrentColumn()) // NO_MORE_COLUMN, try to go to the next column { top = nextY; } else { // check if we are done because of height fitAll = false; done = true; } } ResetCurrentColumn(); if (fitAll) { fitHeight = measureHeight; measureHeight -= heightAdust; } else { measureHeight += heightAdust; // ok, so we've tried the full length! and it cannot fit. // leave the current page as is, and we we'll try on the text page if (firstPass) { break; } } heightAdust /= 2.0f; firstPass = false; } top = origintop; nextY = originnextY; desiredHeight = originDesired; return(fitHeight); }