예제 #1
0
  /**
   * Adds an image to this Cell.
   *
   * @param i the image to add
   * @param left the left border
   * @param right the right border
   * @param extraHeight extra height to add above image
   * @param alignment horizontal alignment (constant from Element class)
   * @return the height of the image
   */
  private float addImage(Image i, float left, float right, float extraHeight, int alignment) {
    Image image = Image.getInstance(i);
    if (image.scaledWidth() > right - left) {
      image.scaleToFit(right - left, Float.MAX_VALUE);
    }
    flushCurrentLine();
    if (line == null) {
      line = new PdfLine(left, right, alignment, leading);
    }
    PdfLine imageLine = line;

    // left and right in chunk is relative to the start of the line
    right = right - left;
    left = 0f;

    if ((image.alignment() & Image.RIGHT) == Image.RIGHT) {
      left = right - image.scaledWidth();
    } else if ((image.alignment() & Image.MIDDLE) == Image.MIDDLE) {
      left = left + ((right - left - image.scaledWidth()) / 2f);
    }
    Chunk imageChunk = new Chunk(image, left, 0);
    imageLine.add(new PdfChunk(imageChunk, null));
    addLine(imageLine);
    return imageLine.height();
  }
예제 #2
0
 /**
  * Returns the number of lines in the cell that are not empty.
  *
  * @return a value
  */
 public int remainingLines() {
   if (lines.size() == 0) return 0;
   int result = 0;
   int size = lines.size();
   PdfLine line;
   for (int i = 0; i < size; i++) {
     line = (PdfLine) lines.get(i);
     if (line.size() > 0) result++;
   }
   return result;
 }
예제 #3
0
 private PdfLine removeLine(int index) {
   PdfLine oldLine = (PdfLine) lines.remove(index);
   contentHeight -= oldLine.height();
   if (index == 0) {
     if (lines.size() > 0) {
       firstLine = (PdfLine) lines.get(0);
       float firstLineRealHeight = firstLineRealHeight();
       contentHeight -= firstLine.height();
       firstLine.height = firstLineRealHeight;
       contentHeight += firstLineRealHeight;
     }
   }
   return oldLine;
 }
예제 #4
0
  /**
   * Gets the lines of a cell that can be drawn between certain limits.
   *
   * <p>Remark: all the lines that can be drawn are removed from the object!
   *
   * @param top the top of the part of the table that can be drawn
   * @param bottom the bottom of the part of the table that can be drawn
   * @return an <CODE>ArrayList</CODE> of <CODE>PdfLine</CODE>s
   */
  public ArrayList getLines(float top, float bottom) {
    float lineHeight;
    float currentPosition = Math.min(top(), top);
    setTop(currentPosition + cellspacing);
    ArrayList result = new ArrayList();

    // if the bottom of the page is higher than the top of the cell: do nothing
    if (top() < bottom) {
      return result;
    }

    // we loop over the lines
    int size = lines.size();
    boolean aboveBottom = true;
    for (int i = 0; i < size && aboveBottom; i++) {
      line = (PdfLine) lines.get(i);
      lineHeight = line.height();
      currentPosition -= lineHeight;
      // if the currentPosition is higher than the bottom, we add the line to the result
      if (currentPosition > (bottom + cellpadding + getBorderWidthInside(BOTTOM))) {
        result.add(line);
      } else {
        aboveBottom = false;
      }
    }
    // if the bottom of the cell is higher than the bottom of the page, the cell is written, so we
    // can remove all lines
    float difference = 0f;
    if (!header) {
      if (aboveBottom) {
        lines = new ArrayList();
        contentHeight = 0f;
      } else {
        size = result.size();
        for (int i = 0; i < size; i++) {
          line = removeLine(0);
          difference += line.height();
        }
      }
    }
    if (difference > 0) {
      Image image;
      for (Iterator i = images.iterator(); i.hasNext(); ) {
        image = (Image) i.next();
        image.setAbsolutePosition(image.absoluteX(), image.absoluteY() - difference - leading);
      }
    }
    return result;
  }
