예제 #1
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
  /**
   * Truncates this <CODE>PdfChunk</CODE> if it's too long for the given width.
   *
   * <p>Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
   *
   * @param width a given width
   * @return the <CODE>PdfChunk</CODE> that doesn't fit into the width.
   */
  PdfChunk truncate(float width) {
    /* ssteward: dropped in 1.44
           if (image != null) {
               if (image.scaledWidth() > width) {
                   PdfChunk pc = new PdfChunk("", this);
                   value = "";
                   attributes.remove(Chunk.IMAGE);
                   image = null;
                   font = PdfFont.getDefaultFont();
                   return pc;
               }
               else
                   return null;
           }
    */

    int currentPosition = 0;
    float currentWidth = 0;

    // it's no use trying to split if there isn't even enough place for a space
    if (width < font.width()) {
      String returnValue = value.substring(1);
      value = value.substring(0, 1);
      PdfChunk pc = new PdfChunk(returnValue, this);
      return pc;
    }

    // loop over all the characters of a string
    // or until the totalWidth is reached
    int length = value.length();
    char character;
    while (currentPosition < length) {
      // the width of every character is added to the currentWidth
      character = value.charAt(currentPosition);
      currentWidth += font.width(character);
      if (currentWidth > width) break;
      currentPosition++;
    }

    // if all the characters fit in the total width, null is returned (there is no overflow)
    if (currentPosition == length) {
      return null;
    }

    // otherwise, the string has to be truncated
    // currentPosition -= 2;
    // we have to chop off minimum 1 character from the chunk
    if (currentPosition == 0) {
      currentPosition = 1;
    }
    String returnValue = value.substring(currentPosition);
    value = value.substring(0, currentPosition);
    PdfChunk pc = new PdfChunk(returnValue, this);
    return pc;
  }
예제 #2
0
 /**
  * Gets the biggest descender for all the fonts used in this line. Note that this is a negative
  * number.
  *
  * @return maximum size of all the descenders used in this line
  */
 public float getDescender() {
   float descender = 0;
   for (int k = 0; k < line.size(); ++k) {
     PdfChunk ck = line.get(k);
     if (ck.isImage()) descender = Math.min(descender, ck.getImageOffsetY());
     else {
       PdfFont font = ck.font();
       descender =
           Math.min(descender, font.getFont().getFontDescriptor(BaseFont.DESCENT, font.size()));
     }
   }
   return descender;
 }
예제 #3
0
 /**
  * Gets the maximum size of the ascender for all the fonts used in this line.
  *
  * @return maximum size of all the ascenders used in this line
  */
 public float getAscender() {
   float ascender = 0;
   for (int k = 0; k < line.size(); ++k) {
     PdfChunk ck = line.get(k);
     if (ck.isImage())
       ascender = Math.max(ascender, ck.getImage().getScaledHeight() + ck.getImageOffsetY());
     else {
       PdfFont font = ck.font();
       ascender =
           Math.max(ascender, font.getFont().getFontDescriptor(BaseFont.ASCENT, font.size()));
     }
   }
   return ascender;
 }
예제 #4
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
 /**
  * Trims the last space.
  *
  * @return the width of the space trimmed, otherwise 0
  */
 public float trimLastSpace() {
   BaseFont ft = font.getFont();
   if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') {
     if (value.length() > 1 && value.endsWith("\u0001")) {
       value = value.substring(0, value.length() - 1);
       return font.width('\u0001');
     }
   } else {
     if (value.length() > 1 && value.endsWith(" ")) {
       value = value.substring(0, value.length() - 1);
       return font.width(' ');
     }
   }
   return 0;
 }
예제 #5
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
 /**
  * Removes all the <VAR>' '</VAR> and <VAR>'-'</VAR>-characters on the right of a <CODE>String</CODE>.
  * <P>
  * @param	string		the <CODE>String<CODE> that has to be trimmed.
  * @return	the trimmed <CODE>String</CODE>
  */
 String trim(String string) {
   BaseFont ft = font.getFont();
   if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') {
     while (string.endsWith("\u0001")) {
       string = string.substring(0, string.length() - 1);
     }
   } else {
     while (string.endsWith(" ") || string.endsWith("\t")) {
       string = string.substring(0, string.length() - 1);
     }
   }
   return string;
 }
예제 #6
0
 protected void printFooter() throws DocumentException {
   out("");
   out(
       renderEnd(
           renderMiddle("", "Page " + (iPageNo + 1)),
           "<"
               + iCurrentSubjectArea.getSubjectAreaAbbreviation()
               + (iCourseNumber != null ? " " + iCourseNumber : "")
               + ">  "));
   // FIXME: For some reason when a line starts with space, the line is shifted by one space in the
   // resulting PDF (when using iText 5.0.2)
   Paragraph p = new Paragraph(iBuffer.toString().replace("\n ", "\n  "), PdfFont.getFixedFont());
   p.setLeading(9.5f); // was 13.5f
   iDoc.add(p);
   iBuffer = new StringBuffer();
   iPageNo++;
 }
예제 #7
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
 /**
  * Constructs a <CODE>PdfChunk</CODE>-object.
  *
  * @param string the content of the <CODE>PdfChunk</CODE>-object
  * @param other Chunk with the same style you want for the new Chunk
  */
 PdfChunk(String string, PdfChunk other) {
   thisChunk[0] = this;
   value = string;
   this.font = other.font;
   this.attributes = other.attributes;
   this.noStroke = other.noStroke;
   this.baseFont = other.baseFont;
   Object obj[] = (Object[]) attributes.get(Chunk.IMAGE);
   if (obj == null) {
     // image = null; ssteward: dropped in 1.44
   } else {
     // image = (Image)obj[0]; ssteward: dropped in 1.44
     offsetX = ((Float) obj[1]).floatValue();
     offsetY = ((Float) obj[2]).floatValue();
     changeLeading = ((Boolean) obj[3]).booleanValue();
   }
   encoding = font.getFont().getEncoding();
   splitCharacter = (SplitCharacter) noStroke.get(Chunk.SPLITCHARACTER);
   if (splitCharacter == null) splitCharacter = this;
 }
예제 #8
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
 float getCharWidth(char c) {
   if (noPrint(c)) return 0;
   return font.width(c);
 }
예제 #9
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
 /**
  * Returns the width of this <CODE>PdfChunk</CODE>.
  *
  * @return a width
  */
 float width() {
   return font.width(value);
 }
예제 #10
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
  /**
   * Splits this <CODE>PdfChunk</CODE> if it's too long for the given width.
   *
   * <p>Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
   *
   * @param width a given width
   * @return the <CODE>PdfChunk</CODE> that doesn't fit into the width.
   */
  PdfChunk split(float width) {
    newlineSplit = false;
    /* ssteward: dropped in 1.44
           if (image != null) {
               if (image.scaledWidth() > width) {
                   PdfChunk pc = new PdfChunk(Chunk.OBJECT_REPLACEMENT_CHARACTER, this);
                   value = "";
                   attributes = new HashMap();
                   image = null;
                   font = PdfFont.getDefaultFont();
                   return pc;
               }
               else
                   return null;
           }
    */
    HyphenationEvent hyphenationEvent = (HyphenationEvent) noStroke.get(Chunk.HYPHENATION);
    int currentPosition = 0;
    int splitPosition = -1;
    float currentWidth = 0;

    // loop over all the characters of a string
    // or until the totalWidth is reached
    int lastSpace = -1;
    float lastSpaceWidth = 0;
    int length = value.length();
    char valueArray[] = value.toCharArray();
    char character = 0;
    BaseFont ft = font.getFont();
    if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') {
      while (currentPosition < length) {
        // the width of every character is added to the currentWidth
        char cidChar = valueArray[currentPosition];
        character = ft.getUnicodeEquivalent(cidChar);
        // if a newLine or carriageReturn is encountered
        if (character == '\n') {
          newlineSplit = true;
          String returnValue = value.substring(currentPosition + 1);
          value = value.substring(0, currentPosition);
          if (value.length() < 1) {
            value = "\u0001";
          }
          PdfChunk pc = new PdfChunk(returnValue, this);
          return pc;
        }
        currentWidth += font.width(cidChar);
        if (character == ' ') {
          lastSpace = currentPosition + 1;
          lastSpaceWidth = currentWidth;
        }
        if (currentWidth > width) break;
        // if a split-character is encountered, the splitPosition is altered
        if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, thisChunk))
          splitPosition = currentPosition + 1;
        currentPosition++;
      }
    } else {
      while (currentPosition < length) {
        // the width of every character is added to the currentWidth
        character = valueArray[currentPosition];
        // if a newLine or carriageReturn is encountered
        if (character == '\r' || character == '\n') {
          newlineSplit = true;
          int inc = 1;
          if (character == '\r'
              && currentPosition + 1 < length
              && valueArray[currentPosition + 1] == '\n') inc = 2;
          String returnValue = value.substring(currentPosition + inc);
          value = value.substring(0, currentPosition);
          if (value.length() < 1) {
            value = " ";
          }
          PdfChunk pc = new PdfChunk(returnValue, this);
          return pc;
        }
        currentWidth += font.width(character);
        if (character == ' ') {
          lastSpace = currentPosition + 1;
          lastSpaceWidth = currentWidth;
        }
        if (currentWidth > width) break;
        // if a split-character is encountered, the splitPosition is altered
        if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, null))
          splitPosition = currentPosition + 1;
        currentPosition++;
      }
    }

    // if all the characters fit in the total width, null is returned (there is no overflow)
    if (currentPosition == length) {
      return null;
    }
    // otherwise, the string has to be truncated
    if (splitPosition < 0) {
      String returnValue = value;
      value = "";
      PdfChunk pc = new PdfChunk(returnValue, this);
      return pc;
    }
    if (lastSpace > splitPosition && splitCharacter.isSplitCharacter(0, 0, 1, singleSpace, null))
      splitPosition = lastSpace;
    if (hyphenationEvent != null && lastSpace < currentPosition) {
      int wordIdx = getWord(value, lastSpace);
      if (wordIdx > lastSpace) {
        String pre =
            hyphenationEvent.getHyphenatedWordPre(
                value.substring(lastSpace, wordIdx),
                font.getFont(),
                font.size(),
                width - lastSpaceWidth);
        String post = hyphenationEvent.getHyphenatedWordPost();
        if (pre.length() > 0) {
          String returnValue = post + value.substring(wordIdx);
          value = trim(value.substring(0, lastSpace) + pre);
          PdfChunk pc = new PdfChunk(returnValue, this);
          return pc;
        }
      }
    }
    String returnValue = value.substring(splitPosition);
    value = trim(value.substring(0, splitPosition));
    PdfChunk pc = new PdfChunk(returnValue, this);
    return pc;
  }