예제 #5
0
 /**
  * Calculates what the height of the first line should be so that the content will be flush with
  * the top. For text, this is the height of the ascender. For an image, it is the actual height of
  * the image.
  *
  * @return the real height of the first line
  */
 private float firstLineRealHeight() {
   float firstLineRealHeight = 0f;
   if (firstLine != null) {
     PdfChunk chunk = firstLine.getChunk(0);
     if (chunk != null) {
       Image image = chunk.getImage();
       if (image != null) {
         firstLineRealHeight = firstLine.getChunk(0).getImage().scaledHeight();
       } else {
         firstLineRealHeight = useAscender ? firstLine.getAscender() : leading;
       }
     }
   }
   return firstLineRealHeight;
 }
예제 #6
0
  /**
   * Sets the bottom of the Rectangle and determines the proper {link #verticalOffset} to
   * appropriately align the contents vertically.
   *
   * @param value
   */
  public void setBottom(float value) {
    super.setBottom(value);
    float firstLineRealHeight = firstLineRealHeight();

    float totalHeight = ury - value; // can't use top (already compensates for cellspacing)
    float nonContentHeight = (cellpadding() * 2f) + (cellspacing() * 2f);
    nonContentHeight += getBorderWidthInside(TOP) + getBorderWidthInside(BOTTOM);

    float interiorHeight = totalHeight - nonContentHeight;
    float extraHeight = 0.0f;

    switch (verticalAlignment) {
      case Element.ALIGN_BOTTOM:
        extraHeight = interiorHeight - contentHeight;
        break;
      case Element.ALIGN_MIDDLE:
        extraHeight = (interiorHeight - contentHeight) / 2.0f;
        break;
      default: // ALIGN_TOP
        extraHeight = 0f;
    }

    extraHeight += cellpadding() + cellspacing();
    extraHeight += getBorderWidthInside(TOP);
    if (firstLine != null) {
      firstLine.height = firstLineRealHeight + extraHeight;
    }
  }
예제 #7
0
 private void flushCurrentLine() {
   if (line != null && line.size() > 0) {
     addLine(line);
   }
 }
예제 #8
0
 private void addLine(PdfLine line) {
   lines.add(line);
   contentHeight += line.height();
   lastLine = line;
   this.line = null;
 }