예제 #11
0
파일: PdfChunk.java 프로젝트: fwenzel/pdftk
  /**
   * Constructs a <CODE>PdfChunk</CODE>-object.
   *
   * @param chunk the original <CODE>Chunk</CODE>-object
   * @param action the <CODE>PdfAction</CODE> if the <CODE>Chunk</CODE> comes from an <CODE>Anchor
   *     </CODE>
   */
  PdfChunk(Chunk chunk, PdfAction action) {
    thisChunk[0] = this;
    value = chunk.content();

    Font f = chunk.font();
    float size = f.size();
    if (size == Font.UNDEFINED) size = 12;
    baseFont = f.getBaseFont();
    int style = f.style();
    if (style == Font.UNDEFINED) {
      style = Font.NORMAL;
    }
    if (baseFont == null) {
      // translation of the font-family to a PDF font-family
      baseFont = f.getCalculatedBaseFont(false);
    } else {
      // bold simulation
      if ((style & Font.BOLD) != 0)
        attributes.put(
            Chunk.TEXTRENDERMODE,
            new Object[] {
              new Integer(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE), new Float(size / 30f), null
            });
      // italic simulation
      if ((style & Font.ITALIC) != 0) attributes.put(Chunk.SKEW, new float[] {0, ITALIC_ANGLE});
    }
    font = new PdfFont(baseFont, size);
    // other style possibilities
    HashMap attr = chunk.getAttributes();
    if (attr != null) {
      for (Iterator i = attr.keySet().iterator(); i.hasNext(); ) {
        Object name = i.next();
        if (keysAttributes.containsKey(name)) {
          attributes.put(name, attr.get(name));
        } else if (keysNoStroke.containsKey(name)) {
          noStroke.put(name, attr.get(name));
        }
      }
      if ("".equals(attr.get(Chunk.GENERICTAG))) {
        attributes.put(Chunk.GENERICTAG, chunk.content());
      }
    }
    if (f.isUnderlined()) {
      Object obj[] = {null, new float[] {0, 1f / 15, 0, -1f / 3, 0}};
      Object unders[][] = Chunk.addToArray((Object[][]) attributes.get(Chunk.UNDERLINE), obj);
      attributes.put(Chunk.UNDERLINE, unders);
    }
    if (f.isStrikethru()) {
      Object obj[] = {null, new float[] {0, 1f / 15, 0, 1f / 3, 0}};
      Object unders[][] = Chunk.addToArray((Object[][]) attributes.get(Chunk.UNDERLINE), obj);
      attributes.put(Chunk.UNDERLINE, unders);
    }
    if (action != null) attributes.put(Chunk.ACTION, action);
    // the color can't be stored in a PdfFont
    noStroke.put(Chunk.COLOR, f.color());
    noStroke.put(Chunk.ENCODING, font.getFont().getEncoding());
    Object obj[] = (Object[]) attributes.get(Chunk.IMAGE);
    if (obj == null) {
      // image = null; ssteward: dropped in 1.44
    } else {
      attributes.remove(Chunk.HSCALE); // images are scaled in other ways
      // image = (Image)obj[0]; ssteward: dropped in 1.44
      offsetX = ((Float) obj[1]).floatValue();
      offsetY = ((Float) obj[2]).floatValue();
      changeLeading = ((Boolean) obj[3]).booleanValue();
    }
    // font.setImage(image); ssteward: dropped in 1.44
    Float hs = (Float) attributes.get(Chunk.HSCALE);
    if (hs != null) font.setHorizontalScaling(hs.floatValue());
    encoding = font.getFont().getEncoding();
    splitCharacter = (SplitCharacter) noStroke.get(Chunk.SPLITCHARACTER);
    if (splitCharacter == null) splitCharacter = this;
  }