예제 #9
0
  /**
   * Constructs a <CODE>PdfCell</CODE>-object.
   *
   * @param cell the original <CODE>Cell</CODE>
   * @param rownumber the number of the <CODE>Row</CODE> the <CODE>Cell</CODE> was in.
   * @param left the left border of the <CODE>PdfCell</CODE>
   * @param right the right border of the <CODE>PdfCell</CODE>
   * @param top the top border of the <CODE>PdfCell</CODE>
   * @param cellspacing the cellspacing of the <CODE>Table</CODE>
   * @param cellpadding the cellpadding of the <CODE>Table</CODE>
   */
  public PdfCell(
      Cell cell,
      int rownumber,
      float left,
      float right,
      float top,
      float cellspacing,
      float cellpadding) {
    // constructs a Rectangle (the bottomvalue will be changed afterwards)
    super(left, top, right, top);
    // copying the other Rectangle attributes from class Cell
    cloneNonPositionParameters(cell);
    this.cellpadding = cellpadding;
    this.cellspacing = cellspacing;
    this.verticalAlignment = cell.verticalAlignment();
    this.useAscender = cell.isUseAscender();
    this.useDescender = cell.isUseDescender();
    this.useBorderPadding = cell.isUseBorderPadding();

    // initialisation of some parameters
    PdfChunk chunk;
    Element element;
    PdfChunk overflow;
    lines = new ArrayList();
    images = new ArrayList();
    leading = cell.leading();
    int alignment = cell.horizontalAlignment();
    left += cellspacing + cellpadding;
    right -= cellspacing + cellpadding;

    left += getBorderWidthInside(LEFT);
    right -= getBorderWidthInside(RIGHT);

    contentHeight = 0;

    rowspan = cell.rowspan();

    ArrayList allActions;
    int aCounter;
    // we loop over all the elements of the cell
    for (Iterator i = cell.getElements(); i.hasNext(); ) {
      element = (Element) i.next();
      switch (element.type()) {
        case Element.JPEG:
        case Element.IMGRAW:
        case Element.IMGTEMPLATE:
          addImage((Image) element, left, right, 0.4f * leading, alignment); //
          break;
          // if the element is a list
        case Element.LIST:
          if (line != null && line.size() > 0) {
            line.resetAlignment();
            addLine(line);
          }
          allActions = new ArrayList();
          processActions(element, null, allActions);
          aCounter = 0;
          ListItem item;
          // we loop over all the listitems
          for (Iterator items = ((List) element).getItems().iterator(); items.hasNext(); ) {
            item = (ListItem) items.next();
            line = new PdfLine(left + item.indentationLeft(), right, alignment, item.leading());
            line.setListItem(item);
            for (Iterator j = item.getChunks().iterator(); j.hasNext(); ) {
              chunk = new PdfChunk((Chunk) j.next(), (PdfAction) (allActions.get(aCounter++)));
              while ((overflow = line.add(chunk)) != null) {
                addLine(line);
                line = new PdfLine(left + item.indentationLeft(), right, alignment, item.leading());
                chunk = overflow;
              }
              line.resetAlignment();
              addLine(line);
              line = new PdfLine(left + item.indentationLeft(), right, alignment, leading);
            }
          }
          line = new PdfLine(left, right, alignment, leading);
          break;
          // if the element is something else
        default:
          allActions = new ArrayList();
          processActions(element, null, allActions);
          aCounter = 0;

          float currentLineLeading = leading;
          float currentLeft = left;
          float currentRight = right;
          if (element instanceof Phrase) {
            currentLineLeading = ((Phrase) element).leading();
          }
          if (element instanceof Paragraph) {
            Paragraph p = (Paragraph) element;
            currentLeft += p.indentationLeft();
            currentRight -= p.indentationRight();
          }
          if (line == null) {
            line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
          }
          // we loop over the chunks
          ArrayList chunks = element.getChunks();
          if (chunks.isEmpty()) {
            addLine(line); // add empty line - all cells need some lines even if they are empty
            line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
          } else {
            for (Iterator j = chunks.iterator(); j.hasNext(); ) {
              Chunk c = (Chunk) j.next();
              chunk = new PdfChunk(c, (PdfAction) (allActions.get(aCounter++)));
              while ((overflow = line.add(chunk)) != null) {
                addLine(line);
                line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                chunk = overflow;
              }
            }
          }
          // if the element is a paragraph, section or chapter, we reset the alignment and add the
          // line
          switch (element.type()) {
            case Element.PARAGRAPH:
            case Element.SECTION:
            case Element.CHAPTER:
              line.resetAlignment();
              flushCurrentLine();
          }
      }
    }
    flushCurrentLine();
    if (lines.size() > cell.getMaxLines()) {
      while (lines.size() > cell.getMaxLines()) {
        removeLine(lines.size() - 1);
      }
      if (cell.getMaxLines() > 0) {
        String more = cell.getShowTruncation();
        if (more != null && more.length() > 0) {
          // Denote that the content has been truncated
          lastLine = (PdfLine) lines.get(lines.size() - 1);
          if (lastLine.size() >= 0) {
            PdfChunk lastChunk = lastLine.getChunk(lastLine.size() - 1);
            float moreWidth = new PdfChunk(more, lastChunk).width();
            while (lastChunk.toString().length() > 0
                && lastChunk.width() + moreWidth > right - left) {
              // Remove characters to leave room for the 'more' indicator
              lastChunk.setValue(lastChunk.toString().substring(0, lastChunk.length() - 1));
            }
            lastChunk.setValue(lastChunk.toString() + more);
          } else {
            lastLine.add(new PdfChunk(new Chunk(more), null));
          }
        }
      }
    }
    // we set some additional parameters
    if (useDescender && lastLine != null) {
      contentHeight -= lastLine.getDescender();
    }

    // adjust first line height so that it touches the top
    if (lines.size() > 0) {
      firstLine = (PdfLine) lines.get(0);
      float firstLineRealHeight = firstLineRealHeight();
      contentHeight -= firstLine.height();
      firstLine.height = firstLineRealHeight;
      contentHeight += firstLineRealHeight;
    }

    float newBottom = top - contentHeight - (2f * cellpadding()) - (2f * cellspacing());
    newBottom -= getBorderWidthInside(TOP) + getBorderWidthInside(BOTTOM);
    setBottom(newBottom);

    this.rownumber = rownumber;
  }